12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576openHigher(** An attribute key is a value that can be used to attach polymorphic data to a
heterogeneous attribute map. *)moduletypeS1=sigtype'aattrtype'amaptype'at(** The type of data associated with the {!attr} attribute key. *)valadd:'at->'amap->'amap(** Attach data for {!attr} to a given map. *)valfind:'amap->'atoption(** Search for data corresponding to the key {!attr} in the given map. *)includeBranded.Swithtype'at:='atvalkey:brattrendmoduletypeAttribute=sigtype'ft(** An ['f t] is an attribute key that can be used to pack polymorphic data
into a heterogeneous {!Map} (and then recover it again).
The type parameter ['f] is the brand of a type operator [f : * ⇒ *] which,
when applied to the type parameter ['a] of a {!Map.t}, gives the type
['a f] of the associated data. This allows a single attribute key to store
{i polymorphic} data. *)valcreate:name:string->_t(** [create ~name] is a fresh attribute key with the given string name. *)valname:_t->string(** Get the string name of an attribute key. *)moduleMap:sigtype'fkey:='fttype'at(** The type of polymorphic, heterogeneous maps. *)type('a,'f)data:=('a,'f)app(** Given an ['a t] map and an ['f key] attribute key, the type of the
corresponding data is [('a, 'f) Higher.app]. *)valempty:_tvalis_empty:_t->boolvalmem:'at->'fkey->boolvaladd:'at->key:'fkey->data:('a,'f)data->'atvalupdate:'at->'fkey->(('a,'f)dataoption->('a,'f)dataoption)->'atvalsingleton:'fkey->('a,'f)data->'attype'abinding=B:'fkey*('a,'f)data->'abindingvaliter:'at->f:('abinding->unit)->unitvalfor_all:'at->f:('abinding->bool)->boolvalexists:'at->f:('abinding->bool)->boolvalcardinal:'at->intvalfind:'at->'fkey->('a,'f)dataoptionvalbindings:'at->'abindinglistendmoduletypeS1=S1withtype'aattr:='atandtype'amap:='aMap.tmoduleMake1(T:sigtype'atvalname:stringend):S1withtype'at='aT.tend