IO monad的逻辑和严格性

我正在尝试在Haskell中编写一个简单的程序。 它应该基本上并行运行两个shell命令。 代码如下:

import System.Cmd
import System.Exit
import Control.Monad

exitCodeToBool ExitSuccess = True
exitCodeToBool (ExitFailure _) = False

run :: String -> IO Bool
run = (fmap exitCodeToBool) . system

main = liftM2 (&&) (run "foo") (run "bar")

但命令“foo”返回ExitFailure,我希望“bar”永远不会运行。 不是这种情况! 它们都运行并且都在控制台上显示错误。

与此同时

False && (all (/= 0) [1..])

评估非常好; 这意味着第二个参数不计算。 我如何在我的应用程序中执行系统命令?


我认为使用&&进行条件执行是一个坏习惯。 当然这只是一个合理的做法,可以避免副作用,例如False && all (/=0) [1..] ,但是当有副作用时,让它们依赖于这样的隐藏的方式。 (因为这种做法非常普遍,所以大多数程序员会立即认识到这一点;但我认为这不是我们应该鼓励的,至少在Haskell中是这样。)

你想要的是一种表达方式:“执行一些动作,直到产生False ”。

举个简单的例子,我只是明确地做到这一点:

main = do
   e0 <- run "foo"
   when e0 $ run "bar"

或简称: run "foo" >>= (`when` run "bar")

如果你想更广泛地使用它,最好是以更一般的方式来完成。 简单地检查一个布尔条件不是很一般,你通常也会想传递某种结果。 传递结果是我们使用monad来处理IO的主要原因,而不是简单地列出原始操作。

啊哈,monads! 事实上,你需要的是IO monad,但是有一个额外的“kill switch”:要么执行一系列操作,每个操作都可能会传递一些结果,或者 - 如果其中任何一个失败 - 则会中止整个事件。 听起来很像Maybe ,对吧?

http://www.haskell.org/hoogle/?hoogle=MaybeT

import Control.Monad.Trans.Maybe

run :: String -> MaybeT IO ()
run s = MaybeT $ do
   e <- system s
   return $ if exitCodeToBool e then Just () else Nothing

main = runMaybeT $ do
   run "foo"
   run "bar"

你说你想并行运行命令,只有在“foo”成功时才运行“bar”。 这个不成立。 你必须决定,如果你想要并行或顺序运行它。

如果您只想在“foo”成功时运行“bar”,请尝试:

import System.Process

main = do callCommand "foo"
          callCommand "bar"

或者,如果您想要并行运行它,请尝试:

import System.Process
import Control.Concurrent


myForkIO :: IO () -> IO (MVar ())
myForkIO io = do
    mvar <- newEmptyMVar
    forkFinally io (_ -> putMVar mvar ())
    return mvar

main = do mvar <- myForkIO $ callCommand "foo"
          callCommand "bar"
          takeMVar mvar

IO操作

liftM2 f action1 action2

为任何二进制函数运行f (例如, (&&) )。 如果你想运行action1你可以按如下方式编写它:

--| Short-circuit &&
sAnd :: IO Bool -> IO Bool -> IO Bool
sAnd action1 action2 = do
    b <- action1
    if b then action2 else return False

将其用作sAnd action1 action2

链接地址: http://www.djcxy.com/p/43013.html

上一篇: Logical AND strictness with IO monad

下一篇: What does "coalgebra" mean in the context of programming?