我正在寻找一种更简洁/惯用的写作方式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
上调用绑定。
答案 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' = (<|>)
请注意,此类型与第一个实现的类型略有不同;它与第二次实现的类型相同但行为更好。