重新格式化Haskell数据构造函数类型程序并重新格式化
我们在包含以下数据构造函数和类型的siml.hs文件中获得了代码:重新格式化Haskell数据构造函数类型程序并重新格式化,haskell,Haskell,我们在包含以下数据构造函数和类型的siml.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
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的函数,它将接受一个siml程序(a
类型为StmtT)的值,并返回此程序的副本,其中
变量名已更改。此函数应具有三个参数:
两个字符串和一个siml程序。字符串表示变量
名字。您的函数应该返回程序的一个副本以及所有
第一个字符串的实例替换为第二个字符串。对于
例如,如果myProgram表示这一点,则使用类似Java的表示法
节目:
虽然我认为我理解了这一点的基本要点,但我对代码的实际实现相当迷茫。例如,如果运行此代码:
changeName "x" "num" testMyProgram...
testMyProgram在哪里
Assign "x" (ALit 3)
我不知道如何让Haskell返回一行StmtT代码,例如:
Assign "num" (ALit 3)
我很确定这就是指导老师想要的 您需要创建一个函数来解构一个术语,如果其中一个组件需要替换,则构建一个新术语
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
,则需要生成一个函数来解构一个术语,如果其中一个组件需要替换,则需要构造一个新术语
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
作为脚注…我会不停地看它,如果我真的弄明白了,我会回来,但我已经盯着这个数小时了…作为脚注…我会不停地看,如果我真的弄明白了,我会回来,但是我已经盯着这个看了好几个小时了…谢谢,我想我理解你的代码和第一个解构部分,但是我不确定changeNameExpr x y b做什么。你能详细解释一下为什么返回分配y b是不够的吗?啊,我想我现在明白了,谢谢你的澄清。我们是否必须在“changeNameExpr”中包含Show和Eq案例,因为它们是派生的?changeNameExpr
作为一个函数不依赖任何东西,因为类型都是具体的,因此只有相关的Eq
存在(对于字符串
)。一旦满意,别忘了结束这个问题。当然,这个解决方案对理解这个项目有很大帮助,非常感谢。谢谢,我想我理解你的代码和第一个解构部分,但我不确定changeNameExpr x y b做什么。你能详细解释一下为什么返回分配y b是不够的吗?啊,我想我现在明白了,谢谢你的澄清。我们是否必须在“changeNameExpr”中包含Show和Eq案例,因为它们是派生的?changeNameExpr
作为一个函数不依赖任何东西,因为类型都是具体的,因此只有相关的Eq
存在(对于字符串
)。一旦满意,别忘了结束这个问题。当然,这个解决方案对理解这个项目有很大帮助,非常感谢。
changeNameExpr x y (Name n) | x == n = Name y
...
changeNameExpr x y (Add a b) = Add (changeNameExpr x y a) (changeNameExpr x y b)