Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map that associates operators with lambda functions

I have a Haskell Map, containing strings as keys and some lambda functions as items . Eg.:

-- List of supported Operators -> mapping with functions
ops = Map.fromList [("+", \x y -> x + y),
                    ("-", \x y -> y - x),
                    ("*", \x y -> x * y),
                    ("/", \x y -> y / x)]

I want to write a function that takes as input:

  • A string representing an operator ["+", "-", "*", "/"]
  • Two numbers

Based on the operator and the ops map, the function will evaluate the sum/subtraction/etc. of the two numbers .

I've tried something like:

(Map.lookup "+" a) 1 2

But it's not working .

The error is:

Top level:
    No instance for (Show (Integer -> Integer))
      arising from use of `print' at Top level
    Probable fix: add an instance declaration for (Show (Integer
    In a 'do' expression: print it

<interactive>:1:1:
    No instance for (Monad ((->) t))
      arising from use of `Data.Map.lookup' at <interactive>:1:1-
    Probable fix: add an instance declaration for (Monad ((->) t)
    In the definition of `it': it = (Data.Map.lookup "+" a) 1 2

... not very helpful for me.

Any suggestions ? Thank you !

like image 598
Andrei Ciobanu Avatar asked Feb 09 '26 16:02

Andrei Ciobanu


2 Answers

lookup is of type lookup :: Ord k => k -> Map k a -> Maybe a. The result is wrapped in a Maybe to indicate that the key may not be present in the map.

Here's a way to do it that will work:

runOp :: String -> a -> a -> b
runOp key x y = case lookup key ops of
                  Just op -> op x y
                  Nothing -> error ("Couldn't find operator: " ++ key)

This will bottom out if the key is not present. You could also return an Either or Maybe result from runOp to accommodate the possibility that the key isn't present, but that's up to you.

Maybe is defined as follows:

data Maybe a = Just a | Nothing

that is, it either holds a result value or an empty value. Like an existential philosopher, Haskell forces you to acknowledge the possibility of Nothing.

like image 152
Bill Avatar answered Feb 12 '26 15:02

Bill


First of all the error you showed is not caused by the code you showed. Your code causes the following error (in ghc):

Couldn't match expected type `t1 -> t2 -> t'
against inferred type `Data.Maybe.Maybe

That error is caused by the fact that lookup returns a Maybe. So you need to unwrap the Maybe first.

like image 23
sepp2k Avatar answered Feb 12 '26 16:02

sepp2k