52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 212

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 212

число точек.

Также импортируем для удобства символьный синоним для fmap из модуля Control.Applicative.

Ленивее некуда | 189

import Control.Applicative((<$> ))

...

Проверим функцию int. Для этого сохраним все новые функции в модуле Stream. hs. Загрузим модуль

в интерпретатор и вычислим производную какой-нибудь функции. Найдём решение для правой части кон-

станты и проверим, что у нас получилась тождественная функция:

*Stream> dist 1000 time $ int 0 $ repeat 1

7.37188088351104e-17

Функции практически совпадают, порядок ошибки составляет 10 16. Так и должно быть для линейных

функций. Посмотрим, что будет если в правой части уравнения стоит тождественная функция:

*Stream> dist 1000 ((\t -> t^2/2) <$> time) $ int 0 time

2.497500000001403e-4

Решение этого уравнения равно функции t 2 . Здесь мы видим, что результаты уже не такие хорошие.

2

Есть функции, которые определяются рекурсивно в терминах дифференциальных уравнений, например

экспонента будет решением такого уравнения:

dx = x

dt

t

x( t) = x(0) +

x( τ )

0

Опишем это уравнение в Haskell:

e = int 1 e

Наше описание копирует исходное математическое определение. Добавим это уравнение в модуль Stream

и проверим результаты:

*Stream> dist 1000 (map exp time) e

^CInterrupted.

К сожалению вычисление зависло. Нажмём ctrl+c и разберёмся почему. Для этого распишем вычисление

потока чисел e:

e

-- раскроем e

=>

int 1 e

-- раскроем int, во втором варгументе

-- int стоит декомпозиция,

=>

int 1 e@(f:fs)

-- для того чтобы узнать какое уравнение

-- для int выбрать нам нужно раскрыть

-- второй аргумент, узнать корневой

-- конструктор, раскроем второй аргумент:

=>

int 1 (int 1 e)

=>

int 1 (int 1e@(f:fs))

-- такая же ситуация

=>