在下面的代码中,我试图显示factorial的结果,它是一个整数。我收到以下错误消息,我想知道发生了什么以及为什么。谢谢!
factorial2 0 = 1
factorial2 n = n * factorial2 (n-1)
main = do putStrLn "What is 5! ?"
x <- readLn
if x == factorial2 5
then putStrLn "Right"
-- else print factorial2 5 -- why can't pass here
-- else show factorial2 5 -- why can't pass here
else putStrLn "Wrong" -- this can pass, no problem
-- Factorial.hs:10:20:
-- Couldn't match expected type ‘Integer -> IO ()’
-- with actual type ‘IO ()’
-- The function ‘print’ is applied to two arguments,
-- but its type ‘(a0 -> a0) -> IO ()’ has only one
-- In the expression: print factorial2 5
-- In a stmt of a 'do' block:
-- if x == factorial2 5 then putStrLn "Right" else print factorial2 5
-- Failed, modules loaded: none.
答案 0 :(得分:3)
Haskell函数应用程序是左关联的。这意味着当你调用print factorial2 5
时,haskell会在将2个参数传递给print factorial2
和5
时解释它,但print只接受一个参数。如果您的代码是另一种语言,则相当于:print(factorial2, 5)
。
show factorial2 5
无效的原因是因为do块中的所有内容都需要返回IO(),但show factorial2 5
会返回一个字符串。
只需print (factorial2 5)
即可,以便haskell知道您希望将factorial2 5
的结果传递给print
。
答案 1 :(得分:0)
show 函数的类型为:a -> String
。
所以它需要一个参数并将其转换为字符串。
在你的行
else show factorial2 5 -- why can't pass here
你提供两个参数,即 factorial2 和 5 。
您必须为函数 show 提供一个参数,在您的情况下为factorial2 5
的结果因此您必须将 factorial2 5 放入括号中:< / p>
else show (factorial2 5)
通常你会看到 $ 运算符:
else show $ factorial2 5
它允许您保存括号。