12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758moduleMake(T:sigtype'atvalcompare:'at->'at->intend)=structtype('a,'b)t=|Leaf|Nodeof('a,'b)t*'aT.t*'b*('a,'b)t*intletempty=Leafletsingletonkv=Node(Leaf,k,v,Leaf,1)letrank=functionLeaf->0|Node(_,_,_,_,r)->rletrecmerget1t2=matcht1,t2with|Leaf,t|t,Leaf->t|Node(l1,k1,v1,r1,_),Node(l2,k2,v2,r2,_)->ifT.comparek1k2>0thenmerge_ltl2k2v2r2t1elsemerge_ltl1k1v1r1t2andmerge_ltlkvrt2=letmerged=mergert2in(* always merge with right *)letrank_left=ranklandrank_right=rankmergedinifrank_left>=rank_rightthenNode(l,k,v,merged,rank_right+1)elseNode(merged,k,v,l,rank_left+1)(* left becomes right due to being shorter *)letinsertkvt=merge(singletonkv)tletpop=function|Leaf->None|Node(l,k,v,r,_)->Some(k,v,mergelr)type('a,'b)pop2=|Headof'aT.t*'b*'aT.t*'b*('a,'b)t|Tailof'aT.t*'b|Doneletpop2=function|Leaf->Done|Node(Leaf,k,v,_,_)->Tail(k,v)|Node(Node(ll,lk,lv,lr,_),k,v,Leaf,_)->Head(k,v,lk,lv,mergelllr)|Node((Node(ll,lk,lv,lr,_)asl),k,v,(Node(rl,rk,rv,rr,_)asr),_)->ifT.comparelkrk<=0thenHead(k,v,lk,lv,merge(mergelllr)r)elseHead(k,v,rk,rv,merge(mergerlrr)l)end