"I'd like to have an optional argument, which should be a path to a file..."
好的,那么沿着
Maybe FilePath
? 听起来这可能是你想要的。或同等ADT:
data Path = StandardInput | Path FilePath
当你说,
"The obvious choice here is to make this argument type IO Handle and when an argument is passed in use openFile"
从命令行解析应该是将要解析的输入转换为适合将来在程序中使用的数据。不要担心在这个阶段打开文件,或者在文件不存在的情况下处理异常,或者以任何其他方式打开文件
这些数据…只是担心这个问题,我的程序的用户是否给了我一个文件路径?也就是说,我有什么数据?其他东西不是(也不应该是)
optparse-applicative
Path
。它可能由每个构造函数的解析器组成。例如。:
stdInputParser :: Parser Path
stdInputParser = ...
pathSuppliedParser :: Parser Path
pathSuppliedParser = ...
pathParser :: Parser Path
pathParser = pathSuppliedParser <|> stdInputParser
不管怎样,一旦你跑了
execParser
,剩下的是您的
路径
数据类型。所以你将把它作为论点传递给你的
run
run :: Path -> IO ()
run StandardInput = ... use stdin here
run (Path filePath) = ... use openFile here, catch and handle exceptions if the file doesn't exist, etc.