如何在 Haskell 中执行命令列表?

Kiw*_*der 2 haskell

我是 Haskell 的新手,我一直在system为我执行 shell 命令,因为我只对退出状态感兴趣。我注意到,因为我可以做这样的事情:

ls <- system "ls"
pwd <- system "pwd"
Run Code Online (Sandbox Code Playgroud)

这正确地执行了两个命令。我正在考虑执行这些命令的数组,例如

lsAndPwd <- return $ system <$> ["ls", "pwd"]
Run Code Online (Sandbox Code Playgroud)

我很惊讶这实际上并没有执行任何操作。这会编译,我检查了lsAndPwd它的类型是否正确,[IO GHC.IO.Exception.ExitCode]但从未执行过命令。这是怎么回事,我怎样才能让它发挥作用?

Apl*_*123 5

你应该使用mapM而不是<$>这样你得到一个IO [ExitCode],而不是一个[IO ExitCode]。这样,它就被收集到一个可以运行的 IO monad 中:

lsAndPwd <- mapM system ["ls", "pwd"]
Run Code Online (Sandbox Code Playgroud)

或者,调用sequence整个事情:

lsAndPwd <- sequence $ system <$> ["ls", "pwd"]
Run Code Online (Sandbox Code Playgroud)

  • @Kiwibreeder `IO` 操作是“惰性的”,除非它们位于 `main :: IO ()` do 块的方式或使用 do 表示法或一元绑定 (`&gt;&gt;=`) 从它到达的方式。特别是,它们可以像任何其他值一样存储在容器中。因此,如果您有一个“IO”操作列表,则需要某种组合器将“IO”操作列表转换为返回列表的“IO”操作。结果操作可以放入“main”的 do 块中并执行。有一系列函数可以执行此类操作,例如“sequence”、“traverse”、“traverse_”、“for”和“for_”。 (2认同)