haskell新手,我觉得:t
缺少括号让我正确理解函数类型
Prelude> :info flip
flip :: (a -> b -> c) -> b -> a -> c -- Defined in ‘GHC.Base’
我可以说:flip
正在使用一个函数并通过包围这样的方式返回另一个函数:
flip :: (a -> b -> c) -> (b -> a -> c)
或者我可以说flip
正在使用一个函数b
和a
并返回元素c
对于我有这种感觉的很多函数类型,我想必须有一些规则来消除这种歧义
答案 0 :(得分:6)
实际上,这不是歧义,它是一个特征!
例如,使用加号运算符(+)。它有类型
(+)::Num a=>a->a->a
您可以将其视为一个带两个数字的函数,并返回第三个。
number
\
----> number
/
number
你这样使用 -
(+) 1 2 (-- evaluates to 3)
or
1 + 2 (-- evaluates to 3)
或,您可以将其用作
(+)::Num a=>a->(a->a)
取一个数字,并输出一个完整的函数,其域和范围都是一个数字,即Num a=>a->a
。
number ------> <function>
例如
(+) 1 (-- evaluates to incrementorFunc)
....also written as (+ 1)
其中incrementorFunc
是向数字添加一个的函数(即incrementorFunc = \x -> 1+x
)。
您现在可以传递此函数以在代码中的其他位置使用。
这种二元性本质上内置于所有函数中,因此类型描述中不需要括号。这个功能是Haskells最大的优势之一。
答案 1 :(得分:2)
您不需要括号,因为两者之间没有区别。
纯粹主义者会说所有Haskell函数只需要一个参数。没有多个参数函数。例如:
map f [1..10]
被解释为:
(map f) [1..10]
即,map
应用参数f
,结果应用参数[1..10]
。
这种解释是使Haskell中的自动currying工作的原因。从某种意义上说,在Haskell中,currying是一种幻觉 - 即我们看到map f
,我们看到map
的curry形式,因为只有一个参数。实际上map
只接受一个参数,因此map f
已完全应用。