Haskell 创建函数的解释器 eval
Haskell interpreter eval to create functions
我正在尝试对函数表达式执行 eval 以便能够在我的解释器上创建函数。到目前为止我有这个:
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)
在给定类型上效果很好。但是,当我尝试将其转换为能够处理以下采用表达式和参数列表的类型时:
data Exp = FunExp [String] Exp| AppExp Exp [Exp]
data Val = Closure [String] Exp Env
如
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)
在如下情况下工作
Main> let fun1 = FunExp ["a", "b"] (IntOpExp "+" (VarExp "a") (VarExp "b"))
Main> eval (AppExp fun1 [IntExp 5, IntExp 4]) empty
9
我遇到语法错误。在 foldr 表达式中:
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)
并在插入表达式中:
(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)
我正在尝试使用 foldr 评估我当前环境的所有参数列表,然后将值插入我的函数环境,然后评估函数结果。任何建议表示赞赏。谢谢。
我已经解决了。基本上我必须以更好的方式处理我的类型流。
首先我检查给定的表达式是否形成闭包,这对于能够评估函数应用程序很重要。
然后,如果表达式是一个有效的闭包,我形成闭包并评估所有函数参数(它们是表达式,在评估时成为值),然后将参数与结果值匹配以添加它们到新环境(现在是函数的环境)并使用这个新环境评估函数的主体。这基本上是当您将一些参数传递给函数时发生的情况,在函数内部形成临时变量并在此新函数环境的上下文中完成计算以 return 一个值。
AppExp则变成如下:
eval (AppExp e1 args) env =
case eval e1 env of
(CloVal v body clenv) -> eval body (new_map) -- evaluate the function body with the new environment "new map" in order to get the result
_ -> ExnVal "Apply to non-closure" -- If the expression is not a closure, do not apply function
where
(CloVal v body clenv) = eval e1 env -- Form a closure
arg = map (\x -> eval x env) args --Evaluate all the args to get a list of vals ->arg
new_map = union (fromList (zip v arg)) (clenv) -- add the evaluated values to the function environment in order to evaluate body of the function
我希望这对其他人有帮助。抱歉格式化。干杯!
我正在尝试对函数表达式执行 eval 以便能够在我的解释器上创建函数。到目前为止我有这个:
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)
在给定类型上效果很好。但是,当我尝试将其转换为能够处理以下采用表达式和参数列表的类型时:
data Exp = FunExp [String] Exp| AppExp Exp [Exp]
data Val = Closure [String] Exp Env
如
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)
在如下情况下工作
Main> let fun1 = FunExp ["a", "b"] (IntOpExp "+" (VarExp "a") (VarExp "b"))
Main> eval (AppExp fun1 [IntExp 5, IntExp 4]) empty
9
我遇到语法错误。在 foldr 表达式中:
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)
并在插入表达式中:
(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)
我正在尝试使用 foldr 评估我当前环境的所有参数列表,然后将值插入我的函数环境,然后评估函数结果。任何建议表示赞赏。谢谢。
我已经解决了。基本上我必须以更好的方式处理我的类型流。
首先我检查给定的表达式是否形成闭包,这对于能够评估函数应用程序很重要。
然后,如果表达式是一个有效的闭包,我形成闭包并评估所有函数参数(它们是表达式,在评估时成为值),然后将参数与结果值匹配以添加它们到新环境(现在是函数的环境)并使用这个新环境评估函数的主体。这基本上是当您将一些参数传递给函数时发生的情况,在函数内部形成临时变量并在此新函数环境的上下文中完成计算以 return 一个值。
AppExp则变成如下:
eval (AppExp e1 args) env =
case eval e1 env of
(CloVal v body clenv) -> eval body (new_map) -- evaluate the function body with the new environment "new map" in order to get the result
_ -> ExnVal "Apply to non-closure" -- If the expression is not a closure, do not apply function
where
(CloVal v body clenv) = eval e1 env -- Form a closure
arg = map (\x -> eval x env) args --Evaluate all the args to get a list of vals ->arg
new_map = union (fromList (zip v arg)) (clenv) -- add the evaluated values to the function environment in order to evaluate body of the function
我希望这对其他人有帮助。抱歉格式化。干杯!