Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell polymorphic calls without complete type knowledge

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?

like image 272
Totoro Avatar asked Apr 18 '13 14:04

Totoro


1 Answers

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 []
like image 53
Mikhail Glushenkov Avatar answered Oct 18 '22 08:10

Mikhail Glushenkov