[英]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]
。 并且,对于任何两种类型A
和B
,它采用态射(即函数) 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.