当前位置:  开发笔记 > 小程序 > 正文

IO monad的逻辑和严格性

如何解决《IOmonad的逻辑和严格性》经验,为你挑选了1个好方法。

我想在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..])

评价完美; 这意味着不计算第二个参数.如何在我的应用程序中使用系统命令执行相同的操作?



1> leftaroundab..:

我认为使用&&条件执行是一种坏习惯.当然这只是一个理由,为做到这一点的事无副作用,喜欢的东西False && all (/=0) [1..],但是当有副作用这是相当confusionsome使他们依赖于这样一个隐藏的方式.(因为这种做法非常普遍,大多数程序员会立即认出来;但我不认为这是我们应该鼓励的,至少在Haskell中是这样.)

你想要的是一种表达方式:"执行一些行动,直到一个人屈服False".

对于您的简单示例,我只是明确地这样做:

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

或短:run "foo" >>= (`when` run "bar").

如果您想更广泛地使用它,最好以更一般的方式进行.简单地检查一个布尔条件不是很一般,你通常也想传递某种结果.传递结果是我们使用monad进行IO的主要原因,而不仅仅是原始动作的列表.

啊哈,单子!实际上,你需要的是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"

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有