1

我使用了本文档底部提供的代码:http ://www.cs.dartmouth.edu/~doug/pearl.ps.gz

import Data.Ratio
infixl 7 .*
default (Integer, Rational, Double)

    -- constant series
ps0, x:: Num a => [a]
ps0 = 0 : ps0
x = 0 : 1 : ps0

    -- arithmetic
(.*):: Num a => a->[a]->[a]
c .* (f:fs) = c*f : c.*fs

instance Num a => Num [a] where
    negate (f:fs) = (negate f) : (negate fs)
    (f:fs) + (g:gs) = f+g : fs+gs
    (f:fs) * (g:gs) = f*g : (f.*gs + fs*(g:gs))
    fromInteger c = fromInteger c : ps0

instance Fractional a => Fractional [a] where
    recip fs = 1/fs
    (0:fs) / (0:gs) = fs/gs
    (f:fs) / (g:gs) = let q = f/g in
        q : (fs - q.*gs)/(g:gs)

    -- functional composition
compose:: Num a => [a]->[a]->[a]
compose (f:fs) (0:gs) = f : gs*(compose fs (0:gs))

revert::Fractional a => [a]->[a]
revert (0:fs) = rs where
    rs = 0 : 1/(compose fs rs)

    -- calculus
deriv:: Num a => [a]->[a]
deriv (f:fs) = (deriv1 fs 1) where
    deriv1 (g:gs) n = n*g : (deriv1 gs (n+1))

integral:: Fractional a => [a]->[a]
integral fs = 0 : (int1 fs 1) where
    int1 (g:gs) n = g/n : (int1 gs (n+1))

expx, cosx, sinx:: Fractional a => [a]
expx = 1 + (integral expx)
sinx = integral cosx
cosx = 1 - (integral sinx)

instance Fractional a => Floating [a] where
    sqrt (0:0:fs) = 0 : sqrt fs
    sqrt (1:fs) = qs where
        qs = 1 + integral((deriv (1:fs))/(2.*qs))

    -- tests
test1 = sinx - sqrt(1-cosx^2)
test2 = sinx/cosx - revert(integral(1/(1+x^2)))
iszero n fs = (take n fs) == (take n ps0)
main = (iszero 30 test1) && (iszero 30 test2)

尝试运行它时,我收到以下错误:

    Prelude> :load pearl.hs
[1 of 1] Compiling Main             ( pearl.hs, interpreted )

pearl.hs:22:10:
    Could not deduce (Eq a) arising from the literal ‘0’
    from the context (Num [a], Fractional a)
      bound by the instance declaration at pearl.hs:20:10-39
    Possible fix: add (Eq a) to the context of the instance declaration
    In the pattern: 0
    In the pattern: 0 : fs
    In an equation for ‘/’: (0 : fs) / (0 : gs) = fs / gs

pearl.hs:28:17:

    Could not deduce (Eq a) arising from the literal ‘0’
    from the context (Num a)
      bound by the type signature for
                 compose :: Num a => [a] -> [a] -> [a]
      at pearl.hs:27:11-32
    Possible fix:
      add (Eq a) to the context of
        the type signature for compose :: Num a => [a] -> [a] -> [a]
    In the pattern: 0
    In the pattern: 0 : gs
    In an equation for ‘compose’:
        compose (f : fs) (0 : gs) = f : gs * (compose fs (0 : gs))

pearl.hs:31:9:
    Could not deduce (Eq a) arising from the literal ‘0’
    from the context (Fractional a)
      bound by the type signature for
                 revert :: Fractional a => [a] -> [a]
      at pearl.hs:30:9-32
    Possible fix:
      add (Eq a) to the context of
        the type signature for revert :: Fractional a => [a] -> [a]
    In the pattern: 0
    In the pattern: 0 : fs
    In an equation for ‘revert’:
        revert (0 : fs)
          = rs
          where
              rs = 0 : 1 / (compose fs rs)

pearl.hs:49:15:
    Could not deduce (Eq a) arising from the literal ‘0’
    from the context (Fractional [a], Fractional a)
      bound by the instance declaration at pearl.hs:48:10-37
    Possible fix: add (Eq a) to the context of the instance declaration
    In the pattern: 0
    In the pattern: 0 : 0 : fs
    In an equation for ‘sqrt’: sqrt (0 : 0 : fs) = 0 : sqrt fs

pearl.hs:57:1:
    Couldn't match expected type ‘IO t0’ with actual type ‘Bool’
    In the expression: main
    When checking the type of the IO action ‘main’
Failed, modules loaded: none.

我已将“import Ratio”更改为“import Data.Ratio”,但后来卡住了。

4

1 回答 1

7

GHC 的“可能修复”消息通常非常具有误导性,但这一消息是正确的。你为什么不试试?

可能的修复:添加(Eq a)到实例声明的上下文中

IE

instance (Fractional a, Eq a) => Fractional [a] where
  ...

这是必要的,因为某些Num实例可能不允许相等比较(实际上这个实例是一个很好的例子,因为无限列表永远不能在有限时间内被证明相等!)但是当编写一个模式时(0:fs) / (0:gs) -> ...,你需要一个相等检查来确认头部实际上是零。列表当然有一个Eq实例,但实际上那些不是您正在处理的一般列表,而是始终无限的列表(否则这些模式是不穷尽的),因此您应该使用没有 Eq实例的 newtype 包装器,例如

newtype Series a = Series {getSeries :: [a]}

在过去,Eq它曾经是 的超类Num,因此[a]可以毫无怨言地编译。但正如我所说,这并不是很好。

于 2014-10-19T22:46:18.993 回答