【问题标题】:Conditional IO action条件 IO 动作
【发布时间】:2017-06-11 15:36:41
【问题描述】:

我正在编写一个程序,该程序应该能够直接从命令行或从文件中读取输入,具体取决于传递的参数。例如。但是我无法使 IO 事件有条件。我的第一个想法是:

import System.Environment

main :: IO ()
main = do
 cla <- getArgs
 let flags = parseFlags (filter isFlag cla) []
 let args  = filter (not.isFlag) cla
 input <- if (elem "e" flags) then (head args) else (readFile (head args))

但这不起作用,因为(head args) 不是 IO 操作。我的下一个想法是:

import System.Environment

main :: IO ()
main = do
 cla <- getArgs
 let flags = parseFlags (filter isFlag cla) []
 let args  = filter (not.isFlag) cla
 file <- (readFile (head args))
 let input = if (elem "e" flags) then (head args) else (file)

但如果输入不是文件名,这将出错。有没有明智的方法来做到这一点?我是不是错误地处理了这个问题?

【问题讨论】:

  • 在您的第一段代码中,问题实际上看起来像 (head args) 不是 IO 操作,但 (readFile (head args)) 是。您将返回 2 种不同的类型。尝试将 (head args) 更改为 (return (head args)) 以将值放入 IO monad。
  • @Carcigenicate 谢谢!这正是我想要的。如果您想发布详细说明此问题的答案,我很乐意接受。
  • 不相关,但你怎么知道args 不为空?
  • @chepner 为清楚起见,此代码已缩写。在显示的代码中我没有,但在我的实际代码中我有更广泛的处理,以确保提供的输入是有效的。出于同样的原因,parseFlags 的定义被省略了。

标签: haskell io


【解决方案1】:

您试图将(head args) 视为在 IO monad 中。由于它只是一个原始值,因此您需要将其放入 monad 中,然后才能将其用作 IO 操作。

只需将(head args) 更改为(return (head args))

【讨论】:

    【解决方案2】:

    您可以使用 return (head args) 将类型提升到 IO monad。

    【讨论】:

      猜你喜欢
      • 2016-04-15
      • 2016-09-27
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 2016-04-26
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多