我有一個Haskell程式,它從命令列接受2或3個Int:
-- 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 _ -> 使用方法
_ -> 使用方法
然而,當我帶著引數運行它時:
$ ./test 100 200
divide。Prelude.read: no parse
為什么?
uj5u.com熱心網友回復:
getArgs :: IO [String]回傳一個Strings的串列,通過獲取head和args,然后它將讀取該專案。
然而你從來沒有指定它應該讀什么,因為你在case ... of ...子句中使用了[x,y,a]和[x,y],它將嘗試把它讀成一個數字的list(數字的型別是由doGeneration簽名指定。因此,這意味著你應該把它寫成:
但是我認為這樣做意義不大,你可以把決議部分改寫成: 這意味著它將 uj5u.com熱心網友回復: 你的運行代碼相當于$ ./test [100,200]/code>
main :: IO ()
main = do
args <- fmap (map read) getArgs
case args of
[x,y,a] -> doGeneration x y a
[x,y] -> doGeneration x y 10 _
_ -> 用途單獨讀取每個引數,并將決議后的專案構建一個串列,然后我們可以在程式引數的決議部分進行模式匹配。因此,在這種情況下,我們仍然可以使用:$ ./test 100 200
....
case (read "100"/span>) of
[x,y,a :: Int] -> doGeneration x y a
[x,y :: Int] -> doGeneration x y10
....
但是把一個字串"100"讀成一個Ints的串列是不可能的,也就是 "沒有決議"。這就是原因。
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 _
_ -> 使用方法
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316899.html
標籤:
上一篇:Haskell函式格式
下一篇:如何驗證一個創建多個記錄的表單
