2010-11-25 121 views
1

有人能解释我为什么做这些功能 有不同数量的参数和行为,但 的同类型签名,但它们都是正确的吗?Haskell的类型签名问题

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 

谢谢。

+2

http://www.haskell.org/haskellwiki/Eta_conversion? – 2010-11-25 17:30:35

+3

两种功能的行为方式不同?看起来和我一样...... – sepp2k 2010-11-25 17:54:27

回答

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脱糖的形式,我们得到:

comp1 = \f -> \g -> \x -> g (f x) 

这是完全一样的comp2脱糖的形式,如此清晰的定义是等价的。

4

comp1 f g = g.f写在point-free样式(不是指分数,而是以的值)。当您呼叫comp1时,隐含地将第三个参数传递给g.f,其是和f这两个函数的组成:(g.f) x等于g (f x),即g通过f x的结果。 comp1中不存在参数x,因为它隐式传递给函数。 (作为部分应用咖喱功能,如果它让你感觉更好你能想到的comp1。)

comp2的类型要求有两个功能,一是从(a->b)和另一(b->c),以及参数类型为a。没有必要在签名中加上a ->

这两个函数真的是等价的;一个简单地使用一些Haskell技巧来更简洁。

1

Currying。 ML和Haskell中的多参数函数只是用于返回函数的单参数函数的语法糖;它返回的函数接受其余的参数。