Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module implements a way of tracking the contents of a Set
at the type level, and provides utilities for manipulating such sets.
The contents of a set are associated with a type parameter, e.g. s
, so that
whenever you see the same type parameter, you know you are working with the
same set. The type s
itself has no internal structure, rather it is merely
a skolem type variable (rank-2 polymorphism runST
trick)
introduced by Data.Reflection.
Warning
This module together with Data.Set rely on Eq
and Ord
instances being
lawful: that ==
is an equivalence relation, and that the Ord
operations
define a total order on the quotient defined by this equivalence relation; at
least for the subset of values that are actually encountered at runtime. If
this assumption is violated, this module may not be able to uphold its
invariants and may throw errors. In particular beware of NaN in Float
and
Double
.
Synopsis
- type KnownSet s a = Reifies s (Set a)
- type Set s a = Dict (KnownSet s a)
- data InSet (f :: Flavor) (s :: Type) = InSet
- data Flavor = Regular
- type Element s = Refined (InSet 'Regular s)
- revealPredicate :: forall s a. (Typeable a, Ord a, KnownSet s a) => Dict (Predicate (InSet 'Regular s) a)
- data SomeSet a where
- withSet :: forall a r. SomeSet a -> (forall s. KnownSet s a => Proxy s -> r) -> r
- data SomeSetWith p a where
- SomeSetWith :: forall s a p. KnownSet s a => !(p s) -> SomeSetWith p a
- withSetWith :: forall a r p. SomeSetWith p a -> (forall s. KnownSet s a => p s -> r) -> r
- data Some2SetWith p a where
- Some2SetWith :: forall s t a p. (KnownSet s a, KnownSet t a) => !(p s t) -> Some2SetWith p a
- with2SetWith :: forall a r p. Some2SetWith p a -> (forall s t. (KnownSet s a, KnownSet t a) => p s t -> r) -> r
- type (:->) p q = forall x. Refined p x -> Refined q x
- newtype SupersetProof f s r = SupersetProof (InSet f r :-> InSet f s)
- newtype EmptyProof f r = EmptyProof (forall s. InSet f r :-> InSet f s)
- empty :: forall a. SomeSetWith (EmptyProof 'Regular) a
- singleton :: forall a. a -> SomeSetWith (SingletonProof 'Regular a) a
- newtype SingletonProof f a r = SingletonProof (Refined (InSet f r) a)
- fromSet :: forall a. Set a -> SomeSet a
- fromTraversable :: forall t a. (Traversable t, Ord a) => t a -> SomeSetWith (FromTraversableProof 'Regular t a) a
- newtype FromTraversableProof f (t :: Type -> Type) a r = FromTraversableProof (t (Refined (InSet f r) a))
- insert :: forall s a. (Ord a, KnownSet s a) => a -> SomeSetWith (InsertProof 'Regular a s) a
- data InsertProof f a s r = InsertProof (Refined (InSet f r) a) (InSet f s :-> InSet f r)
- delete :: forall s a. (Ord a, KnownSet s a) => a -> SomeSetWith (SupersetProof 'Regular s) a
- member :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a)
- lookupLT :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a)
- lookupGT :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a)
- lookupLE :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a)
- lookupGE :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a)
- null :: forall s a. KnownSet s a => Maybe (EmptyProof 'Regular s)
- isSubsetOf :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => Maybe (SubsetProof 'Regular s t)
- newtype SubsetProof f s r = SubsetProof (InSet f s :-> InSet f r)
- disjoint :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => Maybe (DisjointProof 'Regular s t)
- newtype DisjointProof f s r = DisjointProof (forall t. (InSet f t :-> InSet f s) -> (InSet f t :-> InSet f r) -> forall u. InSet f t :-> InSet f u)
- union :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => SomeSetWith (UnionProof 'Regular s t) a
- data UnionProof f s t r = UnionProof ((InSet f s || InSet f t) :-> InSet f r) (forall u. (InSet f s :-> InSet f u) -> (InSet f t :-> InSet f u) -> InSet f r :-> InSet f u)
- difference :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => SomeSetWith (DifferenceProof 'Regular s t) a
- data DifferenceProof f s t r = DifferenceProof (InSet f r :-> InSet f s) (forall u. (InSet f u :-> InSet f r) -> (InSet f u :-> InSet f t) -> forall v. InSet f u :-> InSet f v) (InSet f s :-> (InSet f t || InSet f r))
- intersection :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => SomeSetWith (IntersectionProof 'Regular s t) a
- data IntersectionProof f s t r = IntersectionProof (InSet f r :-> (InSet f s && InSet f t)) (forall u. (InSet f u :-> InSet f s) -> (InSet f u :-> InSet f t) -> InSet f u :-> InSet f r)
- cartesianProduct :: forall s t a b. (KnownSet s a, KnownSet t b) => SomeSetWith (ProductProof 'Regular s t) (a, b)
- newtype ProductProof f s t r = ProductProof (forall a b. Coercion (Refined (InSet f s) a, Refined (InSet f t) b) (Refined (InSet f r) (a, b)))
- disjointUnion :: forall s t a b. (KnownSet s a, KnownSet t b) => SomeSetWith (CoproductProof 'Regular s t) (Either a b)
- newtype CoproductProof f s t r = CoproductProof (forall a b. Coercion (Either (Refined (InSet f s) a) (Refined (InSet f t) b)) (Refined (InSet f r) (Either a b)))
- filter :: forall s a. KnownSet s a => (Element s a -> Bool) -> SomeSetWith (SupersetProof 'Regular s) a
- partition :: forall s a. KnownSet s a => (Element s a -> Bool) -> Some2SetWith (PartitionProof 'Regular s a) a
- data PartitionProof f s a r q = PartitionProof (Refined (InSet f s) a -> Either (Refined (InSet f r) a) (Refined (InSet f q) a)) ((InSet f r || InSet f q) :-> InSet f s) (forall t. (InSet f r :-> InSet f t) -> (InSet f q :-> InSet f t) -> InSet f s :-> InSet f t) (forall t. (InSet f t :-> InSet f r) -> (InSet f t :-> InSet f q) -> forall u. InSet f t :-> InSet f u)
- spanAntitone :: forall s a. KnownSet s a => (Element s a -> Bool) -> Some2SetWith (PartialPartitionProof 'Regular s) a
- data PartialPartitionProof f s r q = PartialPartitionProof ((InSet f r || InSet f q) :-> InSet f s) (forall t. (InSet f r :-> InSet f t) -> (InSet f q :-> InSet f t) -> InSet f s :-> InSet f t) (forall t. (InSet f t :-> InSet f r) -> (InSet f t :-> InSet f q) -> forall u. InSet f t :-> InSet f u)
- splitMember :: forall s a. (Ord a, KnownSet s a) => a -> Some2SetWith (SplitProof 'Regular s (Element s a)) a
- data SplitProof f s e r q = SplitProof !(Maybe e) ((InSet f r || InSet f q) :-> InSet f s) (forall t. (InSet f t :-> InSet f r) -> (InSet f t :-> InSet f q) -> forall u. InSet f t :-> InSet f u)
- map :: forall s a b. (Ord b, KnownSet s a) => (Element s a -> b) -> SomeSetWith (MapProof 'Regular s a b) b
- data MapProof f s a b r = MapProof (Refined (InSet f s) a -> Refined (InSet f r) b) (Refined (InSet f r) b -> Refined (InSet f s) a)
- foldMap :: forall s a m. (KnownSet s a, Monoid m) => (Element s a -> m) -> m
- foldr :: forall s a b. KnownSet s a => (Element s a -> b -> b) -> b -> b
- foldl :: forall s a b. KnownSet s a => (b -> Element s a -> b) -> b -> b
- foldr' :: forall s a b. KnownSet s a => (Element s a -> b -> b) -> b -> b
- foldl' :: forall s a b. KnownSet s a => (b -> Element s a -> b) -> b -> b
- minView :: forall s a. KnownSet s a => Either (EmptyProof 'Regular s) (Element s a, SomeSetWith (SupersetProof 'Regular s) a)
- maxView :: forall s a. KnownSet s a => Either (EmptyProof 'Regular s) (Element s a, SomeSetWith (SupersetProof 'Regular s) a)
- toList :: forall s a. KnownSet s a => [Element s a]
- toDescList :: forall s a. KnownSet s a => [Element s a]
- asIntSet :: forall s. KnownSet s Int => IntSet s
- asHashSet :: forall s a. (Hashable a, KnownSet s a) => HashSet s a
- castElement :: forall s t a. (forall x. Element s x -> Element t x) -> (forall x. Element t x -> Element s x) -> Coercion (Element s a) (Element t a)
- cast :: forall s t a. (forall x. Coercion (Element s x) (Element t x)) -> Coercion (Set s a) (Set t a)
- castFlavor :: forall (f :: Flavor) (g :: Flavor) s a. Coercion (Refined (InSet f s) a) (Refined (InSet g s) a)
Set type
Refinement type
data InSet (f :: Flavor) (s :: Type) Source #
A predicate for use with Refined, verifying that a value is an element of
the set s
.
Instances
(Hashable a, Typeable s, KnownHashSet s a) => Predicate (InSet 'Hashed s :: Type) a Source # | See |
Defined in Data.Container.Refined.Proofs | |
(a ~ Int, Typeable s, KnownIntSet s) => Predicate (InSet 'Int s :: Type) a Source # | See |
Defined in Data.Container.Refined.Proofs | |
(Ord a, Typeable s, KnownSet s a) => Predicate (InSet 'Regular s :: Type) a Source # | See |
Defined in Data.Container.Refined.Proofs | |
FoldableWithIndex (Key s) (IntMap s) Source # | |
Defined in Data.IntMap.Common.Refined ifoldMap :: Monoid m => (Key s -> a -> m) -> IntMap s a -> m # ifoldMap' :: Monoid m => (Key s -> a -> m) -> IntMap s a -> m # ifoldr :: (Key s -> a -> b -> b) -> b -> IntMap s a -> b # ifoldl :: (Key s -> b -> a -> b) -> b -> IntMap s a -> b # | |
FunctorWithIndex (Key s) (IntMap s) Source # | |
TraversableWithIndex (Key s) (IntMap s) Source # | |
Defined in Data.IntMap.Common.Refined | |
KnownIntSet s => MonadReader (Key s) (IntMap s) Source # | Similar to the instance for functions. See also
|
FoldableWithIndex (Key s k) (HashMap s k) Source # | |
Defined in Data.HashMap.Common.Refined ifoldMap :: Monoid m => (Key s k -> a -> m) -> HashMap s k a -> m # ifoldMap' :: Monoid m => (Key s k -> a -> m) -> HashMap s k a -> m # ifoldr :: (Key s k -> a -> b -> b) -> b -> HashMap s k a -> b # ifoldl :: (Key s k -> b -> a -> b) -> b -> HashMap s k a -> b # ifoldr' :: (Key s k -> a -> b -> b) -> b -> HashMap s k a -> b # ifoldl' :: (Key s k -> b -> a -> b) -> b -> HashMap s k a -> b # | |
FoldableWithIndex (Key s k) (Map s k) Source # | |
Defined in Data.Map.Common.Refined ifoldMap :: Monoid m => (Key s k -> a -> m) -> Map s k a -> m # ifoldMap' :: Monoid m => (Key s k -> a -> m) -> Map s k a -> m # ifoldr :: (Key s k -> a -> b -> b) -> b -> Map s k a -> b # ifoldl :: (Key s k -> b -> a -> b) -> b -> Map s k a -> b # ifoldr' :: (Key s k -> a -> b -> b) -> b -> Map s k a -> b # ifoldl' :: (Key s k -> b -> a -> b) -> b -> Map s k a -> b # | |
FunctorWithIndex (Key s k) (HashMap s k) Source # | |
FunctorWithIndex (Key s k) (Map s k) Source # | |
TraversableWithIndex (Key s k) (HashMap s k) Source # | |
Defined in Data.HashMap.Common.Refined | |
TraversableWithIndex (Key s k) (Map s k) Source # | |
Defined in Data.Map.Common.Refined | |
(Hashable k, KnownHashSet s k) => MonadReader (Key s k) (HashMap s k) Source # | Similar to the instance for functions. See also
|
(Ord k, KnownSet s k) => MonadReader (Key s k) (Map s k) Source # | Similar to the instance for functions. See also
|
type Element s = Refined (InSet 'Regular s) Source #
is a value of type Element
s aa
that has been verified to be an
element of s
.
Thus,
is a "refinement" type of Element
s aa
, and this library
integrates with an implementation of refimenement types in Refined, so
the machinery from there can be used to manipulate Element
s (however see
revealPredicate
).
The underlying a
value can be obtained with unrefine
. An a
can be
validated into an
with Element
s amember
.
revealPredicate :: forall s a. (Typeable a, Ord a, KnownSet s a) => Dict (Predicate (InSet 'Regular s) a) Source #
To use Refined machinery that uses the Predicate
typeclass you will
need to pattern match on this Dict
.
The reason is that in the default fast implementation of reflection, we
don't have
, which Refined wants for pretty-printing
exceptions. We can provide Typeable
s
, but at the cost of using the
slow implementation of reflection.Typeable
s
Existentials and common proofs
data SomeSetWith p a where Source #
An existential wrapper for an as-yet-unknown set, together with a proof of
some fact p
about the set. Pattern matching on it gives you a way to refer
to the set (the parameter s
). Most functions will return a set in this way,
together with a proof that somehow relates the set to the function's inputs.
SomeSetWith :: forall s a p. KnownSet s a => !(p s) -> SomeSetWith p a |
withSetWith :: forall a r p. SomeSetWith p a -> (forall s. KnownSet s a => p s -> r) -> r Source #
Apply an unknown set with proof to a continuation that can accept any set
satisfying the proof. This gives you a way to refer to the set (the parameter
s
).
data Some2SetWith p a where Source #
An existential wrapper for an as-yet-unknown pair of sets, together with
a proof of some fact p
relating them.
Some2SetWith :: forall s t a p. (KnownSet s a, KnownSet t a) => !(p s t) -> Some2SetWith p a |
with2SetWith :: forall a r p. Some2SetWith p a -> (forall s t. (KnownSet s a, KnownSet t a) => p s t -> r) -> r Source #
Apply a pair of unknown sets with proof to a continuation that can accept
any pair of sets satisfying the proof. This gives you a way to refer to the
sets (the parameters s
and t
).
newtype SupersetProof f s r Source #
Proof that s
is a superset of the set r
.
SupersetProof (InSet f r :-> InSet f s) | \(r \subseteq s\) |
newtype EmptyProof f r Source #
Proof that the set r
is empty.
EmptyProof (forall s. InSet f r :-> InSet f s) | \(\forall s, r \subseteq s\), which is equivalent to \(r \subseteq \varnothing\) |
Construction
empty :: forall a. SomeSetWith (EmptyProof 'Regular) a Source #
An empty set.
singleton :: forall a. a -> SomeSetWith (SingletonProof 'Regular a) a Source #
Create a set with a single element.
newtype SingletonProof f a r Source #
Proof that r
contains an element of type a
.
SingletonProof (Refined (InSet f r) a) | The element that is guaranteed to be in |
fromTraversable :: forall t a. (Traversable t, Ord a) => t a -> SomeSetWith (FromTraversableProof 'Regular t a) a Source #
Create a set from the elements of an arbitrary traversable.
newtype FromTraversableProof f (t :: Type -> Type) a r Source #
Proof that elements of t a
are contained in r
.
FromTraversableProof (t (Refined (InSet f r) a)) | The original traversable, with all elements refined with a guarantee of
being in |
Insertion
insert :: forall s a. (Ord a, KnownSet s a) => a -> SomeSetWith (InsertProof 'Regular a s) a Source #
Insert an element in a set.
data InsertProof f a s r Source #
Proof that r
is s
with a
inserted.
Deletion
delete :: forall s a. (Ord a, KnownSet s a) => a -> SomeSetWith (SupersetProof 'Regular s) a Source #
Delete an element from a set.
Query
member :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a) Source #
If an element is in the set, return the proof that it is.
lookupLT :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a) Source #
Find the largest element smaller than the given one.
lookupGT :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a) Source #
Find the smallest element greater than the given one.
lookupLE :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a) Source #
Find the largest element smaller or equal to the given one.
lookupGE :: forall s a. (Ord a, KnownSet s a) => a -> Maybe (Element s a) Source #
Find the smallest element greater or equal to the given one.
null :: forall s a. KnownSet s a => Maybe (EmptyProof 'Regular s) Source #
If the set is empty, return the proof that it is.
isSubsetOf :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => Maybe (SubsetProof 'Regular s t) Source #
If s
is a subset of t
(or is equal to), return a proof of that.
newtype SubsetProof f s r Source #
Proof that s
is a subset of the set r
.
SubsetProof (InSet f s :-> InSet f r) | \(s \subseteq r\) |
disjoint :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => Maybe (DisjointProof 'Regular s t) Source #
If s
and t
are disjoint (i.e. their intersection is empty), return a
proof of that.
newtype DisjointProof f s r Source #
Proof that s
and r
are disjoint.
Combine
union :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => SomeSetWith (UnionProof 'Regular s t) a Source #
The union of two sets.
data UnionProof f s t r Source #
Proof that unioning s
and t
gives r
.
difference :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => SomeSetWith (DifferenceProof 'Regular s t) a Source #
Set with elements of s
that are not in t
.
data DifferenceProof f s t r Source #
Proof that if from s
you subtract t
, then you get r
.
DifferenceProof | |
|
intersection :: forall s t a. (Ord a, KnownSet s a, KnownSet t a) => SomeSetWith (IntersectionProof 'Regular s t) a Source #
Intersection of two sets.
data IntersectionProof f s t r Source #
Proof that intersecting s
and t
gives r
.
cartesianProduct :: forall s t a b. (KnownSet s a, KnownSet t b) => SomeSetWith (ProductProof 'Regular s t) (a, b) Source #
Cartesian product of two sets. The elements are all pairs (x, y)
for each
x
from s
and for each y
from t
.
newtype ProductProof f s t r Source #
Proof that the cartesian product of s
and t
is r
.
ProductProof (forall a b. Coercion (Refined (InSet f s) a, Refined (InSet f t) b) (Refined (InSet f r) (a, b))) | A pair of elements from |
disjointUnion :: forall s t a b. (KnownSet s a, KnownSet t b) => SomeSetWith (CoproductProof 'Regular s t) (Either a b) Source #
newtype CoproductProof f s t r Source #
Proof that the tagged disjoint union of s
and t
is r
.
CoproductProof (forall a b. Coercion (Either (Refined (InSet f s) a) (Refined (InSet f t) b)) (Refined (InSet f r) (Either a b))) | Coproduct of elements of |
Filter
filter :: forall s a. KnownSet s a => (Element s a -> Bool) -> SomeSetWith (SupersetProof 'Regular s) a Source #
Return a subset of elements that satisfy the given predicate.
partition :: forall s a. KnownSet s a => (Element s a -> Bool) -> Some2SetWith (PartitionProof 'Regular s a) a Source #
Partition a set into two disjoint subsets: those that satisfy the predicate, and those that don't.
data PartitionProof f s a r q Source #
Proof that s
is the union of disjoint subsets r
and q
, together with
a procedure that decides which of the two an element belongs to.
PartitionProof | |
|
spanAntitone :: forall s a. KnownSet s a => (Element s a -> Bool) -> Some2SetWith (PartialPartitionProof 'Regular s) a Source #
Divide a set into two disjoint subsets at a point where the predicate stops holding.
If p
is antitone ( \(\forall x y, x < y \implies p(x) \ge p(y)\) ), then
this point is uniquely defined. If p
is not antitone, a splitting point is
chosen in an unspecified way.
data PartialPartitionProof f s r q Source #
Proof that s
is the union of disjoint subsets r
and q
, but without a
deciding procedure.
PartialPartitionProof | |
|
splitMember :: forall s a. (Ord a, KnownSet s a) => a -> Some2SetWith (SplitProof 'Regular s (Element s a)) a Source #
Return two disjoint subsets: those less than the given element, and those greater than the given element; along with the proof that the given element was in the set, if it was.
data SplitProof f s e r q Source #
Proof that s
contains disjoint subsets r
and q
, along with an
optional element between them.
SplitProof | |
|
Map
map :: forall s a b. (Ord b, KnownSet s a) => (Element s a -> b) -> SomeSetWith (MapProof 'Regular s a b) b Source #
Apply the given function to each element of the set and collect the results. Note that the resulting set can be smaller.
data MapProof f s a b r Source #
Proof that r
is the direct image of s
under some mapping f :: a -> b
.
Folds
foldMap :: forall s a m. (KnownSet s a, Monoid m) => (Element s a -> m) -> m Source #
Map each element of s
into a monoid (with proof that it was an element),
and combine the results using <>
.
foldr :: forall s a b. KnownSet s a => (Element s a -> b -> b) -> b -> b Source #
Right associative fold with a lazy accumulator.
foldl :: forall s a b. KnownSet s a => (b -> Element s a -> b) -> b -> b Source #
Left associative fold with a lazy accumulator.
foldr' :: forall s a b. KnownSet s a => (Element s a -> b -> b) -> b -> b Source #
Right associative fold with a strict accumulator.
foldl' :: forall s a b. KnownSet s a => (b -> Element s a -> b) -> b -> b Source #
Left associative fold with a strict accumulator.
Min/Max
minView :: forall s a. KnownSet s a => Either (EmptyProof 'Regular s) (Element s a, SomeSetWith (SupersetProof 'Regular s) a) Source #
Retrieves the smallest element of the set, and the set with that element removed; or a proof that the set was empty.
maxView :: forall s a. KnownSet s a => Either (EmptyProof 'Regular s) (Element s a, SomeSetWith (SupersetProof 'Regular s) a) Source #
Retrieves the greatest element of the set, and the set with that element removed; or a proof that the set was empty.
Conversion
toList :: forall s a. KnownSet s a => [Element s a] Source #
List of elements in the set in ascending order.
toDescList :: forall s a. KnownSet s a => [Element s a] Source #
List of elements in the set in descending order.
asIntSet :: forall s. KnownSet s Int => IntSet s Source #
Convert a Set
into an IntSet
, retaining its set of elements, which can
be converted with castFlavor
.
asHashSet :: forall s a. (Hashable a, KnownSet s a) => HashSet s a Source #
Convert a Set
into a HashSet
, retaining its set of elements, which can
be converted with castFlavor
.
Casts
castElement :: forall s t a. (forall x. Element s x -> Element t x) -> (forall x. Element t x -> Element s x) -> Coercion (Element s a) (Element t a) Source #
If elements of s
can be weakened to elements of t
and vice versa, then
s
and t
actually stand for the same set and
can be safely
interconverted with Element
s
.Element
t
The requirement that the weakenings are natural transformations ensures that
they don't actually alter the elements. To build these you can compose
:->
's from proofs returned by functions in this module, or Refined
functions like andLeft
or leftOr
.
cast :: forall s t a. (forall x. Coercion (Element s x) (Element t x)) -> Coercion (Set s a) (Set t a) Source #
If elements can be interconverted (e.g. as proved by castElement
), then
the sets can be interconverted too. For example we can establish that the
intersection of a set with itself is interconvertible with that set:
castIntersection ::IntersectionProof
'Regular
s s r ->Coercion
(Set
r a) (Set
s a) castIntersection (IntersectionProof
p1 p2) =cast
$castElement
(andLeft
. p1) (p2id
id
)