#recursion-schemes #catamorphism
#рекурсия-схемы #катаморфизм
Вопрос:
Какой из них является подходящим морфизмом (схема рекурсии) для использования, когда требуется позиция данного элемента (индекс или путь) в функции преобразования?
Простым примером может быть преобразование списка ["foo", "bar", "qux"]
в строку "foo, bar, and qux"
. Позиция текущего элемента необходима, чтобы знать, когда вставлять and
.
Ответ №1:
Вам нужно сделать индекс частью структуры, чтобы он был доступен для схемы рекурсии. Специальный способ сделать это — определить foldWithIndex
функцию:
foldWithIndex :: (Foldable t, Num i) => (i -> a -> b -> b) -> b -> t a -> b
foldWithIndex f z t = snd $ foldr f' (0, z) t
where
f' z (i, x) = (i 1, f i z x)
Эта функция принимает оператор для объединения элементов, который также учитывает индекс:
foldWithIndex combine "" ["foo", "bar", "qux"]
where
combine 0 s1 s2 = s1 s2
combine 1 s1 s2 = s1 " and " s2
combine _ s1 s2 = s1 ", " s2
приводит к "foo, bar and qux"
.
Для более общего подхода см. Data.Foldable.WithIndex
, Который предоставляет складной класс типов, который также учитывает индекс.