通过阅读 Haskell Book,我的大脑在以下示例中崩溃了。我真的不知道第 21 行的 flip 函数在做什么

1 class Functor f where
2   fmap :: (a -> b) -> f a -> f b
3
4 class Functor f => Applicative f where
5   pure :: a -> f a
6   (<*>) :: f (a -> b) -> f a -> f b
7
8 class Applicative f => Monad f where
9   return :: a -> f a
10   (>>=) :: f a -> (a -> f b) -> f b
11
12 instance Functor ((->) r) where
13   fmap = (.)
14
15 instance Applicative ((->) r) where
16   pure = const
17   f <*> a = \r -> f r (a r)
18
19 instance Monad ((->) r ) where
20   return = pure
21   ra >>= arb = flip arb <*> ra


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

-- ra >>= arb = flip arb <*> ra

据我了解,flip 接受一个函数,该函数接受两个参数,然后是两个单独的参数,并返回一个值。在绑定(bind)示例中,我们是否将 arb 作为 (a -> b -> c) 传递,然后将 <*> 作为翻转签名中的 b 传递,最后将 ra 作为 a 传递?我看不到。

我已经尝试使类型更具体到我的实际示例,以便您可以将 <*> 重写为
(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)

我可以对绑定(bind)做同样的事情
(>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)

所以即使是像我这样的傻瓜也能看出我们是否可以交换 <*>我们可以排队然后像
(<???>) :: (r -> a) -> (r -> a -> b) -> (r -> b)
(>>=) ::   (r -> a) -> (a -> r -> b) -> (r -> b)

但是看看那里的第二个参数,第一个需要 r 作为它的第一个参数,而 bind 需要一个 a
所以不知何故 flip 是这本书的例子正在为我们做这件事,但我真的不明白是怎么做的。任何帮助将不胜感激。

谢谢!

最佳答案

我认为最重要的一点是: flip 正在修改 arb ,而不是像您认为的那样修改 <*> 。我们已经“修改”了 <*> 以获得“正确”的参数顺序,只需按照我们得到它们的相反顺序给 <*> 参数!

现在了解详情。正如你所指出的,我们有:

(>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)

所以,因为我们在左边写了
ra >>= arb = ...

那么我们的范围是:
ra :: r -> a
arb :: a -> r -> b

(注意如何选择名称来反射(reflect)类型!)重写您为 flip 提供的类型,我们有
flip :: (a -> b -> c) -> b -> a -> c -- original
flip :: (a -> r -> b) -> r -> a -> b -- rename variables

因此:
flip arb :: r -> a -> b

现在回想一下你写的 (<*>) 类型:
(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)

因此,对于 (<*>) 的第一个参数,我们需要 r -> a -> b 类型的东西。嘿! flip arb 有那种类型!对于第二个参数,我们需要 r -> a 类型的东西。我们又走运了,因为 ra 有那种类型,所以......
flip arb <*> ra :: r -> b

(与中缀运算符一样,这​​是运算符 (<*>) 的应用,参数 flip arbra 。)我们希望拥有什么类型?好吧,我们现在回到 (>>=) 的类型:
(>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)

接受两个参数后,这应该返回 r -> b 类型的东西。很酷,这就是我们构建的。
ra >>= arb = flip arb <*> ra

关于haskell - 从应用 (<*>) 混淆派生 monad 绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54313967/

10-13 04:27