Reputation: 15
this is my current code:
data Exp x = Con Int | Var x | Sum [Exp x] | Prod [Exp x]
| Exp x :- Exp x | Int :* Exp x | Exp x :^ Int
expression :: Exp String
expression = Sum [3:*(Var"x":^2), 2:*Var"y", Con 1]
type Store x = x -> Int
exp2store :: Exp x -> Store x -> Int
exp2store (Con i) _ = i
exp2store (Var x) st = st x
exp2store (Sum es) st = sum $ map (flip exp2store st) es
exp2store (Prod es) st = product $ map (flip exp2store st) es
exp2store (e :- e') st = exp2store e st - exp2store e' st
exp2store (i :* e) st = i * exp2store e st
exp2store (e :^ i) st = exp2store e st ^ i
Exp should represent a polynomial expression and exp2store takes an expression and a function which supplies the variables in the expression with a value.
Example:
*Main> exp2store (Var"x") $ \"x" -> 5
5
that works. I don't know how I could supply multiple variables with different values, i.e.
*Main> exp2store (Sum[Var"x",Var"y"]) $ \"x" "y" -> 5 10
Obviously, this throws an exception. Can somebody help me with this?
Upvotes: 0
Views: 198
Reputation: 530823
It's difficult to write an anonymous function that maps arbitrary inputs to outputs if there is no general formula. To start, you can use an association list instead; the standard function lookup
allows you to get the value for a given variable. (This isn't the best performing method, but it allows you to avoid any additional imports to start.)
-- I lied; one import from the base library
-- We're going to assume the lookup succeeds;
import Data.Maybe
-- A better function would use Maybe Int as the return type,
-- returning Nothing when the expression contains an undefined variable
exp2store :: Eq x => Exp x -> [(x,Int)] -> Int
exp2store (Con i) _ = i
exp2store (Var x) st = fromJust $ lookup x st
exp2store (Sum es) st = sum $ map (flip exp2store st) es
exp2store (Prod es) st = product $ map (flip exp2store st) es
exp2store (e :- e') st = exp2store e st - exp2store e' st
exp2store (i :* e) st = i * exp2store e st
exp2store (e :^ i) st = exp2store e st ^ i
Call the function as
exp2store (Sum[Var"x",Var"y"]) $ [("x",5), ("y",10)]
If you must keep Store
as defined, you can write your call like this
exp2store (Sum[Var"x",Var"y"]) $ \x -> case x of "x" -> 5; "y" -> 10
Upvotes: 4