Alternatively, you can reorganize your language into binary operations on the one hand and unary on the other. You must write:
data BinOp = PlusOp | MultOp deriving (Show, Eq) data UnOp = ConstOp deriving (Show, Eq) data Expr = Bin BinOp Expr Expr | Un UnOp Expr deriving (Show, Eq) makeBaseFunctor ''Expr
Then the evaluator becomes:
eval :: Expr -> Int eval = cata $ \case BinF op lr -> bin op lr UnF op v -> un op v where bin = \case PlusOp -> (+) MultOp -> (*) un = \case ConstOp -> id
source share