Haskell polymorphic calls without complete type knowledge
haskell, polymorphism, types
Solution
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 []
Problem
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?