Solution (source code)

= Solution

Map each current first-position value with the first function, then swap the functions when descending to the other <algebraic data type>:
``
mapZig :: (a -> c) -> (b -> d) -> Zig a b -> Zig c d
mapZig _ _ Nil = Nil
mapZig f g (Cins x zs) = Cins (f x) (mapZag g f zs)

mapZag :: (a -> c) -> (b -> d) -> Zag a b -> Zag c d
mapZag _ _ Nal = Nal
mapZag f g (Cans x zs) = Cans (f x) (mapZig g f zs)
``
All four <type variables> are independent: mapping may change both element types. There is no `Enum` or numeric constraint on the mapping functions themselves; constraints arise only from particular arguments such as `succ` or `(+2)`. The <mutual recursion> preserves every constructor and applies the intended function at each alternating position. The results are \b[`Cins 3 (Cans 'B' (Cins 4 Nal))`] and \b[`Cans "D" (Cins True (Cans "E" Nil))`], respectively.