Unconstrained trees

In [ ]:
type 'a tree =
type 'a tree =
    Empty : 'a tree
  | Tree : 'a tree * 'a * 'a tree -> 'a tree
 
In [ ]:
let rec depth : 'a.'a tree -> int = function
let rec depth : 'a.'a tree -> int = function
    Empty -> 0
  | Tree (l,_,r) -> 1 + max (depth l) (depth r)
 
In [ ]:
let top : 'a.'a tree -> 'a option = function
let top : 'a.'a tree -> 'a option = function
    Empty -> None
  | Tree (_,v,_) -> Some v
 
In [ ]:
let rec swivel : 'a.'a tree -> 'a tree = function
let rec swivel : 'a.'a tree -> 'a tree = function
    Empty -> Empty
  | Tree (l,v,r) -> Tree (swivel r, v, swivel l)
 

Perfect leafy trees

In [ ]:
type 'a perfect =
type 'a perfect =
    ZeroP : 'a -> 'a perfect
  | SuccP : ('a * 'a) perfect -> 'a perfect
 

Perfect (branchy) trees

In [ ]:
type _ ntree =
type _ ntree =
    EmptyN : 'a ntree
  | TreeN : 'a * ('a * 'a) ntree -> 'a ntree
 
In [ ]:
let rec depthN : 'a.'a ntree -> int = function
let rec depthN : 'a.'a ntree -> int = function
    EmptyN -> 0
  | TreeN (_,t) -> 1 + depthN t
 
In [ ]:
let rec topN : 'a.'a ntree -> 'a option = function
let rec topN : 'a.'a ntree -> 'a option = function
    EmptyN -> None
  | TreeN (v,_) -> Some v
 
In [ ]:
let rec swiv : 'a.('a->'a) -> 'a ntree -> 'a ntree =
let rec swiv : 'a.('a->'a) -> 'a ntree -> 'a ntree =
  fun f t -> match t with
      EmptyN -> EmptyN
    | TreeN (v,t) -> 
      TreeN (f v,swiv (fun (x,y) -> (f y, f x)) t)
 
In [ ]:
let id x = x
let id x = x
 
In [ ]:
let swivelN p = swiv id p
let swivelN p = swiv id p
 

Perfect trees as GADTs

In [ ]:
type z = Z
type z = Z
type _ s = S : 'n -> 'n s
 
In [ ]:
type ('a, _) gtree =
type ('a, _) gtree =
    EmptyG : ('a,z) gtree
  | TreeG : ('a,'n) gtree * 'a * ('a,'n) gtree -> ('a,'n s) gtree
 
In [ ]:
let rec depthG : type a n.(a, n) gtree -> n = function
let rec depthG : type a n.(a, n) gtree -> n = function
    EmptyG -> Z
  | TreeG (l,_,_) -> S (depthG l)
 
In [ ]:
let topG : type a n.(a,n s) gtree -> a =
let topG : type a n.(a,n s) gtree -> a =
  function TreeG (_,v,_) -> v
 
In [ ]:
let rec swivelG : type a n.(a,n) gtree -> (a,n) gtree = function
let rec swivelG : type a n.(a,n) gtree -> (a,n) gtree = function
    EmptyG -> EmptyG
  | TreeG (l,v,r) -> TreeG (swivelG r, v, swivelG l)
 

Zipping perfect trees

In [ ]:
let rec zipTree :
let rec zipTree :
  type a n.(a,n) gtree -> (a,n) gtree -> (a * a,n) gtree =
  fun x y -> match x, y with
      EmptyG, EmptyG -> EmptyG
    | TreeG (l,v,r), TreeG (m,w,s) ->
      TreeG (zipTree l m, (v,w), zipTree r s)
 

Converting from perfect GADT trees to perfect nested trees

In [ ]:
let rec nestify : type a n.(a,n) gtree -> a ntree = function
let rec nestify : type a n.(a,n) gtree -> a ntree = function
    EmptyG -> EmptyN
  | TreeG (l, v, r) -> 
    TreeN (v, nestify (zipTree l r))
 

Unbalanced depth-indexed trees

A type-level max function

In [ ]:
type (_,_) eql = Refl : ('a,'a) eql
type (_,_) eql = Refl : ('a,'a) eql
 
In [ ]:
type (_,_,_) max =
type (_,_,_) max =
    MaxEq : ('a,'b) eql -> ('a,'b,'a) max
  | MaxFlip : ('a,'b,'c) max -> ('b,'a,'c) max
  | MaxSuc : ('a,'b,'a) max -> ('a s,'b,'a s) max
 
In [ ]:
type ('a,_) dtree =
type ('a,_) dtree =
    EmptyD : ('a,z) dtree
  | TreeD : ('a,'m) dtree * 'a * ('a,'n) dtree * ('m,'n,'o) max 
    -> ('a,'o s) dtree
 
In [ ]:
let rec max : type a b c.(a,b,c) max -> a -> b -> c
let rec max : type a b c.(a,b,c) max -> a -> b -> c
  = fun mx m n -> match mx,m with
      MaxEq Refl , _    -> m
    | MaxFlip mx', _    -> max mx' n m
    | MaxSuc mx' , S m' -> S (max mx' m' n)
 
In [ ]:
let rec depthD : type a n.(a,n) dtree -> n = function
let rec depthD : type a n.(a,n) dtree -> n = function
    EmptyD -> Z
  | TreeD (l,_,r,mx) -> S (max mx (depthD l) (depthD r))
 
In [ ]:
let topD : type a n.(a,n s) dtree -> a =
let topD : type a n.(a,n s) dtree -> a =
  function TreeD (_,v,_,_) -> v
 
In [ ]:
let rec swivelD :
let rec swivelD :
  type a n.(a,n) dtree -> (a,n) dtree = function
    EmptyD -> EmptyD
  | TreeD (l,v,r,m) ->
    TreeD (swivelD r, v, swivelD l, MaxFlip m)