Haskell 中作为整数的命令行参数
Command line arguments as Ints in Haskell
我有一个 Haskell 程序,它从命令行接受 2 或 3 Int
s:
-- 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
然而,当我 运行 它带有参数时:
$ ./test 100 200
divide: Prelude.read: no parse
为什么?
getArgs :: IO [String]
returns 一个 String
的列表,通过取头部然后 args
然后它将 read
该项目。
然而,您从未指定它应该读取什么,因为您在 case … of …
子句中使用 args
和 [x,y,a]
和 [x, y]
,它会尝试读取它作为数字的 list(数字的类型由 doGeneration
签名指定。这意味着您应该将其写为:
$ ./test <strong>[100,200]</strong>
不过我觉得这样做意义不大,你可以将解析部分重写为:
main :: IO ()
main = do
args <- fmap <strong>(map read)</strong> getArgs
case args of
[x,y,a] -> doGeneration x y a
[x,y] -> doGeneration x y 10
_ -> usage
这意味着它将read
每个参数单独,并用解析的项目构造一个列表,然后我们可以对程序参数的解析部分进行模式匹配。在那种情况下,我们仍然可以使用:
$ ./test <strong>100 200</strong>
您的 运行 代码等同于
....
case (read "100") of
[x,y,a :: Int] -> doGeneration x y a
[x,y :: Int] -> doGeneration x y 10
....
但是将字符串 "100"
读取为 Int
的列表是不可能的,a.k.a。 “没有解析”。这就是为什么。
Int
来自 doGeneration
的签名,您没有包含。但它必须是 Num
,因为您可以互换使用 a
和 10
。
学习 Haskell 时,最好在 do
块中使用更多变量而不是 fmap
。它减轻了认知负担,让您更清楚地了解正在发生的事情:
main :: IO ()
main = do
args <- getArgs -- getArgs :: IO [String]
-- args :: [String]
let arg1 = head args -- arg1 :: String
val1 = read arg1
case val1 of
[x,y,a] -> doGeneration x y a
[x,y] -> doGeneration x y 10
_ -> usage
我有一个 Haskell 程序,它从命令行接受 2 或 3 Int
s:
-- 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
然而,当我 运行 它带有参数时:
$ ./test 100 200
divide: Prelude.read: no parse
为什么?
getArgs :: IO [String]
returns 一个 String
的列表,通过取头部然后 args
然后它将 read
该项目。
然而,您从未指定它应该读取什么,因为您在 case … of …
子句中使用 args
和 [x,y,a]
和 [x, y]
,它会尝试读取它作为数字的 list(数字的类型由 doGeneration
签名指定。这意味着您应该将其写为:
$ ./test <strong>[100,200]</strong>
不过我觉得这样做意义不大,你可以将解析部分重写为:
main :: IO ()
main = do
args <- fmap <strong>(map read)</strong> getArgs
case args of
[x,y,a] -> doGeneration x y a
[x,y] -> doGeneration x y 10
_ -> usage
这意味着它将read
每个参数单独,并用解析的项目构造一个列表,然后我们可以对程序参数的解析部分进行模式匹配。在那种情况下,我们仍然可以使用:
$ ./test <strong>100 200</strong>
您的 运行 代码等同于
....
case (read "100") of
[x,y,a :: Int] -> doGeneration x y a
[x,y :: Int] -> doGeneration x y 10
....
但是将字符串 "100"
读取为 Int
的列表是不可能的,a.k.a。 “没有解析”。这就是为什么。
Int
来自 doGeneration
的签名,您没有包含。但它必须是 Num
,因为您可以互换使用 a
和 10
。
学习 Haskell 时,最好在 do
块中使用更多变量而不是 fmap
。它减轻了认知负担,让您更清楚地了解正在发生的事情:
main :: IO ()
main = do
args <- getArgs -- getArgs :: IO [String]
-- args :: [String]
let arg1 = head args -- arg1 :: String
val1 = read arg1
case val1 of
[x,y,a] -> doGeneration x y a
[x,y] -> doGeneration x y 10
_ -> usage