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

标签 haskell types polymorphism

我学习 Haskell 已经有一段时间了,所以我是个新手。

下面的代码非常容易理解:

purStrLn $ show [1]

在这里我们可以推断所有类型(带有默认值),并且一切正常。 但下面的代码也可以工作:

putStrLn $ show []

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

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

Prelude> []
[]
Prelude> :t it
it :: [a]
Prelude> 

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

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

为什么以及如何运作?

最佳答案

首先,这仅适用于 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 中有效?答案是extended type defaultingghci中:a的类型默认为()(单位类型)。

这种行为的动机是,用户在解释器中工作时总是指定类型有点烦人。正如 Vitus 在评论中指出的那样,使用 -Wall 运行 ghci (或将 :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 []

关于没有完整类型知识的 Haskell 多态调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16085709/

相关文章:

haskell - GHC 7.6 中类型级别 Nat 的匹配

haskell - 我试图破解 Haskell,并从 GHC 收到 "Inaccessiable code"错误。这是什么意思?

haskell - 您将如何在 Haskell 中使用 foldr 定义映射和过滤器?

methods - 使用函数名作为参数

c++ - std::map、多态和删除

c# - 从父类ctor调用重写的方法

haskell - 为数据构造函数提供列表中的元素

c++ - 让类存储未知数据

mysql - 将 MySQL 值拆分为整数

polymorphism - 编程语言中的多态性是否意味着所涉及类型之间的子集关系?