8.7

8 Like folds, but again.

../code/Review.hs

-- | This is one possible way of representing a Tree as an algebraic datatype
-- In this representation all of the data is held in the branching nodes
-- and the leaves have no informational content
data Tree a = Empty | Node a (Tree a) (Tree a)
  deriving (Show, Eq)


-- | If we wanted to apply a function to all of the data stored in a tree, but
-- keep the structure of the tree preserved, we `map` over the tree.
mapTree :: (a -> b) -> Tree a -> Tree b
mapTree f Empty = Empty
mapTree f (Node d l r) = Node (f d) (mapTree f l) (mapTree f r)

-- | If we wanted to _reduce_ a tree to some value, we _fold_ over the tree
foldTree :: (a -> b -> b -> b) -> b -> Tree a -> b
foldTree f b Empty        = b
foldTree f b (Node d l r) = f d (foldTree f b l) (foldTree f b r)


-- | Here is a completely nonsensical data type that we made up
-- together in class. 
data Chew e = Han e e e
            | Bowcaster
            | BestFriend (Chew e)
            deriving (Show)

-- | In the lecture we came up with the appropriate type for
-- folding over a `Chew e`.
-- Your task is to try and implement this fold
foldChew :: (z -> z -> z -> res) -- thing to do when Han
         -> res                  -- thing to do when Bowcaster
         -> (res -> res)         -- thing to do when BestFriend
         -> Chew z -> res
foldChew h bow bst Bowcaster      = bow
foldChew h bow bst (Han z1 z2 z3) = h z1 z2 z3
foldChew h bow bst (BestFriend c) = bst (foldChew h bow bst c)


chewString :: Show a => Chew a -> String
chewString c = foldChew f "Bowcaster" g c
  where
-- f :: a -> a -> a -> String
   f a b c = "Han " ++ show a ++ show b ++ show c   

-- g :: String -> String
   g s = "BestFriend " ++ s