Haskell 函数类型说明

标签 haskell

我正在尝试理解函数的 Haskell 类型变量。我写了一个函数:

applyTwice f x = f(f x)

我试图理解这个函数的类型变量,所以我做了一个:t applyTwice。这是 Haskell 解释类型的方式:

applyTwice :: (t -> t) -> t -> t

然后我创建了另一个函数:

applyOnce f x = f x

这次 :t Haskell 返回

applyOnce :: (t1 -> t) -> t1 -> t

我的问题是

  1. 我们如何阅读/理解这些函数接受和返回的内容?

  2. 这适用于applyTwice。如果他们说 -> 的左侧是函数接受的内容,而右侧是返回的内容,那么它不应该是 applyTwice::((t -> t) -> t) -> t? (t -> t)(f x)((t -> t) -> t)f (f x ) 并且返回类型为 t

  3. 这是用于applyOnce。为什么函数的类型被解释为 applyOnce::(t1 -> t) -> t1 -> t?因为我们只接受一个函数并返回它的值。不应该是applyOnce::(t1 -> t) -> t1吗?

作为 Haskell 的初学者,我希望得到这方面的任何建议。

最佳答案

我们有:

applyTwice f x = f(f x)

只有当 xf x 的类型相同时,这才有意义(否则你如何能够将 f x 传递给接受 x 的函数?)。因此,您可以说 applyTwice 接受 2 个输入参数:

  • 接受类型 t 并返回相同类型 t 的函数
  • 某种类型的输入

现在这个输入可以是任何类型,比如 t1。但是您还必须能够将函数应用于此输入,因此输入的类型也必须是 t。放在一起,我们得到签名:

applyTwice :: (t -> t) -> t -> t

请记住,只有最后一项是返回类型,所有其他项都是输入类型。

现在考虑:

applyOnce f x = f x

简单地说,关于函数 f 的全部内容就是它应该能够接受任何类型的输入 x。没有关于函数应该返回什么类型的信息except applyOnce 也应该返回相同的类型。因此,我们最终得到了您看到的签名:

applyOnce :: (t1 -> t) -> t1 -> t

其中 t1 可以是任何类型,t 可以是任何类型(与 t1 相同或不同),但要求 f 的返回类型匹配 applyOnce,这里用 t 表示。

TL;DR:具有 n 个输入的函数的函数签名将始终具有 (n+1) 项,最后一项将是函数的返回类型。

但是,您应该注意,这实际上并不是事情在幕后的运作方式。 Haskell 中的所有函数实际上都接受一个参数,即它们是curried。您可以阅读更多相关信息 here .

关于Haskell 函数类型说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42243902/

相关文章:

haskell - 函数似乎在常量空间内工作,但常量空间太多了

haskell - 在 Haskell 中链接/组合类型类

haskell ::. 是什么意思?

haskell - Hackage 包名称如何映射到 'cabal install' 名称?

Haskell:懒惰的 `Control.Monad.ST.Lazy` monad 有多懒惰?

haskell - Haskell 中的零填充右移?

Haskell:解析错误:需要模块头、导入声明或顶级声明

haskell - 试图理解类和实例

list - Haskell 列表 Monad 状态依赖

haskell - 适用于用户定义的类型