module Exp where
import Control.Applicative hiding (Const)
import Data.Monoid
import Data.Traversable
import Data.Foldable
data Exp a
= Var String
| Const Int
| Add a a
deriving (Show, Eq, Ord)
instance Functor Exp where
fmap f x = case x of
Var str -> Var str
Const n -> Const n
Add a b -> Add (f a) (f b)
instance Foldable Exp where
foldMap f x = case x of
Add a b -> f a <> f b
_ -> mempty
instance Traversable Exp where
traverse f x = case x of
Var str -> pure $ Var str
Const n -> pure $ Const n
Add a b -> Add <$> f a <*> f b
-----------------------------------------------
-- interpreters
-- ignore variables
expAsInt :: Exp Int -> Int
expAsInt x = case x of
Var str -> error "boom"
Const n -> n
Add a b -> a + b
expAsDepth :: Exp Int -> Int
expAsDepth x = case x of
Add a b -> 1 + max a b
_ -> 1