Haskell 中的命令行参数为 Int

eme*_*sik 2 io monads haskell

我有一个 Haskell 程序,它Int从命令行接受 2 或 3 秒:

-- test.hs

main :: IO ()
main = do
    args <- fmap (read . head) getArgs
    case args of
        [x,y,a] -> doGeneration x y a
        [x,y]   -> doGeneration x y 10
        _       -> usage
Run Code Online (Sandbox Code Playgroud)

但是,当我使用参数运行它时:

$ ./test 100 200
divide: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)

为什么?

Wil*_*sem 5

getArgs :: IO [String]返回一个 s 列表String,通过获取 head 然后args然后它会read该项目。

\n

然而,您从未指定它应该读取的内容,因为您argscase \xe2\x80\xa6 of \xe2\x80\xa6子句中使用[x,y,a]and [x, y],它会尝试将其读取为数字列表(数字的类型由doGeneration。这意味着您应该编写它作为:

\n
$ ./test [100,200]
Run Code Online (Sandbox Code Playgroud)\n

但我认为这样做没有多大意义,你可以将解析部分重写为:

\n
main :: IO ()\nmain = do\n    args <- fmap (map read) getArgs\n    case args of\n        [x,y,a] -> doGeneration x y a\n        [x,y]   -> doGeneration x y 10\n        _       -> usage
Run Code Online (Sandbox Code Playgroud)\n

这意味着它将read单独处理每个参数,并使用已解析的项目构造一个列表,然后我们可以对程序参数的已解析部分进行模式匹配。在这种情况下我们仍然可以使用:

\n
$ ./test 100 200
Run Code Online (Sandbox Code Playgroud)\n

  • 在“IO”中,最好养成使用“readIO”而不是“read”的习惯,如“args &lt;- mapM readIO =&lt;&lt; getArgs”。如果有人给出非整数参数,您会立即发现,而不是在第一次强制使用错误参数时可能已经完成大量计算之后的某个时间。 (2认同)