Your tree function worked with trees that contained a
to make values of type b
, but your Exp
data type doesn't contain anything except expressions to combine (or count). Let's make a second data type that we can count occurences of. It'd better be Ord
, so we need Eq
, and Show
'll be good for output:
data Term = NumberTerm | AddTerm | SubtractTerm | MultiplyTerm | DivideTerm
deriving (Eq, Ord, Show)
Each of those represents a term of the Exp
type.
I've renamed your insert'
to inc
:
inc :: Ord a => a -> Map a Int -> Map a Int
inc a = insertWith (+) a 1
No we're ready to count:
countExp :: Exp -> Map Term Int
A Number
has just one term (no subterms), so we'll start with empty
and increment the number of NumberTerm
s:
countExp (Number _) = inc NumberTerm empty
Add
terms are more complicated. Each expression has its own count, so we use countExp
recursively on each subterm, then we unionWith (+)
to sum the counts. After that, we inc AddTerm
to include the current Add
term in the totals.
countExp (Add e1 e2) = inc AddTerm $ unionWith (+) (countExp e1) (countExp e2)
We can do almost exactly the same for Subtract
:
countExp (Subtract e1 e2) = inc SubtractTerm $ unionWith (+) (countExp e1) (countExp e2)
You get the idea now I hope so you can finish off.