有人可以解释一下,为什么要这些功能 有不同数量的参数和行为,但是 相同类型的签名,但它们都是正确的吗?
comp1 :: (a -> b) -> (b -> c) -> a -> c
comp1 f g = g.f
comp2 :: (a -> b) -> (b -> c) -> a -> c
comp2 f g x = g (f x)
另外,为什么comp2有
comp2 :: (a -> b) -> (b -> c) -> a -> c
而不是
comp2 :: a -> (a -> b) -> (b -> c) -> a -> c
谢谢。
答案 0 :(得分:4)
comp1 f g = g.f
以point-free样式编写(不是指点,而是值)。当您致电comp1
时,会隐含地将第三个参数传递给g.f
,这是两个函数g
和f
的组合:(g.f) x
等于g (f x)
,即g
传递f x
的结果。 x
中不存在参数comp1
,因为它隐式传递给函数。 (您可以将comp1
视为部分应用的或咖喱功能,如果它让您感觉更好。)
comp2
的类型要求提供两个函数,一个来自(a->b)
,另一个(b->c)
,以及a
类型的参数。没有必要在其签名中加上a ->
。
这两个功能实际上是等价的;一个人简单地使用一些Haskell技巧来更简洁。
答案 1 :(得分:4)
comp2 f g x = g (f x)
是
的语法糖comp2 = \f -> \g -> \x -> g (f x)
类似地
comp1 f g = g.f
是糖的
comp1 = \f -> \g -> g.f
.
的定义是:
f1 . f2 = \x -> f1 (f2 x) -- Names of arguments have been changed to avoid confusion
因此,如果我们将定义插入comp1
的desugared形式,我们得到:
comp1 = \f -> \g -> \x -> g (f x)
这与comp2
的desugared形式完全相同,所以很明显这些定义是等价的。
答案 2 :(得分:1)
Currying。 ML和Haskell中的多参数函数只是返回函数的单参数函数的语法糖;它返回的函数将获取剩余的参数。