繁体   English   中英

从应用(<*>)混淆中导出monad绑定

[英]Deriving monad bind from applicative (<*>) confusion

通过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接受一个函数,它接受两个参数,然后是两个单独的参数,并返回一个值。 在绑定示例中,我们将arb作为(a -> b -> c)传递,然后将<*>作为b的翻转签名,最后ra作为a 我看不出来。

我已经尝试使类型更具体到我的实际示例,所以你可以重写<*>

(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)

我也可以为绑定做同样的事情

(>>=) :: (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

(注意如何选择名称来反映类型!)重写你给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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM