我有一个布尔抽象语法树
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 []
我收到错误:
错误:变体类型列表没有构造函数Not
也试着用这个:
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 []
编译好但永远不会终止!
答案 0 :(得分:5)
首先,它不应该编译,因为Bast
应该是小写的。
这是因为你在前两种情况下返回类型list
的值,在后三种情况下返回一个原子。此外,(编译器尚未提及它,但很快就会提到)Not
构造函数接受bast
,但您尝试使用bast list
}来创建它p>
答案 1 :(得分:1)
这是我可能会写的第一次尝试:
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 = true
(在您的情况下为exp
)写f tree
,因为它意味着exp
的类型为boolean
{1}}和结果值完全相同(请写下真值表来验证)mylist@[tree]
替换为tree::mylist
更快,但会以相反的顺序生成列表。如果您关心该订单,并希望在列表末尾添加最新的测试树,只需将List.rev
应用于结果(当然,您可以在findtrees
的正文中包含该树) / LI>