一般的monadic`(< |>)`?

时间:2015-07-08 14:13:29

标签: haskell monads

我正在寻找一种更简洁/惯用的写作方式getAorB

getAorB = do
  a <- getA
  case a of
    Just _  -> return a
    Nothing -> getB

这是否已作为库函数存在?

请注意liftM2 (<|>) getA getB与:

相同
do a <- getA
   b <- getB
   return $ a <|> b

getAorB不同,因为即使getB返回getA,也始终会在Just上调用绑定。

4 个答案:

答案 0 :(得分:2)

You can use the maybe function (b -> (a -> b) -> Maybe a -> b) with its default value:

getAorB :: Monad m => m a
getAorB = getA >>= maybe getB return

I don't think there's a single function that does this anywhere.

Trying to use an Alternative (such as MaybeT) doesn't work well here imo as it considers the second action to be fallible as well, which your getB isn't. If it if was, you should consider using MaybeT though:

getAorB :: Monad m => m (Maybe a)
getAorB = runMaybeT $ MaybeT getA <|> MaybeT getB

答案 1 :(得分:1)

Sounds like an mplus for MaybeT.

答案 2 :(得分:0)

因为(&lt; |&gt;)从应用中获得它的力量不是不可能的吗? 感觉就像你正在寻找的类型是

Monad m => a ->[m (Maybe a)] -> m a

代替?或者也许

Monad m => a -> (a -> Bool) -> [m a] -> m a

Hoogle并没有给我任何东西。

答案 3 :(得分:0)

隐藏所有变形金刚:

import Control.Monad.Trans.Maybe

getAOrB :: m (Maybe a) -> m (Maybe a) -> m (Maybe a)
getAOrB getA getB = runMaybeT (MaybeT getA <|> MaybeT getB)

但我可能只会在所有地方使用MaybeT

getAOrB' :: MaybeT m a -> MaybeT m a -> MaybeT m a
getAOrB' = (<|>)

请注意,此类型与第一个实现的类型略有不同;它与第二次实现的类型相同但行为更好。