12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455open!Coreopen!Import(* This type represents a combination of static and dynamic data. When only one is
present, the representation is straightforward, but when both are present, we use the
[Join] constructor. [Join] contains the dynamic portion as a single incremental node
(which probably contains a tuple-tree built up with several [both] nodes), and the
static portion is contained implicitly within the function, call it [f]. [f] rearranges
the ['a] by inserting all the pieces of static data into their appropriates places in
the tuple tree. *)type'inputt=|Dynamic:'inputIncr.t->'inputt|Static:'input->'inputt|Join:'aIncr.t*('a->'b)->'btletdynamicinput=Dynamicinputletstatic=Static()letstatic_dummy_for_assoccmp=Static(Map.emptycmp)letstatic_dummy_for_switch=Static(Meta.Input.Hidden.T{input=();type_id=Meta.Input.unit;key=0});;letmapt~f=matchtwith|Dynamicinput->Dynamic(Incr.mapinput~f)|Staticinput->Static(finput)|Join(input,g)->Join(input,funx->f(gx));;letiter_incremental(typey)(t:yt)~f=matchtwith|Static_->()|Join(incr,_)->f(Incr.packincr)|Dynamicincr->f(Incr.packincr);;letto_incremental=function|Dynamicinput->input|Staticinput->Incr.returninput|Join(incr,f)->Incr.mapincr~f;;letmergeab=matcha,bwith|Dynamica,Dynamicb->Dynamic(Incr.bothab)|Dynamica,Staticb->Join(a,funa->a,b)|Statica,Dynamicb->Join(b,funb->a,b)|Statica,Staticb->Static(a,b)|Dynamica,Join(b,f)->Join(Incr.bothab,fun(a,b)->a,fb)|Statica,Join(b,f)->Join(b,funb->a,fb)|Join(a,f),Staticb->Join(a,funa->fa,b)|Join(a,f),Dynamicb->Join(Incr.bothab,fun(a,b)->fa,b)|Join(a,f),Join(b,g)->Join(Incr.bothab,fun(a,b)->fa,gb);;