重新创建带有折返的“ tree cointains元素”。我不明白为什么会这样

时间:2019-09-06 09:04:01

标签: f# tree fold

我试图用折返式创建给定一棵树和一个元素x的函数,如果该元素在树内,它将输出true,否则输出false。 这是我的树:

type 'a binTree =
  | Null                                     // empty tree
  | Node of 'a  * 'a binTree * 'a binTree

这是我的没有折返代码

let rec containsTreeBis bTree y =
match bTree with 
    | Null -> false
    | Node(x,left,right) -> 
        match x=y with 
            | true -> true 
            | _ -> containsTreeBis left y || containsTreeBis right y

这是我的foldTree函数,可将折叠应用于树:

let rec foldTree f e tree = 
match tree with
  | Null -> e
  | Node (x, left, right) ->
    f x ( foldTree f e left )  ( foldTree f e right )

他们俩都表现不错。

现在是问题所在。

我尝试使用foldTree做同样的事情。 我真的很确信并确定这是正确的代码

 let containsTreeF bTree pred = 
    foldTree ( fun y vl vr -> pred y || vl || vr ) true bTree

但是使用FsCheck进行了一些检查,结果是Falsiable。

我随机将代码更改为此:

 let containsTreeF bTree pred = 
    foldTree ( fun y vl vr -> pred y || vl || vr ) false bTree 

最后将true更改为false。

进行了FsCheck。有用。

如何?我不明白。

1 个答案:

答案 0 :(得分:1)

您的fold函数已正确实现,因此问题在于如何使用fold函数检查树(或带有fold操作的任何树)是否包含指定的元素

为此,您需要使用false作为初始值,并使用逻辑or作为操作,即:

let contains x tree = 
  foldTree (fun y vl vr -> x = y || vl || vr) false tree

这将为空树返回false。如果任一分支包含元素,则true || false将为true,但是如果所有分支均不包含元素,则false || false将得到false

当您将true用作初始值时,为什么FsCheck测试没有捕获到该错误?有了该初始值,您的函数将始终返回true,因此您可以通过测试查找不包含在树中的元素来捕获它。

对此的单元测试将是:

let t = Node(1, Node(2, Null, Null), Null)
contains 7 t

使用FsCheck,您可以根据某些随机生成的集合生成值的树,然后检查其中是否包含不在此集合中的项。