I'm studying Haskell since a little while, so I'm a newbie.
The following code is very easily understandable:
purStrLn $ show [1]
Here we can infer all the types (with defaults), and all works well. But the following code works, too:
putStrLn $ show []
even if we can't infer the list type.
If I execute the code with ghci I obtain the following:
Prelude> []
[]
Prelude> :t it
it :: [a]
Prelude>
so the type seems to be polymorphic. But in this case the show would be called with a partially applied type.
The same behavior is common with other types, for example with Data.Map.empty, so it isn't a list feature (or at least it seems like it).
Why and how it works?
First of all, this works only in ghci
. If you try to compile this program with ghc
you'll get a type error:
Test.hs:3:19:
Ambiguous type variable `a0' in the constraint:
(Show a0) arising from a use of `show'
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `($)', namely `show []'
In the expression: putStrLn $ show []
In an equation for `main': main = putStrLn $ show []
Adding a type signature makes the error go away:
module Main where
main = putStrLn $ show ([]::[Int])
But why did it work in ghci
? The answer is extended type defaulting in ghci
: the type of a
is defaulted to ()
(the unit type).
The motivation for this behaviour is that it is a bit tiresome for the user to always specify the types when working in the interpreter. As Vitus notes in the comments, running ghci
with -Wall
(or adding :set -Wall
to your ~/.ghci
) makes it easier to spot the defaulting:
<interactive>:2:12:
Warning: Defaulting the following constraint(s) to type `()'
(Show a0) arising from a use of `show'
In the second argument of `($)', namely `show []'
In a stmt of an interactive GHCi command: it <- putStrLn $ show []
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With