About PFDS The following Oz code is derived from the examples provided in the book:
      "Purely Functional Data Structures" by Chris Okasaki.
      http://okasaki.blogspot.com/2008/02/ten-years-of-purely-functional-data.html

PFDS Chapter #10 Examples in Oz
% Functions defined in previous chapters
ORDEREDVALUE =
   functor
   export
      eq : EQ
      lt : LT
      leq : LEQ
   define
      fun {EQ X Y} X == Y end
      fun {LT X Y} X < Y end
      fun {LEQ X Y} X =< Y end
   end
[OrderedValue] = {Module.apply [ORDEREDVALUE]}

PAIRINGHEAP =
   functor
   export
      initialize : Initialize
      empty      : Empty
      isEmpty    : IsEmpty
      insert     : Insert
      merge      : Merge
      findMin    : FindMin
      deleteMin  : DeleteMin
   define
      Element
      proc {Initialize OrderedSet}
         Element = OrderedSet
      end
      Empty = nil
      fun {IsEmpty Heap} Heap == Empty end
      fun {Merge Heap1 Heap2}
         case Heap1#Heap2
         of _#nil then Heap1
         [] nil#_ then Heap2
         [] tree(X Hs1)#tree(Y Hs2) then
            if {Element.leq X Y} then
               tree(X Heap2|Hs1)
            else
               tree(Y Heap1|Hs2)
            end
         end
      end
      fun {Insert X Heap}
         {Merge tree(X nil) Heap}
      end
      fun {MergePairs HeapList}
         case HeapList
         of nil then nil
         [] [X] then X
         [] Heap1|Heap2|Hs then {Merge {Merge Heap1 Heap2} {MergePairs Hs}}
         end
      end
      fun {FindMin Heap}
         case Heap
         of tree(X Hs) then X
         else raise empty end
         end
      end
      fun {DeleteMin Heap}
         case Heap
         of tree(X Hs) then {MergePairs Hs}
         else raise empty end
         end
      end
   end

% Utility functions for tests
proc {HeapTest F}
   A = {F.insert 1 F.empty}
   B = {F.insert 3 A}
   C = {F.insert 7 B}
   D = {F.insert 5 C}
   X = {F.insert 2 F.empty}
   Y = {F.insert 6 X}
   Z = {F.insert 4 Y}
   H = {F.merge D Z}
in
   {Browse D}
   {Browse Z}
   {Browse H}
   {Browse {F.findMin H}}
   {Browse {F.findMin {F.deleteMin H}}}
   {Browse {F.findMin {F.deleteMin {F.deleteMin H}}}}
   {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}}
   {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}}}
   {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}}}}
   {Browse {F.findMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin {F.deleteMin H}}}}}}}}
end

proc {QueueTest F}
   A = F.empty
   B = {F.snoc A 1}
   C = {F.snoc B 2}
   D = {F.snoc C 3}
in
   {Browse D}
   {Browse {F.head D}}
   {Browse {F.head {F.tail D}}}
   {Browse {F.head {F.tail {F.tail D}}}}
end

proc {RandomAccessListTest F}
   A = F.empty
   B = {F.cons 1 A}
   C = {F.cons 3 B}
   D = {F.cons 5 C}
   X = {F.update 0 7 D}
   Y = {F.update 2 9 X}
in
   {Browse D}
   {Browse {F.head D}}
   {Browse {F.head {F.tail D}}}
   {Browse {F.head {F.tail {F.tail D}}}}
   {Browse {F.lookup 0 Y}}
   {Browse {F.lookup 1 Y}}
   {Browse {F.lookup 2 Y}}
end

proc {CatenableListTest F}
   A = F.empty
   B = {F.cons 2 A}
   C = {F.snoc B 1}
   D = {F.cons 3 C}
   E = {F.append D {F.cons 4 F.empty}}
in
   {Browse D}
   {Browse {F.head D}}
   {Browse {F.head {F.tail D}}}
   {Browse {F.head {F.tail {F.tail D}}}}
   {Browse {F.head E}}
   {Browse {F.head {F.tail E}}}
   {Browse {F.head {F.tail {F.tail E}}}}
   {Browse {F.head {F.tail {F.tail {F.tail E}}}}}
end

