34 people like it.

Composite pattern and Visitor Pattern

use composite pattern to construct a tree and visitor pattern to bring back the traverse result.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
type IA2<'T> =
    abstract member Do : 'T -> unit
 
type CompositeNode<'T> = 
    | Node of 'T
    | Tree of 'T * CompositeNode<'T> * CompositeNode<'T>
    with 
        member this.InOrder f = 
            match this with
            | Tree(n, left, right) -> 
                left.InOrder(f)
                f(n)
                right.InOrder(f)
            | Node(n) -> f(n)
        member this.PreOrder f =
            match this with
            | Tree(n, left, right) ->                 
                f(n)
                left.PreOrder(f)
                right.PreOrder(f)
            | Node(n) -> f(n)
        member this.PostOrder f =
            match this with
            | Tree(n, left, right) -> 
                left.PostOrder(f)
                right.PostOrder(f)
                f(n)
            | Node(n) -> f(n)
       

let Invoke() = 
    let tree = Tree(1, Tree(11, Node(12), Node(13)), Node(2))
    let wrapper = 
        let result = ref 0
        ({ new IA2<int> with                
                member this.Do(n) = 
                    result := !result + n                
        }, result)
    tree.PreOrder (fst wrapper).Do

    printfn "result = %d" !(snd wrapper)
abstract member IA2.Do : 'T -> unit

Full name: Script.IA2`1.Do
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
type CompositeNode<'T> =
  | Node of 'T
  | Tree of 'T * CompositeNode<'T> * CompositeNode<'T>
  member InOrder : f:('T -> unit) -> unit
  member PostOrder : f:('T -> unit) -> unit
  member PreOrder : f:('T -> unit) -> unit

Full name: Script.CompositeNode<_>
union case CompositeNode.Node: 'T -> CompositeNode<'T>
union case CompositeNode.Tree: 'T * CompositeNode<'T> * CompositeNode<'T> -> CompositeNode<'T>
val this : CompositeNode<'T>
member CompositeNode.InOrder : f:('T -> unit) -> unit

Full name: Script.CompositeNode`1.InOrder
val f : ('T -> unit)
val n : 'T
val left : CompositeNode<'T>
val right : CompositeNode<'T>
member CompositeNode.InOrder : f:('T -> unit) -> unit
member CompositeNode.PreOrder : f:('T -> unit) -> unit

Full name: Script.CompositeNode`1.PreOrder
member CompositeNode.PreOrder : f:('T -> unit) -> unit
member CompositeNode.PostOrder : f:('T -> unit) -> unit

Full name: Script.CompositeNode`1.PostOrder
member CompositeNode.PostOrder : f:('T -> unit) -> unit
val Invoke : unit -> unit

Full name: Script.Invoke
val tree : CompositeNode<int>
val wrapper : IA2<int> * int ref
val result : int ref
Multiple items
val ref : value:'T -> 'T ref

Full name: Microsoft.FSharp.Core.Operators.ref

--------------------
type 'T ref = Ref<'T>

Full name: Microsoft.FSharp.Core.ref<_>
type IA2<'T> =
  interface
    abstract member Do : 'T -> unit
  end

Full name: Script.IA2<_>
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
val this : IA2<int>
abstract member IA2.Do : 'T -> unit
val n : int
val fst : tuple:('T1 * 'T2) -> 'T1

Full name: Microsoft.FSharp.Core.Operators.fst
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
Raw view New version

More information

Link:http://fssnip.net/7o
Posted:6 years ago
Author:Tao Liu
Tags: design patterns