Я пытаюсь написать короткую функцию, которая вычисляет площадь под кривой, но я продолжал получать ошибку несоответствия типа.Ошибка вычисления поплавка Haskell
Параметры в следующей функции: 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]
Я также изменить ^
к ^^
иметь дело с отрицательным показателем.