52700.fb2
-- возвращает True только в том случае, если
-- первый список полностью содержится во втором
isInfixOf :: Eq a => [a] -> [a] -> Bool
• Классы Functor и Applicative замкнуты относительно композиции. Это свойство говорит о том, что
композиция (аппликативных) функторов снова является (аппликативным) функтором. Докажите это!
Пусть дан тип, который описывает композицию двух типов:
newtype O f g a = O { unO :: f (g a) }
Определите экземпляры классов:
instance (Functor f, Functor g) => Functor (O f g) where ...
instance (Applicative f, Applicative g) => Applicative (O f g) where ...
Подсказка: если совсем не получается, ответ можно подсмотреть в библиотеке TypeCompose. Но пока мы
не знаем как устанавливать библиотеки и где они живут, всё-таки попытайтесь решить это упражнение
самостоятельно.
Упражнения | 141
Глава 9
Редукция выражений
В этой главе мы поговорим о том как вычисляются программы. В самом начале мы говорили о том, что
процесса вычисления значений нет. В том смысле, что у нас нет новых значений, у нас ничего не меняется,
мы лишь расшифровываем синонимы значений.
Вкратце вспомним то, что мы уже знаем о вычислениях. Сначала мы с помощью типов определяем мно-
жество всех возможных значений. Значения – это деревья в узлах которых записаны конструкторы, которые
мы определяем в типах. Так например мы можем определить тип:
data Nat = Zero | Succ Nat
Этим типом мы определяем множество допустимых значений. В данном случае это цепочки конструкто-
ров Succ, которые заканчиваются конструктором Zero:
Zero, Succ Zero, Succ (Succ Zero), ...
Затем начинаем давать им новые имена, создавая константы (простые имена-синонимы)
zero
= Zero
one
= Succ zero
two
= Succ one
и функции (составные имена-синонимы):
foldNat :: a -> (a -> a) -> Nat -> a
foldNat z
s
Zero
= z
foldNat z
s
(Succ n)
= s (foldNat z s n)
add a = foldNat a
Succ
mul a = foldNat one (add a)
Затем мы передаём нашу программу на проверку компилятору. Мы просим у него проверить не создаём
ли мы случайно какие-нибудь бессмысленные выражения. Бессмысленные потому, что они пытаются создать
значение, которое не вписывается в наши типы. Например если мы где-нибудь попробуем составить выра-