Reputation: 113
I was trying to recreate with a Foldback a function that given a tree and an element x, it will output true if the element is inside the tree, false instead.
This is my tree:
type 'a binTree =
| Null // empty tree
| Node of 'a * 'a binTree * 'a binTree
This is my code without the foldback
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
And this is my foldTree function which applies the fold to a tree:
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 )
They both are working pretty good.
Now to the problem.
I tried to use the foldTree to do the same thing. I was really convinced and sure that this was the right code
let containsTreeF bTree pred =
foldTree ( fun y vl vr -> pred y || vl || vr ) true bTree
but doing some checks with FsCheck, it turns out the result is Falsiable.
I randomly changed the code to this:
let containsTreeF bTree pred =
foldTree ( fun y vl vr -> pred y || vl || vr ) false bTree
Changed the true at the end with false.
Did the FsCheck. It works.
How? I'm not getting it.
Upvotes: 0
Views: 83
Reputation: 243051
Your fold
function is implemented correctly and so the question is about how to use the fold
function to check whether a tree (or anything with a fold
operation) contains a specified element.
To do this, you need to use false
as the initial value and logical or
as the operation, i.e:
let contains x tree =
foldTree (fun y vl vr -> x = y || vl || vr) false tree
This will return false
for an empty tree. If either branch contains the element then true || false
will be true
, but if none of the brnaches contain it then false || false
will result in false
.
How come your FsCheck tests did not catch this when you had true
as the initial value? With that initial value, your function will always return true
, so you would catch this with a test that looks for an element that is not contained in a tree.
A unit test for that would be:
let t = Node(1, Node(2, Null, Null), Null)
contains 7 t
With FsCheck, you could generate tree with values from some randomly generated set and then check that it contains an item that is not in this set.
Upvotes: 1