我找到了斐波纳契数列的总和。这就是我坚持的地方:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
main = do putStrLn "Enter a number:"
num <- readLn
foldr (+) 0 (take num fibs)
错误是:
No instance for (Num (IO t0))
arising from the literal `0'
Possible fix: add an instance declaration for (Num (IO t0))
In the second argument of `foldr', namely `0'
In the expression: foldr (+) 0 (take num fibs)
In the expression:
do { putStrLn "Enter a number:";
num <- readLn;
foldr (+) 0 (take num fibs) }
我到底哪里错了?
答案 0 :(得分:6)
你可能想要print
结果:
main = do putStrLn "Enter a number:"
num <- readLn
print $ foldr (+) 0 (take num fibs)
错误消息的原因是do
块中的每个语句都必须属于同一个monad。如果是main
,那就是IO
。但是,此处foldr
的结果是数字,而不是IO
操作。
错误信息令人困惑,因为GHC的所有智慧都认为IO
行为必须是数字,这当然是无稽之谈。
当您遇到令人困惑的类型错误时,将一些类型注释添加到所涉及的某些表达式中通常很有用,向GHC解释您期望的类型。这通常会给你更好的GHC错误信息。
例如,如果您在使用:: Integer
的行末添加foldr
,则会收到此消息:
Couldn't match expected type `IO b0' with actual type `Integer'
In a stmt of a 'do' block: foldr (+) 0 (take num fibs) :: Integer
In the expression:
do { putStrLn "Enter a number:";
num <- readLn;
foldr (+) 0 (take num fibs) :: Integer }
In an equation for `main':
main
= do { putStrLn "Enter a number:";
num <- readLn;
foldr (+) 0 (take num fibs) :: Integer }
这里更容易看到问题。 GHC期待类型IO b0
的声明,
你给了它Integer
。