Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Pattern Matching for fuctions (+) (-) (/) (*)

For a function definition, I need to output a error when division by zero is detected.

The general case is as follows, op takes the (+), (-), (*), (/) function.

liftIntOp :: (Int->Int->Int)->Val->Val->Val
liftIntOp op (IntVal a) (IntVal b) =IntVal $ op a b

The use case is

Main>liftIntOp (+) (IntVal 3) (IntVal 5)
Main>IntVal 8

However I try to detect the special case of division by 0. My solution is

liftIntOp :: (Int->Int->Int)->Val->Val->Val
liftIntOp (/) _ (IntVal 0) =ErrorVal "Division by 0"
liftIntOp op (IntVal a) (IntVal b) =IntVal $ op a b

But the first branch seems to match any operators.

Main> liftIntOp (-) (IntVal 3) (IntVal 0)
Main> ErrorVal "Division by 0"
Main> liftIntOp (+) (IntVal 3) (IntVal 0)
Main> ErrorVal "Division by 0"

I wonder how to single out the case for division.

like image 744
HarryQ Avatar asked Nov 23 '25 11:11

HarryQ


1 Answers

Firstly, your pattern match on (/) does not work, because GHC thinks you want to bind that argument to the name (/) and overwrite the usual binding of (/). See this simpler example:

ghci> let foo (/) x y = x / y
ghci> foo (+) 1 2
3

As Willem Van Onsem noted in the comments, the usual way to deal with this is to introduce an enumeration data type of all the functions that you want to match against:

data Operation = Add | Sub | Mul | Div

Additionally you then need to give semantics (meaning) to those operations:

applyIntOp :: Operation -> Int -> Int -> Int
applyIntOp Add = (+)
applyIntOp Sub = (-)
applyIntOp Mul = (*)
applyIntOp Div = div -- note that (/) doesn't work on Int

Then you can define liftIntOp as:

liftIntOp :: Operation -> Val -> Val -> Val
liftIntOp Div _ (IntVal 0) = ErrorVal "Division by zero"
liftIntOp op (IntVal x) (IntVal y) = IntVal (applyIntOp op x y)
like image 116
Noughtmare Avatar answered Nov 26 '25 18:11

Noughtmare



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!