I am trying to implement eval on function expressions to be able to create functions on my interpreter. So far I have this :
data Exp = FunExp String Exp| AppExp Exp Exp
data Val = Closure String Exp Env
eval (FunExp v body) env = Closure v body env
eval (AppExp e1 e2) env =
let (Closure v body clenv) = eval e1 env
arg = eval e2 env
in eval body (insert v arg clenv)
which works well on given types. However, when I try to convert this to be able to work on following types that take list of expressions and arguments:
data Exp = FunExp [String] Exp| AppExp Exp [Exp]
data Val = Closure [String] Exp Env
as in
eval (FunExp params body) env = (CloVal params body env)
eval (AppExp e1 args) env =
eval body (insert v arg clenv)
where
(CloVal v body clenv) = eval e1 env
arg = (foldr eval env args)
to work in a case like the following
Main> let fun1 = FunExp ["a", "b"] (IntOpExp "+" (VarExp "a") (VarExp "b"))
Main> eval (AppExp fun1 [IntExp 5, IntExp 4]) empty
9
I get sytax errors. In the foldr expression :
arg = (foldr eval env args)
Couldn't match type ‘Val’ with ‘HashMap String Val’
Expected type: Exp -> Val -> Val
Actual type: Exp -> Env -> Val
• In the first argument of ‘foldr’, namely ‘eval’
In the expression: (foldr eval env args)
In an equation for ‘arg’: arg = (foldr eval env args)
And in the insert expression :
(insert v arg clenv)
Couldn't match type ‘[Char]’ with ‘Char’
Expected type: Env
Actual type: HashMap [String] Val
• In the second argument of ‘eval’, namely ‘(insert v arg clenv)’
In the expression: eval body (insert v arg clenv)
I am trying to evaluate all list of arguments to my current environment using foldr and then insert the values to my functions environment, and then evaluate the function result. Any advice are appreciated. Thank you.