Skip to content

Instantly share code, notes, and snippets.

@sgoguen
Created May 27, 2012 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sgoguen/2815935 to your computer and use it in GitHub Desktop.
Save sgoguen/2815935 to your computer and use it in GitHub Desktop.
LINQ to Tree's - Written in F#
namespace NextWeb.Collections
open System
open System.Runtime.CompilerServices
type ITree<'a> =
abstract member Value: 'a
abstract member Children: seq<ITree<'a>>
[<Extension>]
module Trees =
type Tree<'a>(value:'a,children:seq<ITree<'a>>) =
interface ITree<'a> with
member this.Value = value
member this.Children = children
member this.Value = value
member this.Children = children
let private Tree(value,children) =
Tree<'a>(value, children) :> ITree<'a>
let Return value = Tree(value, Seq.empty<ITree<'a>>)
let rec Generate (value:'a) (f:Func<'a,seq<'a>>) =
Tree(value, seq { for item in f.Invoke(value) do
yield Generate item f })
[<Extension>]
let Expand (tree:ITree<'a>) (f:Func<'a,seq<'a>>) =
let value = tree.Value
Tree(value, seq { for item in f.Invoke(value) do
yield Generate item f } )
[<Extension>]
let rec MaxDepth (tree:ITree<'a>) (depth:int) =
let value = tree.Value
let children = tree.Children
if depth <= 1 then
Return value
else
Tree(value, seq { for child in children do
yield MaxDepth child (depth - 1) })
[<Extension>]
let rec Flatten (tree:ITree<'a>) =
seq {
yield tree.Value
for c in tree.Children do
yield! Flatten c
}
[<Extension>]
let rec Select (tree:ITree<'a>) (f:Func<'a,'b>) =
let value = f.Invoke(tree.Value)
Tree(value, seq { for c in tree.Children do
yield Select c f })
[<Extension>]
let rec Where (tree:ITree<'a>) (test:Func<'a,bool>) =
Tree(tree.Value, seq { for c in tree.Children do
if test.Invoke(c.Value) then
yield c })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment