【发布时间】:2011-03-25 08:49:39
【问题描述】:
我最近一直在学习 Haskell,并且正在与一位正在通过 SICP 工作的朋友交谈。我们很想比较 Common Lisp 和 Scheme,所以我决定作为一个练习尝试将练习 1.29 翻译成 Haskell。
本练习使用一个函数 sigma,它表示数学求和函数 Sigma。该函数采用函数 f 应用于每个术语、一个下界、一个应用于每个术语以获得下一个术语的函数,以及一个上限。它返回应用于每个术语的 f 的总和。
simpsonIntegral 应该使用 Simpson 规则来使用“精度”n 来近似函数 f 在范围 [a, b] 上的积分。我无法使此功能正常工作,因为我似乎不了解所涉及的类型。
此代码将使用 ghc 版本 6.12.1 进行编译,但 simpsonIntegral 将获得一个没有任何意义的类型上下文(Integral a, Fractional a),并且该函数在您调用它时立即崩溃。我曾经做过这个工作,但我所做的显然是一种黑客行为,我想在这里问一下如何以惯用方式处理它。
如何习惯性地处理 h 中所需的 Integral -> Fractional/Real 转换?我读了很多东西,但似乎没有什么明显和干净的。
sigma :: (Ord a, Num b) => (a -> b) -> a -> (a -> a) -> a -> b
sigma f a next b = iter a 0
where
iter current acc | current > b = acc
| otherwise = iter (next current) (acc + f current)
simpsonIntegral f a b n = 1.0 * (h / 3) * (sigma simTerm 0 (1+) n)
where
h = (b - a) / n
simTerm k = (yk k) * term
where
yk k = f (a + h * k)
term =
case k of
0 -> 1
1 -> 1
otherwise -> if odd k then 4 else 2
【问题讨论】:
标签: haskell types type-conversion