我正试图了解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
问题是......你怎么读这个?我不明白我有什么。
答案 0 :(得分:8)
第一个参数是一个函数,因此不能读作:foldl :: a -> b -> a -> a -> [b] -> a
。因为->
是正确的关联,这意味着a -> b -> c
是a -> (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个参数(其中一个是函数)并返回与第二个参数相同类型的值。通过签名......
这些是仅期望foldl具有参数。我们在签名中看到foldl :: (a -> b -> a) -> a -> [b] -> a
和a
因为可以具有与 func 的第一个和第二个参数不同的类型,但a和b可以可以是任何类型,包括两者是同一类型。但是当你将一个函数传递给foldl,创建一个将 func 应用于其余参数的新函数时,你可以添加 func 的类型期望值。由于您传入了一个数字函数,因此该类型注释会添加到生成的签名中。由于b
期望两个参数都是数字,我们只会在签名中看到一个类型变量(仅+
,而不是b
和a
)。