open Common open Ocollection class virtual ['a] oset = object(o: 'o) inherit ['a] ocollection (* no need virtual, but better to redefine (efficiency) *) method virtual union: 'o -> 'o method virtual inter: 'o -> 'o method virtual minus: 'o -> 'o (* allow binary methods tricks, generate exception when not good type *) method tosetb: 'a Setb.t = raise Impossible method tosetpt: SetPt.t = raise Impossible method toseti: Seti.seti = raise Impossible method virtual toset: 'b. 'b (* generic (not safe) tricks *) (* is_intersect, equal, subset *) method is_subset_of: 'o -> bool = fun o2 -> ((o2#minus o)#cardinal >= 0) && ((o#minus o2)#cardinal =|= 0) method is_equal: 'o -> bool = fun o2 -> ((o2#minus o)#cardinal =|= 0) && ((o#minus o2)#cardinal =|= 0) method is_singleton: bool = (* can be short circuited *) o#length =|= 1 method cardinal: int = (* just to keep naming conventions *) o#length (* dont work: method big_union: 'b. ('a -> 'b oset) -> 'b oset = fun f -> todo() *) end let ($??$) e xs = xs#mem e let ($++$) xs ys = xs#union ys let ($**$) xs ys = xs#inter ys let ($--$) xs ys = xs#minus ys let ($<<=$) xs ys = xs#is_subset_of ys let ($==$) xs ys = xs#is_equal ys (* todo: pas beau le seed. I dont put the type otherwise have to * put explicit :> *) let (mapo: ('a -> 'b) -> 'b oset -> 'a oset -> 'b oset) = fun f seed xs -> xs#fold (fun acc x -> acc#add (f x)) seed