结合绑定和返回

时间:2014-02-16 08:29:36

标签: haskell

考虑:

x `f` y = x >>= (return . y)

此函数f似乎与<$>flip liftM非常相似,但<$>似乎不起作用,我必须为{{定义中缀运算符1}}让它看起来不错,我假设一个已经存在?

是否有类似于我所描述的功能以及它是什么?

3 个答案:

答案 0 :(得分:7)

它是flip liftM,但不是<$>。它与flip <$>几乎完全相同,但后者适用于Functor类型类,而不是Monad。 (在最新的标准库中,FunctorMonad之间的关系尚未反映在类型类层次结构but it will be)中。

如果您想查找定义的位置,请转到FP Complete's Hoogle,输入您要查找的类型

Functor f => f a -> (a -> b) -> f b

并发现it is defined in lens

答案 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层级检修发生之前。