1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253(* Open type for unique type identifier *)type_type_id=..exceptionType_non_equal(* Module type for type-level identifier *)moduletypeId=sigtypettype_type_id+=Id:ttype_idend(* Helper type *)type'atype_carrier=T(* Type witness for type equality *)type'awitness=(moduleIdwithtypet='a)typekey=extension_constructortype(_,_)eq=Proof:('a,'a)eq(* Test type equality and, if true, return a proof *)let(=?)(typeu)(typev):uwitness->vwitness->(u,v)eqoption=fun(moduleU)(moduleV)->matchU.Idwith|V.Id->SomeProof|_->None(* Compute the term identifier associated to a type level identifier *)letid(typea)(moduleM:Idwithtypet=a)=[%extension_constructorM.Id](* Obj.extension? Brittle or not? *)(* Binding: pair an 'a value with an 'a witness and hides the type 'a *)typebinding=B:'awitness*'a->binding(* extract back an 'a value from a binding, if the witness is equal to the bound witness *)letextract:typea.awitness->binding->aoption=funwitness(B(witness',x))->matchwitness=?witness'with|SomeProof->Somex|None->None(* Same thing with an exception rather than an option *)letextract_exn:typea.awitness->binding->a=funwitness(B(witness',x))->matchwitness=?witness'with|SomeProof->x|None->raiseType_non_equal(* Create a new type witness *)letcreate(typeu)():uwitness=letmoduleK=structtypet=utype_type_id+=Id:ttype_idendin(moduleK:Idwithtypet=u)