1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162open!Basetype'at={compare:'a->'a->int;equal:'a->'a->bool}letcreate_m(typea)(moduleM:Base.Comparable.Swithtypet=a)={compare=M.compare;equal=M.equal};;letunmap{equal;compare}~f={compare=(funab->Comparable.liftcompare~fab);equal=(funab->Comparable.liftequal~fab)};;moduleExport=structletcomparison_int=create_m(moduleInt)letcomparison_list{compare;equal}={compare=List.comparecompare;equal=List.equalequal};;endmoduleIgnore=structtypet=Ignoreend(* Because [equal] and [compare] are extensional properties of a type -- they only care
about the contents of values, not syntax such as field names -- we can derive [t] using
the [Of_basic] functor. *)includePpx_derive_at_runtime_lib.Of_basic(structtypenonrec'at='attype_attribute=Ignore.tletunit=create_m(moduleUnit)letnothing=create_m(moduleNothing)letmap_unmapt~to_:_~of_:f=unmapt~fletboth(typeab){compare=compare_a;equal=equal_a}{compare=compare_b;equal=equal_b}={compare=[%compare:a*b];equal=[%equal:a*b]};;leteitherab={compare=Either.comparea.compareb.compare;equal=Either.equala.equalb.equal};;letwith_attribute_Ignore.Ignore={compare=(fun__->0);equal=(fun__->true)};;letrecursivelazy_t={compare=(funxy->(forcelazy_t).comparexy);equal=(funxy->(forcelazy_t).equalxy)};;end)