我们在SImpL.hs文件中给出了代码,其中包含以下数据构造函数和类型:
module SImpL where
data AExprT = ALit ValT -- a literal value (an Int)
| AName NameT -- a variable name (a String)
| Add AExprT AExprT -- one arithmetic expression added to another
| Sub AExprT AExprT -- one arithmetic expression subtracted from another
| Mult AExprT AExprT -- one arithmetic expression multiplied by another
deriving (Show,Eq)
data BExprT = BLit Bool -- a literal value (True or False)
| Eq AExprT AExprT -- an equality test between two arithmetic expressions
| Less AExprT AExprT -- a "less than" test between two arithmetic expressions
| Greater AExprT AExprT -- a "greater than" test between two arithmetic expressions
| Not BExprT -- the negation of a boolean expression
| And BExprT BExprT -- the "and" of two boolean expressions
| Or BExprT BExprT -- the "or" of two boolean expressions
deriving (Show,Eq)
type ValT = Integer
type NameT = String
data StmtT = Assign NameT AExprT |
If BExprT StmtT StmtT |
While BExprT StmtT |
Seq [StmtT] -- If the list is empty, this is a statement that does nothing.
deriving (Show,Eq)
If BExprT StmtT StmtT |
While BExprT StmtT |
Seq [StmtT] -- If the list is empty, this is a statement that does nothing.
deriving (Show,Eq)
type ProgT = StmtT
type StateT = [(NameT, ValT)]
我们被要求完成这项任务:
编写一个名为changeName的函数,它将采用一个SImpL程序(a stmtT类型的值)并返回此程序的副本 变量名称已更改。这个函数应该有三个参数: 两个字符串和一个SImpL程序。字符串代表变量 名。您的函数应该返回所有程序的副本 第一个字符串的实例被第二个字符串替换。对于 例如,如果myProgram表示这一点,则使用类似Java的表示法 程序:
x = 3
y = 14
z = 0
while (x < y)
z = z + x*y
x = x + 1
answer = z + y
changeName&#34; x&#34;的结果&#34;数&#34; myProgram应该是一个 该计划的代表:
number = 3
y = 14
z = 0
while (number < y)
z = z + number *y
number = number + 1
answer = z + y
你的changeName函数需要为每种类型都有一个案例 在SImpL语言中的语句,您将需要一个辅助函数 更改表达式中变量的名称。
我所做的伪代码如下:
module Assignment3 where
import SImpL
changeName :: String -> String -> StmtT -> StmtT
changeName val1 val2 (Assign NameT AExprT) = ...
changeName val1 val2 (If BExprT StmtT StmtT) = ...
changeName val1 val2 (While BExprT StmtT) = ...
changeName val1 val2 (Seq [StmtT]) = ...
虽然我认为我理解了这个的基本要点,但我对代码的实际实现感到很遗憾。例如,如果您运行此代码:
changeName "x" "num" testMyProgram...
其中testMyProgram只是
Assign "x" (ALit 3)
我不知道如何让Haskell返回一行StmtT代码,例如:
Assign "num" (ALit 3)
我很确定这是指导者想要的指示。
答案 0 :(得分:2)
您需要创建一个解构术语的函数,如果其中一个组件需要替换,则构造一个新术语。
changeNameStmt x y (Assign a b) | x == a = Assign y (changeNameExpr x y b)
| otherwise = Assign a (changeNameExpr x y b)
...
由于Expr
也可能引用变量,因此有必要递归到它并替换那里出现的所有事件。
changeNameExpr x y (Name n) | x == n = Name y
...
changeNameExpr x y (Add a b) = Add (changeNameExpr x y a) (changeNameExpr x y b)
对语句中涉及的所有类型执行此操作。如果你想要一个多态changeName
,你可以定义一个类并创建它的类型实例。