IO Monad中的短路和

mb1*_*b14 6 haskell

我知道问题已被问到,但我不敢相信没有直接的答案.

我理解在(&&)中隐藏副作用是不好的,但在我的情况下,副作用只是在检查过时的世界(存在文件,检查修改时间等,询问用户是/否的问题) .

那么haskell的方法是什么样的,所以如果cond1为false,则不执行cond2.

cond1, cond2 :: IO bool


main = do
   cond <- liftM2 (&&) con1 con2
   if cond
   then   result1
   else   result2
Run Code Online (Sandbox Code Playgroud)

我期待类似cond <- all [con1, con2]或相当的东西,但我找不到任何东西.

更新

我可以看到很多手动解决方案.我仍然感到疑惑,这个功能在某处并不存在.lazzy评估的一个优点是它不仅&&像C中的硬编码那样短路.在命令式模式下,Haskell甚至不能短路,这真的很奇怪&&.虽然,所有解决方案都以某种方式使用,如果短路评估.有没有办法制作通用的lazzy liftM2

Gab*_*lez 8

这就是做什么Pipes.Prelude.and,经过有效生成的条件和短路的惰性流,如果它们中的任何一个是False:

import Pipes (each)
import qualified Pipes.Prelude as Pipes

conds :: [IO Bool]
conds = ...

main = do
    cond <- Pipes.and (each conds >-> Pipes.sequence)
    print cond
Run Code Online (Sandbox Code Playgroud)

相关链接:


Mic*_*ael 4

这与其他人所说的没有什么不同,但这不是最简单的只是模仿以下的定义and

 andM = foldr (&&&) (return True)
  where ma &&& mb = ma >>= \p -> if p then mb else return p
Run Code Online (Sandbox Code Playgroud)

然后我们得到,说:

 > let test1 = putStrLn "This test succeeds" >> return True
 > let test2 = putStrLn "This test fails" >> return  False
 > andM [test1,test2,undefined,undefined]
 This test succeeds
 This test fails
 False
Run Code Online (Sandbox Code Playgroud)

如果andM没有“短路”,则未定义的单元格将被评估并返回异常。

这有点令人恼火,liftM2 (&&)没有像人们希望的那样发挥作用。

编辑:我刚刚注意到,正如人们所预料的那样,这是在monad-loopshttp://hackage.haskell.org/package/monad-loops-0.4.2.1/docs/src/Control-Monad-Loops.html中定义的#和M