Конечно же, это ненаучный и неточный способ проверять скорость ваших программ. Однако мы могли видеть, что в этом случае использование разностных списков начинает выдавать результаты незамедлительно, тогда как использование обычных занимает нескончаемо долгое время.
Ну, теперь в вашей голове наверняка засела песня «Final Countdown» группы Europe. Балдейте!
Монада Reader? Тьфу, опять эти шуточки!
В главе 11 вы видели, что тип функции >(–>) r
является экземпляром класса >Functor
. Отображение функции >g
с помощью функции >f
создаёт функцию, которая принимает то же, что и >g
, применяет к этому >g
, а затем применяет к результату >f
. В общем, мы создаём новую функцию, которая похожа на >g
, только перед возвращением своего результата также применяет к этому результату >f
. Вот пример:
>ghci> let f = (*5)
>ghci> let g = (+3)
>ghci> (fmap f g) 8
>55
Вы также видели, что функции являются аппликативными функторами. Они позволяют нам оперировать окончательными результатами функций так, как если бы у нас уже были их результаты. И снова пример:
>ghci> let f = (+) <$> (*2) <*> (+10)
>ghci> f 3
>19
Выражение >(+) <$> (*2) <*> (+10)
создаёт функцию, которая принимает число, передаёт это число функциям >(*2)
и >(+10)
, а затем складывает результаты. К примеру, если мы применим эту функцию к >3
, она применит к >3
и >(*2)
, и >(+10)
, возвращая >6
и >13
. Затем она вызовет операцию >(+)
со значениями >6
и >13
, и результатом станет >19
.
Тип функции >(–>) r
является не только функтором и аппликативным функтором, но также и монадой. Как и другие монадические значения, которые вы встречали до сих пор, функцию можно рассматривать как значение с контекстом. Контекстом для функции является то, что это значение ещё не представлено и нам необходимо применить эту функцию к чему-либо, чтобы получить её результат.
Поскольку вы уже знакомы с тем, как функции работают в качестве функторов и аппликативных функторов, давайте прямо сейчас взглянем, как выглядит их экземпляр для класса >Monad
. Он расположен в модуле >Control.Monad.Instances
и похож на нечто подобное:
>instance Monad ((–>) r) where
> return x = \_ –> x
> h >>= f = \w –> f (h w) w
Вы видели, как функция >pure
реализована для функций, а функция >return
– в значительной степени то же самое, что и >pure
. Она принимает значение и помещает его в минимальный контекст, который всегда содержит это значение в качестве своего результата. И единственный способ создать функцию, которая всегда возвращает определённое значение в качестве своего результата, – это заставить её совсем игнорировать свой параметр.