提升的“如果”函数表现出意外
Lifted „if“-function behaves unexpectedly
在我的程序中,我使用了在其中一个模块中定义的函数 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
我知道 <*>
描述是“顺序应用”,所以也许就是这样。但是这里发生了什么?我可以在不编写全新的专用函数的情况下修复它吗?
(<*>)
评估它的两个参数,因此它有效地提升了一些应用程序的应用程序管道。检查值和改变计算的未来的能力是 Monad
class 超过 Applicative
的额外能力,所以你需要使用它来代替,例如
mif' :: Monad m => m Bool -> m a -> m a -> m a
mif' bm xm ym = bm >>= (\b -> if b then xm else ym)
在我的程序中,我使用了在其中一个模块中定义的函数 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
我知道 <*>
描述是“顺序应用”,所以也许就是这样。但是这里发生了什么?我可以在不编写全新的专用函数的情况下修复它吗?
(<*>)
评估它的两个参数,因此它有效地提升了一些应用程序的应用程序管道。检查值和改变计算的未来的能力是 Monad
class 超过 Applicative
的额外能力,所以你需要使用它来代替,例如
mif' :: Monad m => m Bool -> m a -> m a -> m a
mif' bm xm ym = bm >>= (\b -> if b then xm else ym)