【发布时间】:2016-01-11 11:53:34
【问题描述】:
我是 Haskell 世界的新手,我在函数签名方面遇到了一些麻烦:
在简单的世界中意味着什么:
add:: Integer -> Integer -> Integer
是不是说前两个参数是Integer,返回值也是Integer?
你能解释一下,使用箭头来确定参数类型的目的,或者至少给我简要解释一下这个函数签名吗?
【问题讨论】:
标签: haskell
我是 Haskell 世界的新手,我在函数签名方面遇到了一些麻烦:
在简单的世界中意味着什么:
add:: Integer -> Integer -> Integer
是不是说前两个参数是Integer,返回值也是Integer?
你能解释一下,使用箭头来确定参数类型的目的,或者至少给我简要解释一下这个函数签名吗?
【问题讨论】:
标签: haskell
通俗地说,我们确实可以将add 称为一个函数,它接受两个Integers 并产生一个Integer。但是要理解这种表示法,您需要了解从技术上讲,在 Haskell 中不存在接受两个参数的函数。
每个函数都只接受一个参数,函数的类型写成a -> r,其中a 是参数的类型,r 是结果的类型。函数箭头是右关联的,这意味着a -> (b -> c)类型可以不带括号写成a -> b -> c。
所以Integer -> Integer -> Integer 与Integer -> (Integer -> Integer) 相同,这告诉我们add 是一个接受Integer 并产生另一个Integer -> Integer 类型的函数的函数。这称为柯里化,是在 Haskell 中“编码”多参数函数的常用方法。
要调用这样一个柯里化函数,我们可以写add 1 2,因为函数应用是左关联的,所以和(add 1) 2一样,首先调用add 1得到一个Integer -> Integer类型的函数,然后将该函数应用于参数2。
【讨论】:
作为一个简单的心智模型——是的,最后一个箭头后面的东西是返回类型,其他都是参数。
2 元以上函数的签名看起来是这样的,因为它们实际上是返回另一个 1 元以上函数的一元函数。
你的情况
add :: Integer -> (Integer -> Integer)
传递add 一个参数给出
add 3 :: (Integer -> Integer)
而add 3 4,因此只是Integer 类型。
【讨论】:
简短的回答是肯定的:这正是它的意思。最后一种是返回值,其他都是参数。
之所以如此,原因很简单,即:Haskell 中不存在 multi-agrument 函数。实际上所有函数都是单参数的,函数的一般类型是a -> b。然后由于currying,我们得到了一些看起来像多参数函数的东西。您只需要理解括号即可:
add :: Integer -> (Integer -> Integer)
内容如下:add 是一个函数,它接受一个 Integer 并返回一个函数 Integer -> Integer。所有括号都挤在此处的右侧。相反,当你应用时,所有的括号都挤在左边的大小上,像这样:
(add 5) 6
内容如下:将add 应用于参数5。作为回报,您将获得一个函数 - 然后将该函数应用于6(最终结果为11)。我们同样可以这样定义它:
add :: Integer -> (Integer -> Integer)
add x = \y -> x + y
因此,您可以为函数指定多个参数这一事实只是一种语法糖,因此您不必在以后返回所有这些 lambda。
这个事实也是我们可以这样做的原因:
add5 :: Integer -> Integer
add5 = (+5)
【讨论】: