3

我正在尝试学习 Haskell,但我被数字转换卡住了,有人可以解释一下为什么 Haskell 编译器会在这段代码上发疯:

phimagic :: Int -> [Int]
phimagic x = x : (phimagic (round (x * 4.236068)))

它打印错误消息:

problem2.hs:25:33:
    No instance for (RealFrac Int) arising from a use of `round'
    Possible fix: add an instance declaration for (RealFrac Int)
    In the first argument of `phimagic', namely
      `(round (x * 4.236068))'
    In the second argument of `(:)', namely
      `(phimagic (round (x * 4.236068)))'
    In the expression: x : (phimagic (round (x * 4.236068)))


problem2.hs:25:44:
    No instance for (Fractional Int)
      arising from the literal `4.236068'
    Possible fix: add an instance declaration for (Fractional Int)
    In the second argument of `(*)', namely `4.236068'
    In the first argument of `round', namely `(x * 4.236068)'
    In the first argument of `phimagic', namely
      `(round (x * 4.236068))'

我已经在方法签名上尝试了多种组合(添加 Integral、Fractional、Double 等)。有些东西告诉我,文字 4.236068 与问题有关,但无法弄清楚。

4

1 回答 1

12

Haskell will not automatically cast things for you, so x * y only works if x and y have the same type (you can't multiply Int by Double, for example).

phimagic :: Int -> [Int]
phimagic x = x : phimagic (round (fromIntegral x * 4.236068))

Note we can use the Prelude function iterate to more naturally express phimagic:

phimagic = iterate $ round . (4.236068 *) . fromIntegral
于 2013-10-10T05:39:02.693 回答