Haskell多态调用没有完整的类型知识

Tot*_*oro 9 polymorphism haskell types

我有一段时间正在研究Haskell,所以我是新手.

以下代码非常容易理解:

purStrLn $ show [1]
Run Code Online (Sandbox Code Playgroud)

在这里,我们可以推断出所有类型(默认值),并且一切运行良好.但是以下代码也适用:

putStrLn $ show []
Run Code Online (Sandbox Code Playgroud)

即使我们无法推断列表类型.

如果我用ghci执行代码,我会得到以下内容:

Prelude> []
[]
Prelude> :t it
it :: [a]
Prelude> 
Run Code Online (Sandbox Code Playgroud)

所以类型似乎是多态的.但在这种情况下,将使用部分应用类型调用该节目.

相同的行为在其他类型中很常见,例如使用Data.Map.empty,因此它不是列表功能(或者至少看起来像它).

为什么以及如何运作?

Mik*_*kov 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 []
Run Code Online (Sandbox Code Playgroud)

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

module Main where

main = putStrLn $ show ([]::[Int])
Run Code Online (Sandbox Code Playgroud)

但为什么它可以工作ghci?答案是扩展类型违约ghci:类型a默认为()(单位类型).

这种行为的动机是,用户在解释器中工作时始终指定类型有点令人厌烦.作为维图斯在评论中指出,运行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 []
Run Code Online (Sandbox Code Playgroud)

  • 此外,在GHCi中键入`:set -Wall`有助于发现此违约. (3认同)