Map mapping operators to lambda functions

I have a Haskell map containing strings as keys and some lambda functions as elements. For instance:.

-- 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 the operator ["+", "-", "*", "/"]
  • Two numbers

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

I tried something like:

(Map.lookup "+" a) 1 2

But it does not work.

Error:

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 to me.

Any suggestions? Thank!

+3
source share
3 answers

lookup has a type lookup :: Ord k => k -> Map k a -> Maybe a. The result is wrapped in “Maybe” to indicate that the key cannot be present on the card.

Here's how to do it:

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)

, . Either Maybe runOp, , , .

:

data Maybe a = Just a | Nothing

, . , Nothing.

+7

, , . ( ghc):

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

, lookup a Maybe. Maybe.

+4
import Control.Applicative

ops :: (Fractional a) => Map.Map String (a -> a -> a)
ops = Map.fromList [("+", (+)),
                    ("-", flip (-)),
                    ("*", (*)),
                    ("/", flip (/))]

apply :: (Fractional a) => String -> a -> a -> Maybe a
apply op x y = Map.lookup op ops <*> y <*> x

Since it lookupreturns Maybe a(well, Maybe (a -> a -> a)in this case), there is no way to directly apply it to a. We can use <*>to pull the LHS from the mote, apply it to the RHS and insert it back into the monad. (Or do it manually, like Bill.)

+2
source

Source: https://habr.com/ru/post/1783845/


All Articles