考虑使用ghci中的函数定义。
let myF = sin . cos . sum
其中,。代表两个函数的组合(右关联)。我可以打电话给
myF [3.14, 3.14]
它给了我想要的结果。显然,它将list [3.14,3.14]传递给函数'sum',并将其'result'传递给cos,依此类推。但是,如果我在翻译中这样做
let myF y = sin . cos . sum y
或
let myF y = sin . cos (sum y)
然后我遇到了麻烦。将此修改为以下内容可以得到我想要的结果。
let myF y = sin . cos $ sum y
或
let myF y = sin . cos . sum $ y
(。)的类型表明下面的形式应该没有问题,因为'sum y'也是一个函数(不是吗?After-all一切都是Haskell中的一个函数?)
let myF y = sin . cos . sum y -- this should work?
更有趣的是,我可以使用两个(或许多)参数(想想将列表[3.14,3.14]作为两个参数x和y),我必须写下面的
let (myF x) y = (sin . cos . (+ x)) y
myF 3.14 3.14 -- it works!
let myF = sin . cos . (+)
myF 3.14 3.14 -- -- Doesn't work!
关于这种形式的HaskellWiki有一些讨论他们称之为'PointFree'形式http://www.haskell.org/haskellwiki/Pointfree。通过阅读本文,我怀疑这种形式与两个lambda表达式的组合不同。当我尝试绘制一条分隔这两种风格的线时,我感到很困惑。
答案 0 :(得分:9)
让我们看一下types。对于sin
和cos
,我们有:
cos, sin :: Floating a => a -> a
sum
:
sum :: Num a => [a] -> a
现在,sum y
将其转换为
sum y :: Num a => a
这是一个值,而不是一个函数(你可以将它命名为一个没有参数的函数,但这非常棘手,你还需要命名() -> a
函数 - 在某个地方讨论过这个但是我现在找不到链接 - Conal谈到它。)
无论如何,尝试cos . sum y
将无效,因为.
期望双方都有类型a -> b
和b -> c
(签名为(b -> c) -> (a -> b) -> (a -> c)
)和{{ 1}}无法用这种风格书写。这就是为什么你需要包括括号或sum y
。
对于无点样式,简单的翻译方法是:
$
我们最后有mysum x y = x + y
,但我们现在无法将其删除。相反,重写为y
它有效。mysum x y = (x +) y
mysum x = (x +)
(我选择了一个简单的例子,对于更复杂的案例,你必须使用mysum = (+)
和其他人)
答案 1 :(得分:6)
不,sum y
不是一个功能。这是一个数字,就像sum [1, 2, 3]
一样。因此,完全可以理解您不能使用函数组合运算符(.)
。
并非Haskell中的所有功能都是功能。
答案 2 :(得分:3)
强制性的含义是:(空格)比
.
更紧密地绑定
Haskell中的大多数空格可以被认为是一个非常高的固定性$
(“应用”功能)。 w x . y z
与(w $ x) . (y $ z)
当您第一次了解$
和.
时,您还应该确保了解(空格),并确保您了解语言语义是如何隐式括起来的事情可能不会(乍一看)显得直观。