As daunting as specializing reduce to G might seem,
it is quite straightforward following the models in the previous two
sections. The most difficult portion is getting the type of
reduce<G> correct, which we again assert without
justificiation:
reduce<G> ::
(
)
(
. (
. (
)
)
(
. (
)
G
))
The isomorphic datatype is even simpler than the previous ones:
data G
=
:*: (
(G
))
fromG :: G G
fromG (Branch x xg) = x :*: xg
toG :: G
G
toG (x :*: xg) = Branch x xg
The specialization proceeds just as before, with two ``new'' arguments:
reduce<G>
rf ra = (reduce<G
>
rf ra>) o fromG
reduce<G>
rf ra = red<G
>
where
red<G
red< :*: (
(G
))>
red<:*:> red<> red<
(G
)>
red<:*:> red<> (red<
> red<G
>)
red<:*:> red<> (red<
> (red<G> red<
> red<
>))
red<:*:> ra (rf (red<G> rf ra))
red<:*:> ra (rf ((reduce<G>
) rf ra))