9

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?

4

1 回答 1

16

首先,这仅适用于ghci. 如果你尝试编译这个程序,ghc你会得到一个类型错误:

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 []

添加类型签名会使错误消失:

module Main where

main = putStrLn $ show ([]::[Int])

但是为什么它起作用了ghci?答案是默认的扩展类型ghci:类型a默认为()(单位类型)。

这种行为的动机是用户在解释器中工作时总是指定类型有点烦人。正如 Vitus 在评论中指出的那样,运行ghci-Wall或添加:set -Wall到您的~/.ghci)可以更容易地发现默认情况:

<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 []
于 2013-04-18T14:38:35.870 回答