Morphism where the algebra receives the item's position

49 views Asked by At

Which one is the appropriate morphism (recursion scheme) to use when the given item's position (index, or path) is required in the transformer function?

A simple example would be transforming a list ["foo", "bar", "qux"] into the string "foo, bar, and qux". The current element's position is needed to know when to insert the and.

1

There are 1 answers

0
michid On

You need to make the index part of the structure so it is available to the recursion scheme. An ad-hoc way to do this is to define a foldWithIndex function:

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)

This function takes an operator for combining the elements which also considers the index:

foldWithIndex combine "" ["foo", "bar", "qux"]
    where
        combine 0 s1 s2 = s1 ++ s2
        combine 1 s1 s2 = s1 ++ " and " ++ s2
        combine _ s1 s2 = s1 ++ ", " ++ s2

results in "foo, bar and qux".

For a more general approach see Data.Foldable.WithIndex, which provides a foldable typeclass that also takes an index into account.