I have a Tree type:
type Tree<'value> =
| Node of value: 'value * children: ConsList<Tree<'value>>
| Leaf of value: 'value
And a fold function for it:
let rec fold folder acc tree =
let f = fold folder
match tree with
| Leaf value -> folder acc value
| Node(value, children) -> ConsList.fold f (folder acc value) children
ConsList in case you need it:
type ConsList<'value> =
| Cons of head: 'value * tail: ConsList<'value>
| Empty
let rec fold folder acc lst =
let f = fold folder
match lst with
| Empty -> acc
| Cons (hd, tl) -> f (folder acc hd) tl
I need a foldBack function, meaning the function passes through the nodes from left to right from top to bottom, starting from the root.
I ended up on this:
let rec foldBack folder acc tree =
let f = fold folder
match tree with
| Leaf value -> f acc value
| Node(value, children) -> f value (f acc *children*)
Children with ** type is expected to be Tree<'a> but has type ConsList<Tree<Tree<'a>>>
For back folds it is common to have accumulator as a function which receives intermediate folded value of sub-branch and returns new folded value with respect to the current element. Thus iterating through the tree normally from top to bottom you literally construct the computation which when receives the terminal elements will compute the bottom to top fold.
You can look for continuation passing style topic more yourself. This approach is also used to optimize for tail-call recursion because function you accumulating is the chain of function objects which doesn't affect stack.
Here is what I've done so far (I replaced ConsList with normal List type, because otherwise it would require to create the foldBack for it as well, which you can try yourself)
type ConsList<'t> = 't list
type Tree<'value> =
| Node of value: 'value * children: ConsList<Tree<'value>>
| Leaf of value: 'value
let foldBack seed folder (tree: 't Tree) =
let rec fold acc tree =
match tree with
| Leaf value ->
let acc' inner = folder (acc inner) value
acc'
| Node (value, children) ->
let acc' inner = List.foldBack (fold acc) children inner
let acc'' inner = folder (acc' inner) value
acc''
fold id tree seed
let treeSample =
Node ("node1", [
Leaf "subnode1";
Node ("node1.1", [
Leaf "subnode1.1";
Node("node1.2", [
Leaf "leaf1.2"
])
])
])
treeSample|>foldBack ">>seed<<" (fun value acc -> $"{value} -> {acc}" )
val it: string = ">>seed<< -> leaf1.2 -> node1.2 -> subnode1.1 -> node1.1 -> subnode1 -> node1"
I'm struggling with mapping non trivial function to be tail recursive.
take even the simple rosetree
type Tree<'a> =
| Leaf of 'a
| Branch of List<Tree<'a>>
with map
let rec map : ('a -> 'b) -> Tree<'a> -> Tree<'b> =
fun f ->
function
| Leaf a ->
f a
|> Leaf
| Branch xs ->
xs
|> List.map (map f)
|> Branch
(let alone bind)
making this tail recursive seems quite painful, I've looked at examples in things like FSharpx, but they arent tail recursive.
I have found this
https://www.gresearch.co.uk/article/advanced-recursion-techniques-in-f/
but the leap from the final example based on continuities seems quite bespoke to their example (of max), I can't seem to get my head around it.
is there an example implementation of this pretty canonical example somewhere?
so the simple bit would be something like this
let map2 : ('a -> 'b) -> Tree<'a> -> Tree<'b> =
fun f ta ->
let rec innerMap : Tree<'a> -> (Tree<'b> -> Tree<'b>) -> Tree<'b> =
fun ta cont ->
match ta with
| Leaf a ->
f a |> Leaf |> cont
innerMap ta id
but I'm missing the hard bit with branch
If you use the suggestion from your link the implementation is as follows:
let rec mapB : ('a -> 'b) -> Tree<'a> -> (Tree<'b>-> Tree<'b>) -> Tree<'b> =
fun f ta k ->
match ta with
| Leaf a -> k (Leaf (f a))
| Branch ys ->
let continuations = ys |> List.map (mapB f)
let final (list:List<Tree<'b>>) = k (Branch list)
Continuation.sequence continuations final
As you've noticed the case for the leaf is straightforward: apply F, wrap it back into a Leaf and apply the continuation.
As for the Branch, we generate a number of partial functions that map the children in the branch. We leverage Continuation.sequence which executes these partial functions for us. We then take the result, wrap it in a Branch and apply the (final) continuation.
A basic test:
let t = Branch ([Leaf 3; Leaf 4;Leaf 5;Branch([Leaf 6])])
let t4 = mapB (fun x->x+1) t id
printfn "%A" t4
yields
Branch [Leaf 4; Leaf 5; Leaf 6; Branch [Leaf 7]]
On a side note what are you trying to do? run Montecarlo simulations with thousands of scenarios? I have yet to run into a stack overflow error even with your original implementation.
Please, how do I make this function return the value of every branch and leaf as a float list? I have tried several methods with Tail recursion but I am not able to return the head I cannot loop through the branch and leaf.
type 'a Tree = | Leaf of 'a | Branch of 'a Tree * 'a Tree
let medianInTree (lst: float Tree) :float list=
let rec medianInTree' (a : float Tree) acc =
match lst with
| Leaf(n) -> n :: acc
| Branch(Leaf(xx), Leaf(xs)) -> xx :: [xs]
| Branch(Leaf(x), Branch(Leaf(xx), Leaf(xs))) ->
let acc = medianInTree'(Leaf(x)) acc
medianInTree' (Branch(Leaf(xx), Leaf(xs))) acc
| Branch(_, _) -> []
medianInTree' lst []
Question: medianInTree (Branch(Leaf(2.0), Branch(Leaf(3.0), Leaf(5.0))))
I want this result: [2.0;3.0;5.0]
using an accumulator, you can do something like this:
let flatten tree =
let rec toList tree acc =
match tree with
| Leaf a -> a :: acc
| Branch(left, right) ->
let acc = toList left acc
toList right acc
toList tree [] |> List.rev
But doing so, the recursive call to process the left branch is not tail recursive.
To insure tail recursion while processing tree structures, you have to use continuations.
let flatten tree =
let rec toList tree cont acc =
match tree with
| Leaf a -> cont (a :: acc)
| Branch(left, right) -> toList left (fun l ->
toList right (fun r ->
cont r) (cont l)) acc
toList tree id [] |> List.rev
Which can be simplified as:
let flatten tree =
let rec toList tree cont acc =
match tree with
| Leaf a -> cont (a :: acc)
| Branch (left, right) -> toList left (toList right cont) acc
toList tree id [] |> List.rev
Your main bug is using match with lst instead of on a. I made it a bit simpler as well.
let medianInTree (lst: float Tree) :float list=
let rec medianInTree' (a : float Tree)=
match a with
| Leaf(n) -> [n]
| Branch(l, r) -> (medianInTree' l) # (medianInTree' r)
medianInTree' lst
I have a list :
[objA;objB;objC;objD]
I need to do the following reduction :
obj -> obj -> obj
ie :
objA objB -> objB'
and then take back the original list so that I get :
[objB';objC;objD]
I am trying to do the following :
let rec resolveConflicts = function
| [] -> []
| [c] -> resolveConflict c
| [x;y] -> resolveConflict x
|> List.filter getMovesRelatedtoY
|> List.append y
|> resolveConflict
| [x;y::tail] ->
let y' = resolveConflict x
|> List.filter getMovesRelatedtoY
|> List.append y
resolveConflicts y'::tail
This syntax is not correct, may be I am not even using the correct tool... I am open to any well suited solution so that I can learn.
As to why, I filter the list and append one to another, it is just that every conflict is a list of moves.
To match first element, second element and the rest of the list, use this pattern:
| fst::snd::rest ->
You can match any constant number of first elements using this styling:
| fst::snd::thrd:: ... ::rest ->
This is hurting my brain!
I want to recurse over a tree structure and collect all instances that match some filter into one list.
Here's a sample tree structure
type Tree =
| Node of int * Tree list
Here's a test sample tree:
let test =
Node((1,
[Node(2,
[Node(3,[]);
Node(3,[])]);
Node(3,[])]))
Collecting and filtering over nodes with and int value of 3 should give you output like this:
[Node(3,[]);Node(3,[]);Node(3,[])]
The following recursive function should do the trick:
// The 'f' parameter is a predicate specifying
// whether element should be included in the list or not
let rec collect f (Node(n, children) as node) =
// Process recursively all children
let rest = children |> List.collect (collect f)
// Add the current element to the front (in case we want to)
if (f n) then node::rest else rest
// Sample usage
let nodes = collect (fun n -> n%3 = 0) tree
The function List.collect applies the provided function to all elements of the
list children - each call returns a list of elements and List.collect
concatenates all the returned lists into a single one.
Alternatively you could write (this maay help understanding how the code works):
let rest =
children |> List.map (fun n -> collect f n)
|> List.concat
The same thing can be also written using list comprehensions:
let rec collect f (Node(n, children) as node) =
[ for m in children do
// add all returned elements to the result
yield! collect f m
// add the current node if the predicate returns true
if (f n) then yield node ]
EDIT: Updated code to return nodes as pointed out by kvb.
BTW: It is generally a good idea to show some code that you tried to write so far. This helps people understand what part you didn't understand and so you'll get more helpful answers (and it is also considered as polite)
A more complex tail recursive solution.
let filterTree (t : Tree) (predicate : int -> bool) =
let rec filter acc = function
| (Node(i, []) as n)::tail ->
if predicate i then filter (n::acc) tail
else filter acc tail
| (Node(i, child) as n)::tail ->
if predicate i then filter (n::acc) (tail # child)
else filter acc (tail # child)
| [] -> acc
filter [] [t]
Just for showing usage of F# Sequences Expression (maybe not the best approach, Tomas's solution more likely better I think):
type Tree =
| Node of int * Tree list
let rec filterTree (t : Tree) (predicate : int -> bool) =
seq {
match t with
| Node(i, tl) ->
if predicate i then yield t
for tree in tl do
yield! filterTree tree predicate
}
let test = Node (1, [ Node(2, [ Node(3,[]); Node(3,[]) ]); Node(3,[]) ])
printfn "%A" (filterTree test (fun x -> x = 3))
When my brain hurts cuz it's stuck up a tree, I try to say what I want as simply and clearly as I can:
Given a tree of info, list all sub-trees matching a predicate (in this case, info = 3).
One straightforward way to do it is to list all nodes of the tree, then filter on the predicate.
type 'info tree = Node of 'info * 'info tree list
let rec visit = function
| Node( info, [] ) as node -> [ node ]
| Node( info, children ) as node -> node :: List.collect visit children
let filter predicate tree =
visit tree
|> List.filter (fun (Node(info,_)) -> predicate info)
Here's the tree filter run against the OP's sample data:
let result = filter (fun info -> info = 3) test
One thing that surprised me is how easily the code works for any 'info type with the appropriate predicate:
let test2 =
Node(("One",
[Node("Two",
[Node("Three",[Node("Five",[]);Node("Three",[])]);
Node("Three",[])]);
Node("Three",[])]))
let res2 = filter (fun info -> info = "Three") test2
Alternatively, if you wanted to list the info rather than the sub-trees, the code is breath-takingly simple:
let rec visit = function
| Node( info, [] ) -> [ info ]
| Node( info, children ) -> info :: List.collect visit children
let filter predicate tree =
visit tree
|> List.filter predicate
which supports the same queries but only returns the 'info records, not the tree structure:
let result = filter (fun info -> info = 3) test
> val result : int list = [3; 3; 3; 3]
Tomas's approach looks standard, but doesn't quite match your example. If you actually want the list of matching nodes rather than values, this should work:
let rec filter f (Node(i,l) as t) =
let rest = List.collect (filter f) l
if f t then t::rest
else rest
let filtered = filter (fun (Node(i,_)) -> i=3) test
Here is an over engineered solution but it shows seperation of concerns with Partial Active Patterns. This isn't the best example for partial active patterns but it was a fun exercise nonetheless. Match statements are evaluated in order.
let (|EqualThree|_|) = function
| Node(i, _) as n when i = 3 -> Some n
| _ -> None
let (|HasChildren|_|) = function
| Node(_, []) -> None
| Node(_, children) as n -> Some children
| _ -> None
let filterTree3 (t : Tree) (predicate : int -> bool) =
let rec filter acc = function
| EqualThree(n)::tail & HasChildren(c)::_ -> filter (n::acc) (tail # c)
| EqualThree(n)::tail -> filter (n::acc) tail
| HasChildren(c)::tail -> filter acc (tail # c)
| _::tail -> filter acc tail
| [] -> acc
filter [] [t]