【发布时间】:2016-12-20 15:28:04
【问题描述】:
我正在尝试编写一个计算曲线下面积的简短函数,但我不断收到类型不匹配错误。
以下函数中的参数:l、r为求值范围,a、b为曲线参数。
solve :: Int -> Int -> [Int] -> [Int] -> [Double]
solve l r a b = [area]
where eval a b p = fromIntegral . sum . map (\(ai, bi) -> ai * p ^ bi) $ zip a b
area = foldl (\acc p -> acc + 0.001 * eval a b p) 0 range
range = map (\a -> (fromIntegral a :: Double ) / 1000) [l*1000..r*1000]
我感到非常沮丧,因为 Haskell 中的类型系统真的不是那么直观。有人可以建议在数值计算中处理浮点数时的最佳做法吗?
综上所述,上面的代码不起作用,因为:
- 在类型声明中
a被声明为[Int] - 因此Haskell推断
eval也有Int类型,因为(*)有签名Num a => a -> a -> a(所以它只接受相同类型的参数)
如果我们想在不改变输入类型的情况下将这个问题中的代数曲线计算为浮点值,我们可以将a 转换为[Double]。代码如下:
solve :: Int -> Int -> [Int] -> [Int] -> [Double]
solve l r a b = [area]
where eval p = sum . map (\(ai, bi) -> ai * p ^^ bi) $ zip af b
area = foldl (\acc p -> acc + 0.001 * eval p) 0 range
range = map (\x -> (fromIntegral x :: Double ) / 1000) [l*1000..r*1000]
af = map fromIntegral a :: [Double]
我还将^ 更改为^^ 以处理负指数。
【问题讨论】:
标签: haskell floating-point numeric