Haskell未执行所有外部shell命令

Haskell未执行所有外部shell命令,shell,haskell,io,lazy-evaluation,Shell,Haskell,Io,Lazy Evaluation,我编写了这个程序,并使用: ghc --make shell.hs $./shell enter your number: 6 6 okay... it execute 6 time... import os for i in range(6): os.system("echo " + str(i)) os.system("sleep 2") 当我运行时,它看起来像: ghc --make shell.hs $./shell enter your number: 6 6 okay

我编写了这个程序,并使用:

ghc --make shell.hs
$./shell
enter your number:
6
6
okay... it execute 6 time...
import os
for i in range(6):
  os.system("echo " + str(i))
  os.system("sleep 2")
当我运行时,它看起来像:

ghc --make shell.hs
$./shell
enter your number:
6
6
okay... it execute 6 time...
import os
for i in range(6):
  os.system("echo " + str(i))
  os.system("sleep 2")
如果我删除
sleep 2
语句,它将快速退出,但只输出
6

我试着按照一个类似问题给出的建议(这是下面代码中的内容),但没有成功

看起来很奇怪,它没有执行所有的命令。如何强制它以严格的顺序执行所有命令?懒散是一个很好的特性,但是当谈到IO时,它只是很糟糕,或者我不是足够的专家来理解它

我要做的是严格按照顺序执行列表中的所有命令,我不希望Haskell代表我“智能地”删除一些命令(如果我想在shell中执行sleep 2秒钟,我应该被允许这样做)

如果必须使用
waitForProcess
来解决这个问题,那么我的问题是我不知道如何使用它。我尝试过谷歌,但没有看到一个简单的例子

请注意,我希望为下面给出的程序代码提供一个有效的代码解决方案,并且应该有一个合理的保证,即当下面给出的Python程序运行时,该程序能够在典型Linux(比如Debian 7)上运行在bash上

import System.Process
import System.Exit

main = do
 putStrLn "enter your number:"
 n <- getLine
 main1 (readInt n)
 putStrLn ("okay... it execute " ++ n ++" time...")

readInt:: String -> Int
readInt = read

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 if n == 0 then (main1 (n-1)) else return ()

使用
表单
编写更像Python版本的代码怎么样

import Control.Monad

main1 n = do
  forM_ [n,n-1 .. 1] $ \n -> do
    ExitSuccess <- system ("echo " ++ (show n))
    ExitSuccess <- system "sleep 2"
    return ()
import-Control.Monad
main1 n=do
表格[n,n-1..1]$\n->do

ExitSuccess使用
表单
编写更像Python版本的代码如何:

import Control.Monad

main1 n = do
  forM_ [n,n-1 .. 1] $ \n -> do
    ExitSuccess <- system ("echo " ++ (show n))
    ExitSuccess <- system "sleep 2"
    return ()
import-Control.Monad
main1 n=do
表格[n,n-1..1]$\n->do

ExitSuccess使用
表单
编写更像Python版本的代码如何:

import Control.Monad

main1 n = do
  forM_ [n,n-1 .. 1] $ \n -> do
    ExitSuccess <- system ("echo " ++ (show n))
    ExitSuccess <- system "sleep 2"
    return ()
import-Control.Monad
main1 n=do
表格[n,n-1..1]$\n->do

ExitSuccess使用
表单
编写更像Python版本的代码如何:

import Control.Monad

main1 n = do
  forM_ [n,n-1 .. 1] $ \n -> do
    ExitSuccess <- system ("echo " ++ (show n))
    ExitSuccess <- system "sleep 2"
    return ()
import-Control.Monad
main1 n=do
表格[n,n-1..1]$\n->do

ExitSuccess程序正在执行您告诉他的操作:

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 if n == 0 then (main1 (n-1)) else return ()
或者,相当于:

import Control.Monad

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 when (n > 0) $ main1 (n-1)
在这里,您知道
mapM\uu
[1..n]
所做的事情,因此,将它们组合在一起可以告诉您
execute
操作将执行
n次


在任何情况下,
IO
monad保证所有操作都按顺序执行,因此您不应该将代码未按预期次数执行的事实归因于Haskell lazyness


懒散和输入/输出的问题是不同的。

程序正在执行您告诉他的操作:

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 if n == 0 then (main1 (n-1)) else return ()
或者,相当于:

import Control.Monad

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 when (n > 0) $ main1 (n-1)
在这里,您知道
mapM\uu
[1..n]
所做的事情,因此,将它们组合在一起可以告诉您
execute
操作将执行
n次


在任何情况下,
IO
monad保证所有操作都按顺序执行,因此您不应该将代码未按预期次数执行的事实归因于Haskell lazyness


懒散和输入/输出的问题是不同的。

程序正在执行您告诉他的操作:

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 if n == 0 then (main1 (n-1)) else return ()
或者,相当于:

import Control.Monad

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 when (n > 0) $ main1 (n-1)
在这里,您知道
mapM\uu
[1..n]
所做的事情,因此,将它们组合在一起可以告诉您
execute
操作将执行
n次


在任何情况下,
IO
monad保证所有操作都按顺序执行,因此您不应该将代码未按预期次数执行的事实归因于Haskell lazyness


懒散和输入/输出的问题是不同的。

程序正在执行您告诉他的操作:

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 if n == 0 then (main1 (n-1)) else return ()
或者,相当于:

import Control.Monad

main1 n = do
 ExitSuccess <- system ("echo " ++ (show n))
 ExitSuccess <- system "sleep 2"
 when (n > 0) $ main1 (n-1)
在这里,您知道
mapM\uu
[1..n]
所做的事情,因此,将它们组合在一起可以告诉您
execute
操作将执行
n次


在任何情况下,
IO
monad保证所有操作都按顺序执行,因此您不应该将代码未按预期次数执行的事实归因于Haskell lazyness


懒惰和输入/输出的问题是不同的。

我注意到的第一件事是你的
if-then-else
短语似乎是错误的。尝试将then表达式与else表达式交换。您希望在n==0时返回。。。当然,您也可以使用模式匹配将其拆分:
main1 0=do return();main1 n=do ExitSuccess有更好的编写方法,但唯一真正的问题是循环中的测试是错误的。你想要的是
n>1
而不是
n==0
@BitTickler谢谢。它很好用。抱歉给你添麻烦了。我接受你的建议,将其转化为答案。python程序上的一个注意事项是:你应该避免
os.system
。使用
subprocess.call
代替:来自subprocess import call的
;呼叫(['echo',str(i)]);呼叫(['sleep','2'])
。当(且仅当)您需要shell功能时,您可以将
shell=True
传递给
call
。我注意到的第一件事是您的
if-then-else
短语似乎有误。尝试将then表达式与else表达式交换。您希望在n==0时返回。。。当然,您也可以使用模式匹配将其拆分:
main1 0=do return();main1 n=do ExitSuccess有更好的编写方法,但唯一真正的问题是循环中的测试是错误的。你想要的是
n>1
而不是
n==0
@BitTickler谢谢。它很好用。抱歉给你添麻烦了。我接受你的建议,将其转化为答案。python程序上的一个注意事项是:你应该避免
os.system
。使用
subprocess.call
代替:来自subprocess import call的
;呼叫(['echo',str(i)]);呼叫(['sleep','2'])
。当(且仅当)您需要shell功能时,您可以传递
shell=True