I annotate the class a bit:
-- The functional dependency here ties in to the issues with -- restricted type class instances, for which there is no one -- globally adopted solution. class Set set a | set -> a where -- This is a `Monoid`- or `Alternative`-like constant empty :: set -- This is an `Applicative`-like operation singleton :: a -> set -- If you have `singleton` and `union` you have `insert`. -- Which means that `insert` might fall out of the -- `Alternative` class. insert :: a -> set -> set -- This looks like a variant of `filter` below. delete :: a -> set -> set -- These two are `Semigroup` operations union :: set -> set -> set intersection :: set -> set -> set -- Can't think of anything for this one. member :: a -> set -> Bool -- This is very `Monad`-like operation. You can write this -- in terms of a bind/`unionMap` operation + your `singleton` -- and `empty`. filter :: (a -> Bool) -> set -> set
Thus, the community prefers many small classes that are more reusable than this Set class.
Here is another point that may be helpful. You seem to mentally associate classes with types, as a mental classification of types that are similar because they “represent sets”. But the Haskell community more often associates classes with operations . You can see this in the annotation above, I hope most of the operations you offer remind me of an existing class. The black label is the fact that most of these classes will not work with a type of type Set , which has an element type constraint ...
source share