2011-04-28 42 views
0

這段代碼有什麼問題?以下程序有什麼問題?

module Main where 
import System.Environment 
main :: IO() 
main = do 
    args <- getArgs 
    putStrLn ("Hello, " ++ args !! 0 ++ ", " ++ args !! 1) 
    putStrLn(add (read args !! 0) (read args !! 1)) 
add x y = x + y 

下面是錯誤信息:

main.hs:8:15: 
    No instance for (Num String) 
     arising from a use of `add' 
    Possible fix: add an instance declaration for (Num String) 
    In the first argument of `putStrLn', namely 
     `(add (read args !! 0) (read args !! 1))' 
    In the expression: putStrLn (add (read args !! 0) (read args !! 1)) 
    In the expression: 
     do { args <- getArgs; 
      putStrLn ("Hello, " ++ args !! 0 ++ ", " ++ args !! 1); 
      putStrLn (add (read args !! 0) (read args !! 1)) } 

main.hs:8:25: 
    Couldn't match expected type `Char' with actual type `[Char]' 
    Expected type: String 
     Actual type: [String] 
    In the first argument of `read', namely `args' 
    In the first argument of `(!!)', namely `read args' 
+0

那麼,它是什麼*錯?錯誤? – deceze 2011-04-28 10:21:07

回答

8

read args !! 0應該read (args !! 0)add x y = x +應該add x y = x + y。另外putStrLn只接受一個字符串,所以請使用print而不是打印數字。


但是,看到你是哈斯克爾的新手。我重寫了一部分程序,以展示更加怪誕的方式。

main = do 
    (arg0:arg1:restArgs) <- getArgs 
    putStrLn $ "Hello, " ++ arg0 ++ ", " ++ arg1 
    print $ add (read arg0) (read arg1) 
add = (+) 

我認爲它現在看起來更清潔一些。請注意,使用!!通常被認爲是不好的做法。

+1

您需要從'add'的無點點版本中刪除'x y'。好的答案,否則,+1。 – interjay 2011-04-28 11:21:33

+0

這是正確的。編輯它,抱歉沒有麻煩編譯代碼。 :) – Tarrasch 2011-04-28 11:41:45

+0

我認爲真正的原因'!!'被認爲是不好的做法是因爲它有不受歡迎的錯誤處理。我也可以指出,雖然在列表中使用模式匹配比使用'!!'更簡潔,但它具有相同的危險錯誤行爲。 – mightybyte 2011-04-28 14:16:19

3

只是在錯誤消息和給出的解決方案上添加一點細節。看第一個錯誤:

 
    No instance for (Num String) 
    ... 
    In the first argument of `putStrLn' 

這可能有點不清楚。看看類型簽名putStrLn:

 
putStrLn :: String -> IO() 

所以,putStrLn是一個函數,將一個字符串的計算結果爲一個IO動作。然而,你直接試圖通過putStrLn一些表達式,如(x + y),這是一個數字,並且字符串不是數字(在Haskell術語中,它的類型簽名是(Num t)=> t)。

上面給出使用打印功能建議代替溶液:

 
print :: (Show a) => a -> IO() 

「打印」和「putStrLn」之間的區別在於打印可以採取任何showable,其包括數字。

下一步:

 
    Couldn't match expected type `Char' with actual type `[Char]' 
    Expected type: String 
     Actual type: [String] 
    In the first argument of `read', namely `args' 

這是說編譯器預計String作爲讀取第一個參數,但看到字符串的列表。綜觀原代碼:

 
read args !! 0 

在Haskell,功能應用的優先級最高,所以編譯器基本上是讀你的代碼如下所示:

 
(read args) !! 0 

(尤其紙條,上面寫着的應用程序綁定更高比使用!!運算符)。希望現在應該清楚讀取已應用於所有參數

至於你的意圖似乎是閱讀args來第一個元素,你需要使用括號像這樣:

希望這是錯誤信息多一點理解!