表达的(f . g) x
意思f (g x)
。
连贯地,(f . g) x y
意味着f (g x) y
。
请注意如何y
作为第二个参数传递给f
,而不是传递给g
。结果不是 f (g x y)
。
在您的情况下,(sort . (++)) x y
将意味着sort ((++) x) y
, 它将sort
使用第一个参数(++) x
(将列表x
添加到其列表参数的函数)和第二个参数调用y
。唉,这是错误的类型,因为sort
只需要一个参数。
因此,这也是无效的
appendAndSort x y = (sort . (++)) x y
因此,这也是
appendAndSort = sort . (++)
相比之下,((f .) . g) x y
确实按预期工作。让我们计算一下:
((f .) . g) x y
= -- same reasoning as above, y is passed to (f.), not g
(f .) (g x) y
= -- application associates on the left
((f .) (g x)) y
= -- definition of `(f.)`
(f . (g x)) y
= -- definition of .
f ((g x) y)
= -- application associates on the left
f (g x y)
所以这真的y
可以传递给g
(而不是f
)。
在我看来,“成语”(f .) . g
不值得使用。重点\x y -> f (g x y)
更容易阅读,而且不会太长。
如果你真的想要,你可以定义一个自定义组合运算符来处理两个参数的情况。
(.:) f g = \x y -> f (g x y)
然后,你可以写
appendAndSort = sort .: (++)