我正在尝试用 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 中不应该鼓励。)
你想要的是一种表达方式:“执行一些动作,until一个产量False
".
对于您的简单示例,我只是明确地执行此操作:
main = do
e0 <- run "foo"
when e0 $ run "bar"
或简称:run "foo" >>= (`when` run "bar")
.
如果您想更广泛地使用它,最好以更通用的方式进行。简单地检查布尔条件并不是很通用,您通常还想传递某种结果。传递结果是我们使用 monad 进行 IO 的主要原因,而不是简单地使用原始操作列表。
啊哈,单子!事实上,您需要的是 IO monad,但需要一个额外的“终止开关”:要么您执行一系列操作,每个操作可能会传递一些结果,要么 – 如果其中任何一个失败 – 您将中止整个操作。听起来很像Maybe
, right?
http://www.haskell.org/hoogle/?hoogle=MaybeT 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"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)