use*_*926 5 haskell logical-operators strictness
我想在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")
Run Code Online (Sandbox Code Playgroud)
但命令"foo"返回ExitFailure,我希望"bar"永远不会运行.不是这种情况!它们都运行并且都在控制台上显示错误.
同时
False && (all (/= 0) [1..])
Run Code Online (Sandbox Code Playgroud)
评价完美; 这意味着不计算第二个参数.如何在我的应用程序中使用系统命令执行相同的操作?
我认为使用&&条件执行是一种坏习惯.当然这只是一个理由,为做到这一点的事无副作用,喜欢的东西False && all (/=0) [1..],但是当有副作用这是相当confusionsome使他们依赖于这样一个隐藏的方式.(因为这种做法非常普遍,大多数程序员会立即认出来;但我不认为这是我们应该鼓励的,至少在Haskell中是这样.)
你想要的是一种表达方式:"执行一些行动,直到一个人屈服False".
对于您的简单示例,我只是明确地这样做:
main = do
e0 <- run "foo"
when e0 $ run "bar"
Run Code Online (Sandbox Code Playgroud)
或短: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"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
189 次 |
| 最近记录: |