Why does the signature change after the job

Playing ghci , I got the following expression: unlines . map (\(a,b) -> show a ++ " " ++ show b) unlines . map (\(a,b) -> show a ++ " " ++ show b)

Now when I check it through :t , I get:

 > :t unlines . map (\(a,b) -> show a ++ " " ++ show b) unlines . map (\(a,b) -> show a ++ " " ++ show b) :: (Show a, Show a1) => [(a, a1)] -> String 

As accurate as expected. But now, if I try to assign it to some name, I get a more specific signature than the original:

 > let f = unlines . map (\(a,b) -> show a ++ " " ++ show b) > :tf f :: [((), ())] -> String 

Why is this happening?

+7
source share
2 answers

Due to the restriction of monomorphism, the definitions of the form x = ... (without parameters) are given monomorphic (i.e. not polymorphic) type, which usually includes some defaults, as mentioned in another answer .

To prevent this, add a type signature to your definition or disable monomorphism restriction with :set -XNoMonomorphismRestriction . You can add this to your .ghci file so that it starts automatically at startup until it is disabled by default in GHCi in the next version .

+12
source

The default rules.

When you enter material into GHCi, it tries to apply default types. IIRC, for things with a Num constraint, he chooses Integer , for Fractional he chooses Double , and for everything else he chooses () .

If you write this in the Haskell source file and upload it to GHCi, this will not happen (I believe).

I think you can also say something like default Int to change the default rules for each module.

+4
source

All Articles