我是haskell世界的新手,我在功能签名方面遇到了一些麻烦:
在简单的世界中意味着什么:
add:: Integer -> Integer -> Integer
这是否意味着两个第一个参数是Integer
,返回值也是Integer
?
你能解释一下,使用箭头确定参数类型的目的,或者至少给我一个关于这个函数签名的简要解释吗?
答案 0 :(得分:11)
通俗地说,我们确实可以将add
称为一个函数,它需要两个Integer
并产生一个Integer
。但是要理解这个符号,你需要理解技术上没有在Haskell中接受两个参数的函数。
而是每个函数只接受一个参数,并且函数的类型被写为a -> r
,其中a
是参数的类型,r
是结果的类型。函数箭头是右关联的,这意味着类型a -> (b -> c)
可以不用括号写成a -> b -> c
。
因此Integer -> Integer -> Integer
与Integer -> (Integer -> Integer)
相同,后者告诉我们add
是一个函数,它接受Integer
并生成另一个Integer -> Integer
类型的函数。这称为currying,是编码"编码的常用方法。 Haskell中的多参数函数。
要调用这样一个curried函数,我们可以编写add 1 2
,因为函数应用程序是左关联的,与(add 1) 2
相同,首先调用add 1
来获取函数键入Integer -> Integer
,然后将该函数应用于参数2
。
答案 1 :(得分:4)
作为一个简单的心智模型 - 是的,最后一个箭头之后的东西是一个返回类型,其他一切都是参数。
2-and-more-ary函数的签名看起来是这样的,因为它们实际上是一元函数,返回另一个1-and-more-ary函数。
在你的情况下
add :: Integer -> (Integer -> Integer)
传递add
参数
add 3 :: (Integer -> Integer)
add 3 4
因此只是Integer
类型。
答案 2 :(得分:1)
简短的回答是肯定的:这正是它的含义。最后一种类型是返回值,所有其他类型都是参数。
这是一个非常简单的原因,即:在Haskell中没有多重agrument功能。所有函数在reallity中都是单参数,函数的一般类型是a -> b
。然后,由于 currying ,我们看起来像多参数功能。所有你需要理解的是括号:
add :: Integer -> (Integer -> Integer)
其中读取:add
是一个函数,它接受Integer
并返回函数Integer -> Integer
。所有括号都在右边的sqeeze这里。相反,当您申请时,所有括号都会挤压左手大小,如下所示:
(add 5) 6
其中包括:将add
应用于参数5
。作为回报,您将获得一个函数 - 然后将该函数应用于6
(最终结果为11
)。我们同样可以这样定义它:
add :: Integer -> (Integer -> Integer)
add x = \y -> x + y
因此,您可以为函数指定多个参数这一事实只是一个语法糖,因此您不必在路上返回所有这些lambda。
这也是我们能够做到这一点的原因:
add5 :: Integer -> Integer
add5 = (+5)