traverseпревращает вещи внутри a Traversableв a Traversableвещей "внутри" an Applicative, учитывая функцию, которая делает Applicatives из вещей.
Давайте использовать Maybeas 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]]