% 10.1 AltBinaryRandomAccessList
ALTBINARYRANDOMACCESSLIST =
   functor
   export
      empty   : Empty
      isEmpty : IsEmpty
      cons    : Cons
      head    : Head
      tail    : Tail
      lookup  : Lookup
      update  : Update
   define
      Empty = nil
      fun {IsEmpty Xs} Xs == Empty end
      fun {ConsEP X Xs}
         case Xs
         of nil then one(X nil)
         [] zero(Ps) then one(X Ps)
         [] one(Y Ps) then zero({ConsEP pair(X Y) Ps})
         end
      end
      fun {Cons X Xs}
         {ConsEP elem(X) Xs}
      end
      fun {UnconsEP Xs}
         case Xs
         of nil then raise empty end
         [] one(X nil) then X#nil
         [] one(X Ps) then X#zero(Ps)
         [] zero(Ps) then
            local
               pair(X Y)#Psp = {UnconsEP Ps}
            in
               X#one(Y Psp)
            end
         end
      end
      fun {Head Xs}
         elem(X)#_ = {UnconsEP Xs}
      in
         X
      end
      fun {Tail Xs}
         _#Xsp = {UnconsEP Xs}
      in
         Xsp
      end
      fun {LookupEP I Xs}
         case I#Xs
         of _#nil then raise subscript end
         [] 0#one(X Ps) then X
         [] _#one(X Ps) then {LookupEP I-1 zero(Ps)}
         [] _#zero(Ps) then
            local
               pair(X Y) = {LookupEP (I div 2) Ps}
            in
               if I mod 2 == 0 then
                  X
               else
                  Y
               end
            end
         end
      end
      fun {Lookup I Xs}
         elem(X) = {LookupEP I Xs}
      in
         X
      end
      fun {Fupdate F I Xs}
         case I#Xs
         of _#nil then raise subscript end
         [] 0#one(X Ps) then one({F X} Ps)
         [] _#one(X Ps) then {ConsEP X {Fupdate F I-1 zero(Ps)}}
         [] _#zero(Ps) then
            local
               fun {Fp pair(X Y)}
                  if I mod 2 == 0 then
                     pair({F X} Y)
                  else
                     pair(X {F Y})
                  end
               end
            in
               zero({Fupdate Fp (I div 2) Ps})
            end
         end
      end
      fun {Update I Y Xs}
         {Fupdate fun {$ X} elem(Y) end I Xs}
      end
   end

[AltBinaryRandomAccessList] = {Module.apply [ALTBINARYRANDOMACCESSLIST]}

{RandomAccessListTest AltBinaryRandomAccessList}

% 10.1 BootstrappedQueue
fun lazy {LazyReverse L}
   fun {Iter L1 L2}
      case L1
      of H|T then {Iter T H|L2}
      [] nil then L2
      end
   end
in
   {Iter L nil}
end

