我很难理解Haskell中类型签名背后的原因。
1)因为->
被认为是右关联的,它是否意味着它可以以类似的方式理解,例如4 ^(2 ^(3 ^ 2))?
2)使用简单函数的类型签名来表达我的疑虑(解释我理解它的方式,我将使用a
,b
,c
代替Num a => a
或Int
' s):
myAdd :: a -> b -> c
myAdd x y = x+y
这意味着函数接受参数a
并返回带b
的函数,最后返回c
但它可以重写为:
myAdd :: (a->(b->c))
由于大多数学习材料都说我们示例中c
是函数myAdd的结果,为什么根据括号的使用它表示第一个'操作'是b->c
?如何从该类型签名中推断出已执行操作的顺序?
3)我被赋予了实施
的任务map f xs
使用foldr
,(.)
和(:)
导致:
map f xs = foldr ((:) . f) [] xs
我在理解上述功能的运作方面没有任何问题,但我们再来一次 - 输入签名。如果我们假设这些名称是统一的,那么a
类型代表所有合同中的相同类型,似乎c
和d
可以用a
来表示b
。在数学中,类似的任务可能非常简单,但我如何在Haskell中处理它?</ p>
map :: (a -> b) -> [a] -> [b]
foldr :: (a -> c -> c) -> c -> [a] -> c
(:) :: b -> ([b] -> [b])
(.) :: (b -> d) -> (a -> b) -> a -> d
答案 0 :(得分:5)
使用您的符号,
myAdd :: a -> b -> c
myAdd x y = x+y
您正确地将类型解释为a -> (b->c)
,但接着建议b -> c
中的计算以某种方式首先完成。
评估myAdd 2 10
之类的内容时,功能评估从左到右。
1)评估第一个myAdd 2
。此评估的结果是将给定数字y
发送到2 + y
的函数。实际上,myAdd
的定义与
myAdd x = \y -> x+y
2)然后将最后一个函数应用于参数10
以产生2 + 10 = 12
因此,类型表达式中->
的正确关联性与函数评估中的从右到左的计算顺序不对应。事实上,功能评估是左关联的:myAdd 2 10
与(myAdd 2) 10
相同。