Functional programming 获取ast的子树
我有一个布尔抽象语法树Functional programming 获取ast的子树,functional-programming,ocaml,abstract-syntax-tree,Functional Programming,Ocaml,Abstract Syntax Tree,我有一个布尔抽象语法树 type bast = True | False | Not of bast | Or of bast * bast | And of bast * bast 我想在它上面应用一个函数,得到所有返回true的子树 我的尝试: let findtrees f (ast: bast ) = let rec findtree (tree: bast ) (mylist: bast list) = match tree with
type bast =
True
| False
| Not of bast
| Or of bast * bast
| And of bast * bast
我想在它上面应用一个函数,得到所有返回true的子树
我的尝试:
let findtrees f (ast: bast ) =
let rec findtree (tree: bast ) (mylist: bast list) = match tree with
| True ->
if (f tree)=true then mylist@[tree] else []
| False ->
if (f tree)=true then mylist@[tree] else []
| Not e -> Not (findtree e subtrees)
| And (e1,e2) -> And (findtree e1 mylist, findtree e2 mylist)
| Or (e1,e2) -> Or (findtree e1 mylist, findtree e2 mylist)
in findtree ast []
我得到一个错误:
错误:变量类型列表没有构造函数
还尝试了以下方法:
let findtrees f (ast: bast) =
let rec findtree (tree: bast) (mylist: bast list) = match tree with
(True|False) -> mylist
| subtree ->
if (f subtree)=true then
mylist@[subtree]
else
select_tree subtree mylist
in findtree ast []
编译很好,但从不终止 首先,它不应该编译,因为
Bast
应该小写
这是因为在前两种情况下返回类型为
list
的值,在后三种情况下返回类型为atom的值。此外,(编译器还没有提到它,但很快就会提到)构造函数不接受bast
,但您试图用bast列表创建它,首先,它不应该编译,因为bast
应该是小写的
这是因为在前两种情况下返回类型为list
的值,在后三种情况下返回类型为atom的值。此外,(编译器还没有提到它,但很快就会提到)不是构造函数接受bast
,但您正在尝试使用bast列表创建它
let findtrees f (ast: bast ) =
let rec findtree tree mylist =
let mylist = if f tree then tree::mylist else mylist in
match tree with
| True| False -> mylist
| Not e -> findtree e mylist
| Or (e1,e2)
| And (e1,e2) -> findtree e2 @@ findtree e1 mylist
in findtree ast []
一些评论:
- 您不需要为任何表达式
exp
编写exp=true
(在您的例子中是f tree
),因为这意味着exp
属于布尔类型,并且结果值将完全相同(请编写真值表以验证这一点)
- 我将
mylist@[tree]
替换为tree::mylist
,后者速度更快,但生成的列表顺序相反。如果您关心该顺序,并且希望在列表末尾有最新的测试树,只需对结果应用list.rev
(您当然可以将其包含在findtrees
的主体中)
- 因为您的树表示布尔表达式,所以可能有更好的方法来处理您试图解决的问题李>
作为第一次工作尝试,我可能会写以下内容:
let findtrees f (ast: bast ) =
let rec findtree tree mylist =
let mylist = if f tree then tree::mylist else mylist in
match tree with
| True| False -> mylist
| Not e -> findtree e mylist
| Or (e1,e2)
| And (e1,e2) -> findtree e2 @@ findtree e1 mylist
in findtree ast []
一些评论:
- 您不需要为任何表达式
exp
编写exp=true
(在您的例子中是f tree
),因为这意味着exp
属于布尔类型,并且结果值将完全相同(请编写真值表以验证这一点)
- 我将
mylist@[tree]
替换为tree::mylist
,后者速度更快,但生成的列表顺序相反。如果您关心该顺序,并且希望在列表末尾有最新的测试树,只需对结果应用list.rev
(您当然可以将其包含在findtrees
的主体中)
- 因为您的树表示布尔表达式,所以可能有更好的方法来处理您试图解决的问题李>
尝试使用| Not(e)->Not(findtree e子树)
同样的错误,@chrisstewart如果您不关心结果顺序,您可能希望返回mylist@[Not(findtree e子树)]
或更简单的(Not(findtree e子树))::mylist
。在接下来的匹配中,和
以及或
也是如此。两者都不起作用,@didiercLet澄清了你函数的目标:你想遍历给定树的每一个子树(包括子树的子树),并返回给定函数所接受的所有子树f
,对吗?尝试使用| Not(e)->Not(findtree e子树)
相同错误,@chrisstewart您可能希望返回mylist@[Not(findtree e子树)]
或更简单的(Not(findtree e子树))::mylist
如果你不关心结果的顺序。在接下来的匹配中,和
和或
也是如此。两者都不起作用,@didiercLet澄清了你函数的目标:你想遍历给定树的每一个子树(包括子树的子树)然后返回给定函数f
,对吗?感谢您的帮助,@ivg!对此有什么建议吗?您需要确保函数的所有分支上的返回类型都相同。在Ocaml中,不能像在d中一样在同一个函数中返回list
和bast
类型的内容动态类型语言,如python。您希望函数返回bast
还是list
?我希望返回f参数返回true的所有子树的列表。我认为,您混淆了自己并试图做错误的事情。首先,如果您的函数f
已经接受bast
,则恩,它应该递归到树中。这意味着,你确实有两个嵌套循环。而且,任务在我看来是错误的。我认为,你正在尝试做类似的事情。但我可能错了。我建议你,从一个例子开始,说明你的函数应该如何工作。就像给定这个输入,我期望这个输出。问题是,当我在叶子上返回一个bast类型(如果是f tree,那么是tree)没有其他条件,因为我的ast不支持空值。因此我返回列表。感谢您的帮助,@ivg!对此有什么建议吗?您需要确保返回类型在函数的所有分支上都是相同的。您不能在Ocaml中与c相同的函数中返回list
和bast
类型的内容动态类型语言(如python)中的。是否希望函数返回bast
或list
?我希望返回f参数返回true的所有子树的列表。我认为,您混淆了自己并试图做错误的事情。首先,如果您的函数f
已经接受bast代码>然后它应该递归到树中。这意味着,您确实有两个嵌套循环。而且,任务在我看来是错误的。我认为,您正在尝试做类似的事情。但我可能是