BOOTSTRAPPEDQUEUE =
   functor
   export
      empty   : Empty
      isEmpty : IsEmpty
      snoc    : Snoc
      head    : Head
      tail    : Tail
   define
      Empty = nil
      fun {IsEmpty Q} Q == Empty end
      fun {CheckQ Q=LenFM#F#M#LenR#R}
         if LenR =< LenFM then
            {CheckF Q}
         else
            {CheckF (LenFM+LenR)#F#{SnocEL M {LazyReverse R}}#0#nil}
         end
      end
      fun {CheckF Q}
         case Q
         of LenFM#nil#nil#LenR#R then nil
         [] LenFM#nil#M#LenR#R then
            local
               F = {HeadEL M}
            in
               q(LenFM#F#{Tail M}#LenR#R)
            end
         else q(Q)
         end
      end
      fun {SnocEL Q X}
         case Q
         of nil then q(1#[X]#nil#0#nil)
         [] q(LenFM#F#M#LenR#R) then {CheckQ LenFM#F#M#LenR+1#(X|R)}
         end
      end
      fun {HeadEL Q}
         case Q
         of nil then raise empty end
         [] q(LenFM#(X|Fp)#M#LenR#R) then X
         end
      end
      fun {Tail Q}
         case Q
         of nil then raise empty end
         [] q(LenFM#(X|Fp)#M#LenR#R) then {CheckQ (LenFM-1)#Fp#M#LenR#R}
         end
      end
      fun {Snoc Q X}
         {SnocEL Q elem(X)}
      end
      fun {Head Q}
         elem(X) = {HeadEL Q}
      in
         X
      end
   end

[BootstrappedQueue] = {Module.apply [BOOTSTRAPPEDQUEUE]}

{QueueTest BootstrappedQueue}

% 10.2 CatenableList
CATENABLELIST =
   functor
   export
      initialize : Initialize
      empty      : Empty
      isEmpty    : IsEmpty
      cons       : Cons
      snoc       : Snoc
      append     : Append
      head       : Head
      tail       : Tail
   define
      Queue
      proc {Initialize Q} Queue = Q end
      Empty = nil
      fun {IsEmpty L} L == Empty end
      fun {Link c(X Q) S}
         c(X {Queue.snoc Q S})
      end
      fun {LinkAll Q}
         T = {Queue.head Q}
         Qp = {Queue.tail Q}
      in
         if {Queue.isEmpty Qp} then
            T
         else
            {Link T {fun lazy {$} {LinkAll Qp} end}}
         end
      end
      fun {Append Xs Ys}
         case Xs#Ys
         of _#nil then Xs
         [] nil#_ then Ys
         else {Link Xs Ys}
         end
      end
      fun {Cons X Xs}
         {Append c(X Queue.empty) Xs}
      end
      fun {Snoc Xs X}
         {Append Xs c(X Queue.empty)}
      end
      fun {Head L}
         case L
         of nil then raise empty end
         [] c(X _) then X
         end
      end
      fun {Tail L}
         case L
         of nil then raise empty end
         [] c(X Q) then
            if {Queue.isEmpty Q} then
               nil
            else
               {LinkAll Q}
            end
         end
      end
   end

[CatenableList] = {Module.apply [CATENABLELIST]}
{CatenableList.initialize BootstrappedQueue}

{CatenableListTest CatenableList}

% 10.2 BootstrapHeap
BOOTSTRAPHEAP =
   functor
   export
      initialize : Initialize
      empty      : Empty
      isEmpty    : IsEmpty
      insert     : Insert
      merge      : Merge
      findMin    : FindMin
      deleteMin  : DeleteMin
   define
      Element
      PrimH
      BOOTSTRAPPEDELEM =
         functor
         export
            eq : EQ
            lt : LT
            leq : LEQ
         define
            fun {EQ heap(X _) heap(Y _)} {Element.eq X Y} end
            fun {LT heap(X _) heap(Y _)} {Element.lt X Y} end
            fun {LEQ heap(X _) heap(Y _)} {Element.leq X Y} end
         end
      proc {Initialize HEAP OrderedSet}
         [BootstrappedElem] = {Module.apply [BOOTSTRAPPEDELEM]}
         [Heap] = {Module.apply [HEAP]}
      in
         {Heap.initialize BootstrappedElem}
         PrimH = Heap
         Element = OrderedSet
      end
      Empty = nil
      fun {IsEmpty Heap} Heap == Empty end
      fun {Merge Heap1 Heap2}
         case Heap1#Heap2
         of nil#_ then Heap2
         [] _#nil then Heap1
         [] heap(X P1)#heap(Y P2) then
            if {Element.leq X Y} then
               heap(X {PrimH.insert Heap2 P1})
            else
               heap(Y {PrimH.insert Heap1 P2})
            end
         end
      end
      fun {Insert X Heap}
         {Merge heap(X PrimH.empty) Heap}
      end
      fun {FindMin Heap}
         case Heap
         of nil then raise empty end
         [] heap(X _) then X
         end
      end
      fun {DeleteMin Heap}
         case Heap
         of nil then raise empty end
         [] heap(X P) then
            if {PrimH.isEmpty P} then
               nil
            else
               local
                  heap(Y P1) = {PrimH.findMin P}
                  P2 = {PrimH.deleteMin P}
               in
                  heap(Y {PrimH.merge P1 P2})
               end
            end
         end
      end
   end

[BootstrapHeap] = {Module.apply [BOOTSTRAPHEAP]}
{BootstrapHeap.initialize PAIRINGHEAP OrderedValue}

{HeapTest BootstrapHeap}

% 10.2 Trie
TRIE =
   functor
   export
      initialize : Initialize
      empty      : Empty
      bind       : Bind
      lookup     : Lookup
   define
      Map
      Empty
      proc {Initialize FiniteMap}
         Map = FiniteMap
         Empty = trie(nil Map.empty)
      end
      fun {Lookup L Trie}
         case L#Trie
         of nil#trie(nil M) then raise notFound end
         [] nil#trie(X M) then X
         [] (H|T)#trie(X M) then {Lookup T {Map.lxookup H M}}
         end
      end
      fun {Bind L X Trie}
         case L#Trie
         of nil#trie(_ M) then trie(X M)
         [] (H|T)#trie(V M) then
            local
               Tr = try {M.lookup H M} catch notFound then nil end
               Tp = {Bind T X Tr}
            in
               trie(V {M.bind H Tp M})
            end
         end
      end
   end

[Trie] = {Module.apply [TRIE]}
%{Trie.initialize ???}

%{FiniteMapTest Trie}

% 10.3 TrieOfTrees
TRIEOFTREES =
   functor
   export
      initialize : Initialize
      empty      : Empty
      bind       : Bind
      lookup     : Lookup
   define
      Map
      Empty
      proc {Initialize FiniteMap}
         Map = FiniteMap
         Empty = trie(nil Map.empty)
      end

      fun {LookupEM T Trie}
         case T#Trie
         of nil#trie(nil M) then raise notFound end
         [] nil#trie(X M) then X
         [] t(K A B)#trie(V M) then
            local
               map(Mp) = {LookupEM A {Map.lookup K M}}
            in
               {LookupEM B Mp}
            end
         end
      end
      fun {Lookup T Trie}
         elem(X) = {LookupEM T Trie}
      in
         X
      end
      fun {BindEM T X Trie}
         case T#Trie
         of nil#trie(_ M) then trie(X M)
         [] t(K A B)#trie(V M) then
            local
               Tt = try {Map.lookup K M} catch notFound then nil end
               Tx = try {LookupEM A Tt} catch notFound then map(nil) end
               Tp = {BindEM B X Tx}
               Ttp = {BindEM A map(Tp) Tt}
            in
               trie(V {Map.bind K Ttp M})
            end
         end
      end
      fun {Bind T X Trie}
         {BindEM T elem(X) Trie}
      end
   end

[TrieOfTrees] = {Module.apply [TRIEOFTREES]}
%{TrieOfTrees.initialize ???}

%{FiniteMapTest TrieOfTrees}

Chris Rathman / Chris.Rathman@tx.rr.com