static void Main(string[] args) { Console.WriteLine("Unlabeled Tree:"); var t = new Br <string> { left = new Lf <string> { contents = "a" }, right = new Br <string> { left = new Br <string> { left = new Lf <string> { contents = "b" }, right = new Lf <string> { contents = "c" } }, right = new Lf <string> { contents = "d" } }, }; t.Show(2); Console.WriteLine(); Console.WriteLine("Hand-Labeled Tree:"); var t1 = new Br <Scp <string> > { left = new Lf <Scp <string> > { contents = new Scp <string> { label = 0, lcpContents = "a" } }, right = new Br <Scp <string> > { left = new Br <Scp <string> > { left = new Lf <Scp <string> > { contents = new Scp <string> { label = 1, lcpContents = "b" } }, right = new Lf <Scp <string> > { contents = new Scp <string> { label = 2, lcpContents = "c" } } }, right = new Lf <Scp <string> > { contents = new Scp <string> { label = 3, lcpContents = "d" } } }, }; t1.Show(2); Console.WriteLine(); Console.WriteLine("Non-monadically Labeled Tree:"); var t2 = Label <string>(t); t2.Show(2); Console.WriteLine(); Console.WriteLine("Monadically Labeled Tree:"); var t3 = MLabel <string>(t); t3.Show(2); Console.WriteLine(); }
static void Main(string[] args) { Console.WriteLine("Unlabeled Tree:"); var t = new Br <string> { left = new Lf <string> { contents = "a" }, right = new Br <string> { left = new Br <string> { left = new Lf <string> { contents = "b" }, right = new Lf <string> { contents = "c" } }, right = new Lf <string> { contents = "d" } }, }; t.Show(2); Console.WriteLine(); Console.WriteLine("Hand-Labeled Tree:"); var t1 = new Br <Scp <string> > { left = new Lf <Scp <string> > { contents = new Scp <string> { label = 0, lcpContents = "a" } }, right = new Br <Scp <string> > { left = new Br <Scp <string> > { left = new Lf <Scp <string> > { contents = new Scp <string> { label = 1, lcpContents = "b" } }, right = new Lf <Scp <string> > { contents = new Scp <string> { label = 2, lcpContents = "c" } } }, right = new Lf <Scp <string> > { contents = new Scp <string> { label = 3, lcpContents = "d" } } }, }; t1.Show(2); Console.WriteLine(); Console.WriteLine("Non-monadically Labeled Tree:"); var t2 = Label <string>(t); t2.Show(2); Console.WriteLine(); Console.WriteLine("Monadically Labeled Tree:"); var t3 = MLabel <string>(t); t3.Show(2); Console.WriteLine(); // Exercise 1: generalize over the type of the state, from int // to <S>, say, so that the SM type can handle any kind of // state object. Start with Scp<T> --> Scp<S, T>, from // "label-content pair" to "state-content pair". var tree = new Branch <string>( new Leaf <string>("a"), new Branch <string>( new Branch <string>( new Leaf <string>("b"), new Leaf <string>("c")), new Leaf <string>("d"))); Exercise1.Exercise1.Run(tree, 0); // Exercise 2: go from labeling a tree to doing a constrained // container computation, as in WPF. Give everything a // bounding box, and size subtrees to fit inside their // parents, recursively. var initialDepth = 0.0; var initialRect = new Rect(100, 100, 0, 0); var ex2Seed = Tuple.Create(initialDepth, initialRect); Exercise2.Exercise2.Run(tree, ex2Seed); // Exercise 3: promote @return and @bind into an abstract // class "M" and make "SM" a subclass of that. // Running exercise 3 with all the pieces from exercise 2: Exercise3.Exercise3.Run(tree, ex2Seed); // Exercise 4 (HARD): go from binary tree to n-ary tree. // Exercise 5: Abstract from n-ary tree to IEnumerable; do // everything in LINQ! (Hint: SelectMany). Exercise5.Exercise5.Run(tree, ex2Seed); // Exercise 6: Go look up monadic parser combinators and // implement an elegant parser library on top of your new // state monad in LINQ. // Exercise 7: Verify the Monad laws, either abstractly // (pencil and paper), or mechnically, via a program, for the // state monad. // Exercise 8: Design an interface for the operators @return // and @bind and rewrite the state monad so that it implements // this interface. See if you can enforce the monad laws // (associativity of @bind, left identity of @return, right // identity of @return) in the interface implementation. // Exercise 9: Look up the List Monad and implement it so that // it implements the same interface. // Exercise 10: deconstruct this entire example by using // destructive updates (assignment) in a discipline way that // treats the entire CLR and heap memory as an "ambient // monad." Identify the @return and @bind operators in this // monad, implement them explicitly both as virtual methods // and as interface methods. }