Harrison
Harrison

Reputation: 430

Data types and non exhaustive patterns

If have a data type

data Arith  = Con Int
              | Add Arith Arith
              | Sub Arith Arith
              | Mul Arith Arith
              | Div Arith Arith

an instance:

instance Show Arith where
    show (Con i)     = show i
    show (Add e1 e2) =  "(" ++ show e1 ++ " + " ++ show e2 ++ ")" 
    show (Sub e1 e2) =  "(" ++ show e1 ++ " - " ++ show e2 ++ ")" 
    show (Mul e1 e2) =  "(" ++ show e1 ++ " * " ++ show e2 ++ ")" 
show (Div e1 e2) =  "(" ++ show e1 ++ " / " ++ show e2 ++ ")" 

and a function evaluate which is expected behave like:

ghci> eval (Mul (Con 5) (Div (Con 6) (Con 2) ))
15

this is what I've come up with that's not working when I try anything more complex then the basic case.

eval :: ArithExp -> Int
eval (Con e1)                = e1
eval (Add (Con e1) (Con e2)) = e1 + e2
eval (Sub (Con e1) (Con e2)) = e1 - e2
eval (Div (Con e1) (Con e2)) = e1 `div` e2
eval (Mul (Con e1) (Con e2)) = e1 * e2

When I try anything that isn't in this case, of course I get an error about exhaustive patterns.

So my question is, how do I catch all of the patterns without doing it the naive way?

I did notice that Add is defined as Add Arith Arith, Sub Arith Arith so how would I take advantage of that in my eval function? I tried doing:

eval (Add Arith Arith) = Arith + Arith

But that didn't work either, (not in scope error).

You don't need to give me a full working code example or anything, I'm just trying to get pointed in the right direction. Still new at haskell.

Thanks.

Upvotes: 1

Views: 191

Answers (2)

nponeccop
nponeccop

Reputation: 13677

Here is a little refactoring to reduce duplication:

data OpT = Add | Sub | Mul | Div

data Arith  = Con Int
            | Op OpT Arith Arith

eval :: Arith -> Int
eval (Con a) = a
eval (Op f a b) = evalOp f (eval a) (eval b) where
    evalOp Add = (+)
    evalOp Sub = (-)
    evalOp Mul = (*)
    evalOp Div = div

You can do the same with show.

Upvotes: 0

migorec
migorec

Reputation: 110

You should use recursion.

eval (Add a1 a2) = (eval a1) + (eval a2)

etc..

Upvotes: 6

Related Questions