haskell - 如果我对返回值进行硬编码,为什么 Haskell 会给出类型错误?

标签 haskell functional-programming

我真的无法解释为什么这是一个类型错误:

foo :: (Eq a) => a -> a
foo _ = 2

谁能解释一下吗?

最佳答案

因为

的类型
foo "bar"
根据您的签名,

应该是字符串,但不是(2 不是字符串)。在您的代码中 foo 是通用的,因此它应该返回与参数类型完全相同的实例。

haskell 类型系统的强大功能为我们提供了额外的信息 - 您对 foo 内的参数所能做的就是检查它与其他东西是否相等,但是我可以想出任何新类型(我们称之为 Baz)并且在其上使用 foo - 您不可能有任何其他 Baz 实例,因此返回 Baz 实例的唯一方法是返回与参数完全相同的实例。

如果你像这样重写 foo :

foo _ = True

它会有一个 foo::a -> Bool 签名,这基本上就是您尝试做的事情,但是数字会使事情变得更加复杂。

一般来说,你的函数有一个签名

foo :: (Num t1) => t -> t1

这意味着它为任何给定参数返回一个 Num 实例。 (这是因为 2 在 haskell 中可以有许多不同的类型,具体取决于您的需要,它可以是 Int 或 Real 或其他类型。)

您应该尝试使用 ghci 中的类型,例如:

:t foo

将为您提供 foo 的推断类型签名。

:t 2

给你(Num t) => t,这意味着2可以是实现Num的任何类型的实例。

关于haskell - 如果我对返回值进行硬编码,为什么 Haskell 会给出类型错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2357994/

相关文章:

scala - 以下命令式代码最有效的功能版本是什么?

clojure - Clojure 中的一级序列展平函数是什么?

haskell - 伴随仿函数决定了单子(monad)更改器(mutator),但是升力在哪里呢?

haskell - 多版本API实现

haskell - `newtype` 和 `data` 之间的区别,带有严格的注释

java - "Unwrap"在 Java 流(或并行流)中返回之前 Optional.empty 的可选

functional-programming - 类型检查与类型推断

haskell - 为什么 `putStrLn getLine` 不起作用?

haskell - 刚性类型变量不匹配

haskell - Haskell 如何知道 `xs` 是函数定义中的列表?