Недавно я изучал Haskell и разговаривал с другом, который работает через SICP. Нам было любопытно сравнить Common Lisp и Scheme, поэтому я решил как упражнение попытаться перевести упражнение 1.29 в Haskell.Иерархия числового типа Haskell в упражнениях SICP
В этом упражнении используется сигма функции, представляющая математическую функцию суммирования Sigma. Эта функция принимает функцию f для применения к каждому члену, нижней границе, функцию, применяемую к каждому члену для получения следующего слагаемого, и верхнюю границу. Он возвращает сумму f, применяемую к каждому члену.
simpsonIntegral должен использовать правило Симпсона для приближения интеграла функции f по диапазону [a, b] с использованием «точности» n. У меня возникли проблемы с работой этой функции, потому что, похоже, я не понимаю о связанных типах.
Этот код будет скомпилирован с версией 6.12.1 из ghc, но 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
Вопрос о fromIntegral. Я пытался это, но не в правильном месте на ответ Трэвиса, и я думал, что он не работает, потому что согласно этому http://www.haskell.org/tutorial/numbers.html num не предоставляет оператор разделения. Является ли fromIntegral полиморфным по типу возвращаемого значения и ghc указывает, что мне нужен тип возврата Fractional? – asm
Да, 'fromIntegral' является полиморфным в своем обратном типе' b', в этом 'b' (возвращаемый тип) разрешен любой тип данных, который является членом класса типа« Num ». В то время как класс типа «Num» не предоставляет разделение, некоторые типы данных, которые являются членами этого типа, предоставляют деление, например «Двойной». – yfeldblum