2

フィボナッチ級数の和を求めています。そして、これは私が立ち往生している場所です:

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) }

正確にどこが間違っているのですか?

4

1 に答える 1

6

あなたはおそらく結果を望んでいましprintた:

main = do putStrLn "Enter a number:"
          num <- readLn
          print $ foldr (+) 0 (take num fibs)

エラー メッセージの理由は、doブロック内のすべてのステートメントが同じモナドに属している必要があるためです。の場合はmainですIO。ただし、foldrここでの結果は数値であり、IOアクションではありません。

IOエラーメッセージは紛らわしいです。なぜなら、GHC はすべての賢明な方法で、アクションは数字でなければならないと結論付けているからです。これはもちろんナンセンスです。

紛らわしい型エラーに直面したとき、関連する式のいくつかにいくつかの型注釈を追加して、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.

于 2013-05-29T21:51:17.263 に答える