【发布时间】:2020-01-21 21:03:59
【问题描述】:
假设我有两个函数
f :: Monad m => a -> m a
g :: a -> a
我想像这样连续应用于某些元素:
(return x) >>= f >>= g
这不起作用,因为 g 是纯的,所以我首先需要“人为地”将它变成一元的。一种可能是
(return x) >>= f >>= (return . g)
这对我来说不是很直观。另一种可能性是使用 Monad is Applicative:
(return g) <*> ((return x) >>= f)
但这不是很直观,因为函数和参数的顺序不同:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
处理此问题的规范方法是什么?如果(>>==) = (flip ((<*>) . pure)) 可以写((pure x) >>= f) >>== g,除了运算符优先级之外,这很好。当然,monadic 代码中的纯函数是很常见的事情,那么肯定有一种标准的方法来处理它们吗?
编辑:我最初并没有这么说,但我在想一种情况,我有几个函数,一些是纯函数,一些是单子函数,我想以某种随机顺序应用它们。
【问题讨论】:
-
你可以使用
fmap,所以return x >>= fmap g . f,你可以将其简化为fmap g (f x)