type tree =
| Leaf of int
| Node of tree*tree ;;
Leaf 0;;
let x = Node(Node(Leaf 1, Leaf 2), Leaf 3);;
let rec sum t =
;; solution
let rec sum t =
match t with
| Leaf i -> i
| Node (t1,t2) -> sum t1 + sum t2;;
sum x;;
let rec delete t i =
;; solution
let rec delete t i =
match t with
| Leaf i' -> if i = i' then Leaf 0 else Leaf i'
| Node (t1,t2) -> Node(delete t1 i,delete t2 i);;
;; add Empty case to datatype, and update sum, delete
;; solution
type tree =
| Empty
| Leaf of int
| Node of tree*tree ;;
let rec sum t =
match t with
| Empty -> 0
| Leaf i -> i
| Node (t1,t2) -> sum t1 + sum t2;;
let rec delete t i =
match t with
| Empty -> Empty
| Leaf i' -> if i = i' then Empty else Leaf i'
| Node (t1,t2) -> Node(delete t1 i,delete t2 i);;
;; In java, let's do sum and delete
type tree =
| Leaf of int
| Node of tree*tree ;;
;; solution
abstract class Tree {
abstract public int sum();
abstract public Tree delete(int i);
}
class Leaf extends Tree {
private int data;
public Leaf(int i) { data = i; }
int sum () { return data; }
Tree delete(int i) {
if (data == i) {
return Leaf(0)
} else {
return this
}
}
class Node extends Tree {
private Tree left;
private Tree right;
public Node(Tree l, Tree r) { left = l; right = r; }
int sum () { return left.sum() + right.sum() }
Tree delete(int i) {
return Node(left.delete(), right.delete())
}
}
x = Node(Node(Leaf(1), Leaf(2)), Leaf (3))
x.sum()
;; note: the code of "sum" and "delete" is spread through several classes,
;; whereas in ocaml, all the code for "sum" and "delete" were in one
;; place
;; OCaml organizes computation by operations
;; given an operation, write all cases for that operation in one place
;; in other words, write each operation, and inside you list each kind of data
;;
;; OO organizes computation by cases
;; given a case, write all operations for that case in one place
;; in other words, write each kind of data, and inside you list each operation
;; In java, let's add Empty
;; solution
class Empty extends Tree {
public int sum() { return 0; }
public Tree delete(int i) { return Empty; }
}
;; note: can add Empty case in a modular way, by just adding code,
;; without modifying any code
;; Key lesson:
;; OCAML pattern matching vs OO encoding
;; OCAML: allows for modular addition of "operations" like "sum":
;; - in OCaml, can add a new operation all in one place
;; - in OO, requires changing many different classes
;;
;; OO: allows for modular addition of cases like "Empty":
;; - in OO, can add "Empty" all in one place
;; - in OCaml, requires changing all functions that match on Tree
;;