繁体   English   中英

了解Haskell类型签名

[英]Understanding Haskell Type Signatures

我正在自学Haskell,我想知道以下类型的签名:

Prelude> :t ($)
($) :: (a -> b) -> a -> b
Prelude>

我应该如何解释(没有双关语意)?

一个半相似的结果也证明是令人费解的:

Prelude> :t map
map :: (a -> b) -> [a] -> [b]
Prelude>

我将从map开始。 map函数将操作应用于列表中的每个元素。 如果我有

add3 :: Int -> Int
add3 x = x + 3

然后我可以使用map将它应用于整个Int的列表:

> map add3 [1, 2, 3, 4]
[4, 5, 6, 7]

所以,如果你看一下类型签名

map :: (a -> b) -> [a] -> [b]

你会看到第一个参数是(a -> b) ,它只是一个带a并返回b的函数。 第二个参数是[a] ,它是类型a的值列表,返回类型[b]是类型b的值列表。 因此,简单地说, map函数将函数应用于值列表中的每个元素,然后将这些值作为列表返回。

这就是使map成为一个更高阶函数的原因 ,它将一个函数作为一个参数并对其进行处理。 查看map另一种方法是在类型签名中添加一些括号来制作它

map :: (a -> b) -> ([a] -> [b])

因此,您也可以将其视为将函数从a转换为b[a][b]的函数的函数。


函数($)具有类型

($) :: (a -> b) -> a -> b

并使用像

> add3 $ 1 + 1
5

它所做的只是取右边的东西 ,在这种情况下是1 + 1 ,并将它传递给左边的函数,这里是add3 为什么这很重要? 它具有方便的固定性或运算符优先级,使其等效于

> add3 (1 + 1)

因此,无论如何,在传递给左边之前,基本上将其包裹在括号中。 这使得将多个函数链接在一起非常有用:

> add3 $ add3 $ add3 $ add3 $ 1 + 1

比...更好

> add3 (add3 (add3 (add3 (1 + 1))))

因为你不必关闭括号。

好吧,正如已经说过的那样,如果你只是忘记currying并且在C ++中看到它就可以很容易地理解$

template<typename A, typename B>
B dollar(std::function<B(A)> f, A x) {
  return f(x);
}

但实际上,除了将函数应用于值之外,还有更多内容! $map的签名之间的明显相似性实际上是一个非常深刻的类别理论意义:两者都是仿函数的一个例子 - 仿函数!

在我们一直使用的Hask类别中,对象是类型。 这有点混乱 ,但不要担心)。 态射是函数。

最着名的(endo-) 仿函数是那些具有同名类型实例的仿函数 但实际上,在数学上,仿函数只是将对象映射到对象和态射到态射1的东西 map (双关语,我想!)就是一个例子:它取一个对象(即类型) A并将其映射到一个类型[A] 并且,对于任何两种类型AB ,它采用态射(即函数) A -> B ,并将其映射到类型[A] -> [B]的相应列表函数。

这只是仿函数类签名操作的一个特例:

fmap :: Functor f   =>   (a->b) -> (f a->f b)

数学并不要求这个fmap有一个名字。 所以也可以有身份函子 ,它只是为自己分配任何类型。 并且,每个态度对自己:

($) :: (a->b) -> (a->b)

“身份”显然更为普遍存在,您也可以将任何类型的值映射到自己。

id :: a -> a
id x = x

当然,可能的实施就是这样

($) = id

1心灵,不是映射物体和态射的任何东西都是一个算子......它确实需要满足算子定律

($)只是功能应用程序。 它得到类型的函数a->b ,类型的参数a ,应用功能,并返回类型的值b

map是阅读函数类型签名有助于理解它的一个很好的例子。 map的第一个参数是一个带a和返回b的函数,它的第二个参数是一个类型为[a]的列表。 所以map应用类型的函数a->b到的列表a值。 结果类型确实是[b]类型 - b值列表!

(a->b)->[a]->[b]可以解释为“接受函数和列表并返回另一个列表”,也可以解释为“接受类型a->b函数并返回另一个函数类型[a]->[b] “。 当你以这种方式看待它时, map “upgrade”f(在这个上下文中通常使用术语“lift”)来处理列表:如果double是一个加倍整数的函数,那么map double是一个map double的函数列表中的整数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM