asm*_*asm 5 haskell types type-conversion
我最近一直在学习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中所需的积分 - >分数/实数转换?我读了很多东西,但似乎没有什么是明显和干净的.
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
Run Code Online (Sandbox Code Playgroud)
fromIntegral :: (Integral a, Num b) => a -> b
r = fromIntegral i
Run Code Online (Sandbox Code Playgroud)
为了跟进 Justice 的回答:如果您好奇将fromIntegrals 放在哪里,可以编译以下内容:
simpsonIntegral :: (Integral a, Fractional b) => (b -> b) -> a -> a -> a -> b
simpsonIntegral f a b n = 1.0 * (h / 3) * (sigma simTerm 0 (1+) n)
where
h = fromIntegral (b - a) / fromIntegral n
simTerm k = (yk k) * term
where
yk k = f (fromIntegral a + h * fromIntegral k)
term =
case k of
0 -> 1
1 -> 1
otherwise -> if odd k then 4 else 2
Run Code Online (Sandbox Code Playgroud)
并且似乎有效:
*Main> simpsonIntegral (^3) 0 1 100
0.2533333233333334
*Main> simpsonIntegral (^3) 0 1 1000
0.2503333333323334
Run Code Online (Sandbox Code Playgroud)