提升“if”功能意外行为

时间:2016-03-06 14:34:16

标签: haskell monads applicative io-monad lifting

在我的程序中,我使用在其中一个模块中定义的函数if'而不是内置的if-then-else构造。它的定义很简单,效果很好。

但是,代码中有一个地方需要将其应用于monad值(在我的情况下为IO),即类型签名应该看起来有点像IO Bool -> IO a -> IO a -> IO a。 当然,我试图解除它。

if' <$> mb <*> action1 <*> action2

但是当我尝试评估表达时,我得不到我期望的结果。

*Main> if' <$> return True <*> putStrLn "yes" <*> putStrLn "no"
yes
no

我知道<*>描述读取“顺序应用”,所以也许就是这样。但是这里发生了什么?我可以在不编写全新专用功能的情况下修复它吗?

1 个答案:

答案 0 :(得分:3)

(<*>)评估它的两个参数,因此它有效地解决了一些应用程序的应用程序。检查值和更改计算未来的能力是Monad类超过Applicative的额外功率,因此您需要使用它,例如。

mif' :: Monad m => m Bool -> m a -> m a -> m a
mif' bm xm ym = bm >>= (\b -> if b then xm else ym)