考虑:
x `f` y = x >>= (return . y)
此函数f
似乎与<$>
和flip liftM
非常相似,但<$>
似乎不起作用,我必须为{{定义中缀运算符1}}让它看起来不错,我假设一个已经存在?
是否有类似于我所描述的功能以及它是什么?
答案 0 :(得分:7)
它是flip liftM
,但不是<$>
。它与flip <$>
几乎完全相同,但后者适用于Functor
类型类,而不是Monad
。 (在最新的标准库中,Functor
和Monad
之间的关系尚未反映在类型类层次结构but it will be)中。
如果您想查找定义的位置,请转到FP Complete's Hoogle,输入您要查找的类型
Functor f => f a -> (a -> b) -> f b
答案 1 :(得分:2)
你的功能
x `f` y = x >>= (return . y)
相当于flip fmap
,因此如果您不介意交换订单,可以import Data.Functor
,定义fmap
并将其写为
y <$> x
(无需等待Functor
成为Monad
的超类;您今天可以继续定义它。)
这有很好的优先级,所以你可以编写像
这样的东西munge = Just . remove bits . add things <$> operation 1
>>= increase something <$> operation 2
而不是
munge' = do
thing1 <- operation 1
let thing2 = Just . remove bits. add things $ thing1
thing3 <- operation 2
return . increase something $ thing3
但更好的是,如果你改为import Control.Applicative
(也导出<$>
),你可以组合多个东西,例如:
addLine = (+) <$> readLine <*> readLine >>= print
而不是
addLine' = do
one <- readLine
two <- readLine
print (one + two)
如果the Functor-Applicative-proposal继续,你必须制作所有Monads Applicatives(以及Functors)。你也可以从现在开始。
如果你的Monad还不是申请人,你可以定义pure = return
和
mf <*> mx = do
f <- mf
x <- mx
return (f x)
如果它不是Functor,您可以定义
fmap f mx = do
x <- mx
return (f x)
该提案建议使用来自(<*>) = ap
的{{1}}和fmap = liftM
,但上述定义也很简单,您可能会在自己的Monad中更容易找到它。
答案 2 :(得分:1)
Data.Generics.Serialization.Standard
导出(>>$)
,定义为flip liftM
。不完全是一个依赖的通用模块,但如果你愿意,你可以。我在其他特定于应用程序的模块中看到了类似的定义。这表明没有通用模块定义这样的功能。
最不痛苦的解决方案可能是定义自己的解决方案,至少在大Monad层级检修发生之前。