我正在学习haskell而且我不知道如何完成一项练习:
我们可以将广义表达式的数据结构定义为 如下:
data Expr a = Lit a | EVar Var | Op (Ops a) [Expr a]
type Ops a = [a] -> a
type Var = Char
要评估表达式,我们需要知道其变量的所有值。 定义新类型或数据类型Valuation a,将变量与值相关联 类型a。然后写一个函数:
eval :: Valuation a -> Expr a -> a
对于给定的变量估值和表达式,评估(折叠) 表达式为单个值。
额外信息(由我的教授在演习中提供):
评估可以是任何类型,关联Var(= Char)和' a',例如:> [(Var,a)]或Var - > a。
eval函数,在接收到一个结构(类型:Valuation a)和一个>表达式(类型:Expr a)之后,应该将该表达式简化为一个" a"输入>值。
表达式(Expr Int)示例:标准表达式如(x + 10)* y将>看起来像这样:Op * [Op + [EVar'x',Lit 10],EVar'y']。 Valuation Int类型>结构会将EVar'x'与15和EVar'y'与2相关联,然后结束>结果应为50。
我的问题是:
1)估值的这种数据结构应该如何?我正在考虑某种带有键和值的地图,但我可能完全错了。
2)对于eval,我正在考虑编写一个包含所有操作符及其优先级的函数,但总体而言,与我们通常所做的其他练习相比,这个练习看起来有点太难(在我看来) - 大多数情况下最困难的部分是弄清楚练习需要什么,解决方案本身只占用大约5-15行代码;那么,也许我对这个练习的想法是关闭的? 任何帮助,将不胜感激。
答案 0 :(得分:2)
让我们将评论合并到一个答案中:
1)估值的这种数据结构应该如何?我正在考虑某种带有键和值的地图,但我可能完全错了。
您确实在寻找能够将Var
个关键字与a
值相关联的内容。 [(Var, a)]
对列表是实现这一目标的一种方式。然后,您可以使用lookup
:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
lookup key assocs
在关联列表中查找密钥。
或者,您可能需要考虑使用正确的地图类型,例如Map
from containers。
2)对于eval,我正在考虑编写一个包含所有运算符及其优先级的函数[...]
鉴于您的问题陈述,您没有要包含的“所有运营商”列表。再看看Expr
定义......
data Expr a = Lit a | EVar Var | Op (Ops a) [Expr a]
type Ops a = [a] -> a
...表明Op
表达式已经封装了要执行的操作,其中[a] -> a
函数的形式是第一个字段。然后,您的任务归结为将第二个字段中的[Expr a]
转换为[a]
,正确处理这三种Expr
中的每一种,然后应用[a] -> a
函数生成[a]
列表。