traverse
превращает вещи внутри a Traversable
в a Traversable
вещей "внутри" an Applicative
, учитывая функцию, которая делает Applicative
s из вещей.
Давайте использовать Maybe
as Applicative
и перечислить как Traversable
. Для начала нам понадобится функция преобразования:
half x = if even x then Just (x `div` 2) else Nothing
Итак, если число четное, мы получаем его половину (внутри a Just
), иначе мы получаем Nothing
. Если все идет "хорошо", это выглядит так:
traverse half [2,4..10]
--Just [1,2,3,4,5]
Но...
traverse half [1..10]
-- Nothing
Причина в том, что <*>
функция используется для построения результата, и когда один из аргументов есть Nothing
, мы Nothing
возвращаемся.
Другой пример:
rep x = replicate x x
Эта функция генерирует список длины x
с содержимым x
, например rep 3
= [3,3,3]
. Что в результате traverse rep [1..3]
?
Мы получаем частичные результаты [1]
, [2,2]
и [3,3,3]
использования rep
. Теперь семантика списков , как Applicatives
это «принимать все комбинации», например , (+) <$> [10,20] <*> [3,4]
есть [13,14,23,24]
.
«Все комбинации» [1]
и [2,2]
составляют два раза [1,2]
. Все комбинации два раза [1,2]
и [3,3,3]
шесть раз [1,2,3]
. Итак, у нас есть:
traverse rep [1..3]
--[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]