如何阅读“Num(a - > b - > a)=> a - > [b] - > a”定义

时间:2013-10-07 09:39:05

标签: haskell

我正试图了解Haskell函数定义。我采用了折叠函数,其定义为

:t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a

现在第一个参数是一个函数,所以如果我传递它,那么剩下的就是:

:t foldl (+)
foldl (+) :: Num b => b -> [b] -> b

我读作“一个获取数值并返回带数组的函数的函数”。

现在,第一个参数真的是一个函数吗?可以读作

foldl :: a -> b -> a -> a -> [b] -> a

代替?

我尝试只传递一个数值,这就是我所拥有的:

foldl 4 :: Num (a -> b -> a) => a -> [b] -> a

问题是......你怎么读这个?我不明白我有什么。

2 个答案:

答案 0 :(得分:8)

第一个参数是一个函数,因此不能读作:foldl :: a -> b -> a -> a -> [b] -> a。因为->是正确的关联,这意味着a -> b -> ca -> (b -> c),这与(a -> b) -> c不同

答案 1 :(得分:1)

'Num'混淆了这是因为你将(+)传递给了foldl。所以你创建一个带签名的函数

foldl (+) :: Num b => b -> [b] -> b

这是一个函数,它接受Numericics和Numerics列表并返回一个Numeric。

Num b => b 

意味着“返回数字的函数 - 这就是 Scala 中的意思。Num b表示{{1}的所有实例在此签名的其余部分中,1}}是Numeric。这是在Haskell中完成类型注释的方式。

b

表示一个函数,它接受3个参数(其中一个是函数)并返回与第二个参数相同类型的值。通过签名......

  1. 第一个参数是一个函数,它本身接受两个参数并返回与第一个参数相同类型的值。它用括号表示它只是一个参数和一个函数 - 括号内的东西是它的函数签名。我们称这个函数为 func
  2. 第二个参数可以是任何内容,只要它与 func 采用的第一个参数类型相同。
  3. 第三个参数必须是与 func
  4. 采用的第二个参数相同类型的序列
  5. 结果必须与第二个参数的类型相同(以及 func 采用的第一个参数)。
  6. 这些是期望foldl具有参数。我们在签名中看到foldl :: (a -> b -> a) -> a -> [b] -> a a因为可以具有与 func 的第一个和第二个参数不同的类型,但a和b可以可以是任何类型,包括两者是同一类型。但是当你将一个函数传递给foldl,创建一个将 func 应用于其余参数的新函数时,你可以添加 func 的类型期望值。由于您传入了一个数字函数,因此该类型注释会添加到生成的签名中。由于b期望两个参数都是数字,我们只会在签名中看到一个类型变量(仅+,而不是ba )。