Морфизм, при котором алгебра получает позицию элемента

#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 , Который предоставляет складной класс типов, который также учитывает индекс.