You are already using recursion. Indeed, you use roseMap f
in terms of itself:
roseMap :: (a -> b) -> RoseTree a -> RoseTree b
roseMap f rtree = case rtree of
RoseNode a [] -> allCaps a
RoseNode a sub -> Rose (allCaps a) (map (roseMap f sub))
But the above will not work for several reasons:
- you do not make use of
f
here. Indeed you write Rose (allCaps a)
, so you do not use f
to map the elements;
- the
sub
should not be passed in the brackets of roseMap f
;
- you should use
RoseNode
instead of Rose
; and
- your first case, you return
allCaps a
, instead of RoseNode (allCaps a) []
.
Making a distinction between a node with no children, or with children, is not necessary anway. We can define the mapping as:
roseMap :: (a -> b) -> RoseTree a -> RoseTree b
roseMap f (RoseNode a xs) = RoseNode (f a) (map (roseMap f) xs)
So here we use f a
instead, and we perform a mapping on the children.
If we then perform a roseMap
with allCaps
as function, we get:
Prelude Data.Char> roseMap allCaps things
RoseNode "THING" [RoseNode "ANIMAL" [RoseNode "CAT" [],RoseNode "DOG" []],RoseNode "METAL" [RoseNode "ALLOY" [RoseNode "STEEL" [],RoseNode "BRONZE" []],RoseNode "ELEMENT" [RoseNode "GOLD" [],RoseNode "TIN" [],RoseNode "IRON" []]],RoseNode "FRUIT" [RoseNode "APPLE" [RoseNode "GRANNY SMITH" [],RoseNode "PINK LADY" []],RoseNode "BANANA" [],RoseNode "ORANGE" []],RoseNode "ASTRONOMICAL OBJECT" [RoseNode "PLANET" [RoseNode "EARTH" [],RoseNode "MARS" []],RoseNode "STAR" [RoseNode "THE SUN" [],RoseNode "SIRIUS" []],RoseNode "GALAXY" [RoseNode "MILKY WAY" []]]]
We do not need to implement the mapping ourself, we can enable the DeriveFunctor
extension [ghc-doc], and let Haskell do the work for us:
{-# LANGUAGE DeriveFunctor #-}
data RoseTree a = RoseNode a [RoseTree a] deriving (Functor, Show)
the we can call this with fmap :: Functor f => (a -> b) -> f a -> f b
:
Prelude Data.Char> fmap (map toUpper) things
RoseNode "THING" [RoseNode "ANIMAL" [RoseNode "CAT" [],RoseNode "DOG" []],RoseNode "METAL" [RoseNode "ALLOY" [RoseNode "STEEL" [],RoseNode "BRONZE" []],RoseNode "ELEMENT" [RoseNode "GOLD" [],RoseNode "TIN" [],RoseNode "IRON" []]],RoseNode "FRUIT" [RoseNode "APPLE" [RoseNode "GRANNY SMITH" [],RoseNode "PINK LADY" []],RoseNode "BANANA" [],RoseNode "ORANGE" []],RoseNode "ASTRONOMICAL OBJECT" [RoseNode "PLANET" [RoseNode "EARTH" [],RoseNode "MARS" []],RoseNode "STAR" [RoseNode "THE SUN" [],RoseNode "SIRIUS" []],RoseNode "GALAXY" [RoseNode "MILKY WAY" []]]]