这段代码出了什么问题?
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 :(得分: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 :(得分:3)
只是为错误消息和给出的解决方案添加一些细节。看第一个错误:
No instance for (Num String) ... In the first argument of `putStrLn'
这可能有点不清楚。看看putStrLn的类型签名:
putStrLn :: String -> IO ()
因此,putStrLn是一个接受String并计算IO动作的函数。但是你直接试图传递putStrLn一些表达式,如(x + y),这是一个数字,而字符串不是数字(在Haskell术语中,它的类型签名是(Num t)=&gt;吨)。
上面给出的解决方案建议使用打印功能:
print :: (Show a) => a -> IO ()
'print'和'putStrLn'之间的区别在于打印可以显示任何可显示的内容,其中包括数字。
接下来:
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 。
由于您的意图似乎是阅读args的第一个元素,您需要使用如下括号:
read (args !! 0)
希望这会使错误消息更容易理解!