2

在我的程序中,我使用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

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

4

1 回答 1

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)
于 2016-03-06T14:46:22.173 回答