|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: Joy of OCaml - Part I |
| 4 | +published: false |
| 5 | +--- |
| 6 | + |
| 7 | +{% highlight ocaml %} |
| 8 | + |
| 9 | + |
| 10 | +type 'a event = Empty | Leaf of 'a node | Node of 'a node |
| 11 | +and 'a node = { value : 'a; |
| 12 | + left : 'a event; |
| 13 | + right : 'a event} |
| 14 | +let change_r e = |
| 15 | + (match e.right with |
| 16 | + |Empty -> Empty |
| 17 | + |_ -> e.right |
| 18 | + ) |
| 19 | + |
| 20 | +let change_l e = |
| 21 | + (match e.left with |
| 22 | + |Empty -> Empty |
| 23 | + |_ -> e.left |
| 24 | + ) |
| 25 | + |
| 26 | +let copy e = |
| 27 | + match e with |
| 28 | + |Node n -> |
| 29 | + let el = n.left in |
| 30 | + let er = n.right in |
| 31 | + Leaf { value = n.value; left = change_l { n with left = el }; right = change_r { n with right = er } } |
| 32 | + |
| 33 | + |Leaf l -> |
| 34 | + let el = l.left in |
| 35 | + let er = l.right in |
| 36 | + Leaf { value = l.value; left = change_l { l with left = el }; right = change_r { l with right = er } } |
| 37 | + |Empty -> Empty |
| 38 | + |
| 39 | +let rec join (e1 : 'a event) ( e2 : 'a event) : 'a event = |
| 40 | + |
| 41 | + match e1,e2 with |
| 42 | + | Node node1,Node node2-> |
| 43 | + if node1.value > node2.value then |
| 44 | + begin |
| 45 | + join (copy e2) e1; |
| 46 | + end |
| 47 | + else |
| 48 | + let d = node2.value - node1.value in |
| 49 | + let n_left = join node1.left node2.left in |
| 50 | + let n_right = join node1.right node2.right in |
| 51 | + Node { value = node2.value + d; left = n_left; right = n_right } |
| 52 | + | Leaf _,Node _-> |
| 53 | + let n = Node { value = 0; left = Empty; right = Empty } in |
| 54 | + join n e2; |
| 55 | + | Node _,Leaf _-> |
| 56 | + let n = Node { value = 0; left = Empty; right = Empty } in |
| 57 | + join e1 n; |
| 58 | + | Leaf node1,Leaf node2-> |
| 59 | + Node { value = max node1.value node2.value; left = node1.left; right = node1.right }; |
| 60 | + | Empty,Empty -> Printf.printf "Event failure"; Empty; |
| 61 | + | Empty, _ -> |
| 62 | + e2 |
| 63 | + | _, Empty -> e1 |
| 64 | + (* e1.normalize(); *) |
| 65 | + |
| 66 | +let drop val1 val2 = |
| 67 | + if val1 <= val2 then |
| 68 | + val2 - val1 |
| 69 | + else |
| 70 | + val1 |
| 71 | + |
| 72 | +let normalize e1 = |
| 73 | + match e1 with |
| 74 | + | Node node-> |
| 75 | + (match node.left,node.right with |
| 76 | + | Leaf node1,Leaf node2 when node1.value == node2.value -> |
| 77 | + Leaf { value = node.value + node1.value; left = node.left; right = node.right } |
| 78 | + | Node node1,Node node2 -> |
| 79 | + let mm = (min node1.value node2.value) in |
| 80 | + let n_l = Node { value = (drop node1.value mm); left = node1.left; right = node1.right } in |
| 81 | + let n_r = Node { value = drop node2.value mm; left = node2.left; right = node2.right } in |
| 82 | + Node { value = node.value + mm ; left = n_l; right = n_r } |
| 83 | + | Node node1, (Empty | Leaf _) -> |
| 84 | + Node { value = node.value; left = Node node1; right = node.right } |
| 85 | + | (Empty | Leaf _), Node node2 -> |
| 86 | + Node { value = node.value; left = node.left; right = Node node2 } |
| 87 | + | (Empty, Empty) -> |
| 88 | + Node { value = node.value; left = Empty; right = Empty } |
| 89 | + | (Empty, Leaf node ) -> |
| 90 | + Node { value = node.value; left = Empty; right = Leaf node } (* Case is not clear *) |
| 91 | + | (Leaf node, (Empty|Leaf _)) -> |
| 92 | + Node { value = node.value; left = Leaf node ; right = Leaf node } (* Case is not clear *) |
| 93 | + ) |
| 94 | + | Leaf node -> |
| 95 | + Leaf { value = node.value ; left = node.left; right = node.right } |
| 96 | + | Empty -> Empty |
| 97 | + |
| 98 | +{% endhighlight %} |
0 commit comments