Lifts 和扩展的双重概念在 Haskell 中绝对使用,也许最突出的是在 comonadic extend 和 monadic bind 的幌子下。 (令人困惑的是,extend 是电梯,而不是扩展。)comonad w 的 extend 让我们采用函数 w a -> b 并将其沿 extract :: w b -> b 提升以获取地图 w a -> w b。在ASCII艺术中,给定图表
w b
|
V
w a ---> b
在垂直箭头是提取的地方,extend 给了我们一个对角箭头(使图表通勤):
-> w b
/ |
/ V
w a ---> b
大多数 Haskeller 更熟悉的是 bind (>>=) 的双重概念,用于单子 m。给定一个函数a -> m b 和return :: a -> m a,我们可以沿着return“扩展”我们的函数,得到一个函数m a -> m b。在 ASCII 艺术中:
a ---> m b
|
V
m a
给我们
a ---> m b
| __A
V /
m a
(那个A是一个箭头!)
所以是的,extend 可以被称为lift,bind 可以被称为extend。 至于 Haskell 的 lifts,我不知道他们为什么这么叫!
编辑:实际上,我再次认为,Haskell 的 lifts 实际上是扩展。如果f 是可应用的,并且我们有一个函数a -> b -> c,我们可以将这个函数与pure :: c -> f c 组合得到一个函数a -> b -> f c。 Uncurrying,这与函数(a, b) -> f c 相同。现在我们也可以用pure 打(a, b) 来得到一个函数(a, b) -> f (a, b)。现在,通过fmaping fst 和snd,我们得到函数f (a, b) -> f a 和f (a, b) -> f b,我们可以将它们组合起来得到函数f (a, b) -> (f a, f b)。与我们之前的pure 组合得到(a, b) -> (f a, f b)。呸!回顾一下,我们有 ASCII 艺术图
(a, b) ---> f c
|
V
(f a, f b)
现在liftA2 给了我们一个函数(f a, f b) -> f c,我不会画它,因为我厌倦了制作糟糕的图表。但重点是,图表是通勤的,所以liftA2 实际上为我们提供了水平箭头沿垂直箭头的延伸。