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

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

этом все конструкторы заменяются на функции, которые возвращают новый тип.

Развёрткой (unfold) мы получаем из произвольного типа значение данного рекурсивного типа. Мы словно

разворачиваем его из значения, этот процесс очень похож на ленивые вычисления.

Мы узнали некоторые стандартные функции структурной рекурсии: cond или if-выражения, maybe, foldr,

unfoldr.

12.4 Упражнения

• Определите развёртку для деревьев из модуля Data.Tree.

• Определите с помощью свёртки следующие функции:

sum, prod

:: Num a => [a] -> a

or,

and

:: [Bool] -> Bool

length

:: [a] -> Int

cycle

:: [a] -> [a]

unzip

:: [(a,b)] -> ([a],[b])

unzip3

:: [(a,b,c)] -> ([a],[b],[c])

• Определите с помощью развёртки следующие функции:

infinity

:: Nat

map

:: (a -> b) -> [a] -> [b]

iterateTree :: (a -> [a]) -> a -> Tree a

zipTree

:: Tree a -> Tree b -> Tree (a, b)

• Поэкспериментируйте в интерпретаторе с только что определёнными функциями и теми функциями,

что мы определяли в этой главе.

• Рассмотрим ещё один стандартный тип. Он определён в Prelude. Это тип Either (дословно – один из

двух). Этот тип принимает два параметра:

data Either a b = Left a | Right b

Значение может быть либо значением типа a, либо значением типа b. Часто этот тип используют как

Maybe с информацией об ошибке. Конструктор Left хранит сообщение об ошибке, а конструктор Right

значение, если его удалось вычислить.

Например мы можем сделать такие определения:

headSafe :: [a] -> Either String a

headSafe []

= Left ”Empty list”

headSafe (x:_)

= Right x

divSafe :: Fractional a => a -> a -> Either String a

divSafe a 0 = Left ”division by zero”

divSafe a b = Right (a/b)

Для этого типа также определена функция свёртки она называется either. Не подглядывая в Prelude,

определите её.

Краткое содержание | 199

• Список является частным случаем дерева. Список это дерево, в каждом узле которого, лишь однин