9

你能解释一下表达式 ((.).(.)) 的含义吗?据我所知 (.) 的类型为 (b -> c) -> (a -> b) -> a -> c。

4

2 回答 2

24

(.) . (.)是组合算子与自身的组合。

如果我们看

((.) . (.)) f g x

我们可以评估几个步骤,首先我们加上括号,

((((.) . (.)) f) g) x

然后我们申请,使用(foo . bar) arg = foo (bar arg)

~> (((.) ((.) f)) g) x
~> (((.) f) . g) x
~> ((.) f) (g x)
~> f . g x

更有原则,

(.) :: (b -> c) -> (a -> b) -> (a -> c)

所以,(.)作为 的第一个参数(.),我们必须统一

b -> c

(v -> w) -> (u -> v) -> (u -> w)

这会产生

b = v -> w
c = (u -> v) -> (u -> w)

(.) (.) = ((.) .) :: (a -> v -> w) -> a -> (u -> v) -> (u -> w)

现在,要将其应用于(.),我们必须统一类型

a -> v -> w

类型为(.), 重命名后

(s -> t) -> (r -> s) -> (r -> t)

产生

a = s -> t
v = r -> s
w = r -> t

因此

(.) . (.) :: (s -> t) -> (u -> r -> s) -> (u -> r -> t)

并且从我们可以(几乎)读取的类型中,(.) . (.)将(一个参数的)函数应用于两个参数的函数的结果。

于 2013-02-05T12:48:54.557 回答
2

你已经得到了答案,这里有一个稍微不同的看法。

组合逻辑 (.)中是B -combinator : Babc = a(bc)。在编写组合子表达式时,通常假定每个标识符仅由一个字母组成,并在应用程序中省略空格,以使表达式更具可读性。当然,通常的柯里化适用:abcdeis (((ab)c)d)e,反之亦然。

(.)B,所以((.) . (.))== (.) (.) (.)== BBB。所以,

BBBfgxy = B(Bf)gxy = (Bf)(gx)y = Bf(gx)y = (f . g x) y    
 abc        a  bc                 a b  c                  

我们可以在最后扔掉两个ys (这被称为eta-reduction : Gy=Hy--> G=H,如果y没有出现在H1中)。但是,另一种表达方式是

BBBfgxy = B(Bf)gxy = ((f .) . g) x y = f (g x y)     -- (.) f == (f .)
-- compare with:       (f .) g x = f (g x)

((f .) . g) x y可能比输入更容易((.).(.)) f g x y,但是 YMMV.


1例如,使用S组合器,定义为Sfgx = fx(gx),不考虑该规则,我们可以写

Sfgx = fx(gx) = B(fx)gx = (f x . g) x
Sfg = B(fx)g = (f x . g)   --- WRONG, what is "x"?

这是胡说八道。

于 2013-02-06T10:45:17.050 回答