柯里化由 - 链接的函数链:

Currying of chain of functions linked by -:

我正在学习 Haskell LYAH tutorial. I am at Walk the line 部分。它介绍了非常有用的运算符:

x -: f = f x 

它允许使用此运算符获取初始状态和链函数:

(0,0) -: landLeft 1 -: landRight 4 -: landLeft (-1) -: landRight (-2)

我的问题是我怎样才能使用这个函数链并给它一个单独的名称?例如:

chain = landLeft 1 -: landRight 4 -: landLeft (-1) -: landRight (-2)
(0,0) -: chain

不,你不能。原因是

chain = x -: y -: z

表示

chain = z (y x)

因此,当您申请 w -: chain 时,您将获得

w -: chain = z (y x) w

这本质上是垃圾,类型检查器可能会抱怨。 你反而想要

w -: chain = z (y (x w)))

您可以做的是使用组合运算符 (.).

定义链
chain = z . y . x

请注意,该顺序与您在 -: 中的顺序 相反。要颠倒顺序,您可以改用

import Control.Arrow (>>>)
chain = x >>> y >>> z

你可以给出一个明确的论点

chain x = x -: landLeft 1 -: landRight 4 -: landLeft (-1) -: landRight (-2)

这个运算符本身不太利于链接操作,它实际上只是 flip ($),而且我们知道你不能用 chain = h $ g $ f 来替换 h $ g $ f $ x。相反,通常将 $ 替换为 .,如 chain = h . g . f。如果您想改用从左到右的样式,我建议制作一个单独的运算符相当于 flip (.):

(-:) = flip ($)
(-.) = flip (.)

chain = landLeft 1 -. landRight 4 -. landLeft (-1) -. landRight (-2)

或者您可以将 Control.Arrow 中的运算符与您的 -: 运算符一起使用:

import Control.Arrow

chain = landLeft 1 >>> landRight 4 >>> landLeft (-1) >>> landRight (-2)

> x -: chain

实际上,给定 Control.Arrow 中的运算符,您可以定义 landLeftlandRight:

landLeft c = first (+c)
landRight c = second (+c)
landBoth c = (+c) *** (+c)