【发布时间】:2019-01-22 17:57:52
【问题描述】:
阅读 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 传递给flip 的签名,最后将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 f = \arg1 arg2 -> f arg2 arg1是将a -> r -> b转换为r -> a -> b所需的全部内容。在 Haskell 中,函数都是一个值的一个参数(有时该值是另一个函数),这也相当于flip f arg1 arg2 = f arg2 arg1。