Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
This module implements a way of tracking the contents of an
IntSet
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.
Synopsis
- type KnownIntSet s = Reifies s IntSet
- type IntSet s = Dict (KnownIntSet s)
- data InSet (f :: Flavor) (s :: Type) = InSet
- data Flavor = Int
- type Element s = Refined (InSet 'Int s) Int
- revealPredicate :: forall s. KnownIntSet s => Dict (Predicate (InSet 'Int s) Int)
- data SomeIntSet where
- SomeIntSet :: forall s. KnownIntSet s => Proxy# s -> SomeIntSet
- withIntSet :: forall r. SomeIntSet -> (forall s. KnownIntSet s => Proxy s -> r) -> r
- data SomeIntSetWith p where
- SomeIntSetWith :: forall s p. KnownIntSet s => !(p s) -> SomeIntSetWith p
- withIntSetWith :: forall r p. SomeIntSetWith p -> (forall s. KnownIntSet s => p s -> r) -> r
- data Some2IntSetWith p where
- Some2IntSetWith :: forall s t p. (KnownIntSet s, KnownIntSet t) => !(p s t) -> Some2IntSetWith p
- with2IntSetWith :: forall r p. Some2IntSetWith p -> (forall s t. (KnownIntSet s, KnownIntSet t) => 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 :: SomeIntSetWith (EmptyProof 'Int)
- singleton :: Int -> SomeIntSetWith (SingletonProof 'Int Int)
- newtype SingletonProof f a r = SingletonProof (Refined (InSet f r) a)
- fromIntSet :: IntSet -> SomeIntSet
- fromTraversable :: forall t. Traversable t => t Int -> SomeIntSetWith (FromTraversableProof 'Int t Int)
- newtype FromTraversableProof f (t :: Type -> Type) a r = FromTraversableProof (t (Refined (InSet f r) a))
- insert :: forall s. KnownIntSet s => Int -> SomeIntSetWith (InsertProof 'Int Int s)
- data InsertProof f a s r = InsertProof (Refined (InSet f r) a) (InSet f s :-> InSet f r)
- delete :: forall s. KnownIntSet s => Int -> SomeIntSetWith (SupersetProof 'Int s)
- member :: forall s. KnownIntSet s => Int -> Maybe (Element s)
- lookupLT :: forall s. KnownIntSet s => Int -> Maybe (Element s)
- lookupGT :: forall s. KnownIntSet s => Int -> Maybe (Element s)
- lookupLE :: forall s. KnownIntSet s => Int -> Maybe (Element s)
- lookupGE :: forall s. KnownIntSet s => Int -> Maybe (Element s)
- null :: forall s. KnownIntSet s => Maybe (EmptyProof 'Int s)
- isSubsetOf :: forall s t. (KnownIntSet s, KnownIntSet t) => Maybe (SubsetProof 'Int s t)
- newtype SubsetProof f s r = SubsetProof (InSet f s :-> InSet f r)
- disjoint :: forall s t. (KnownIntSet s, KnownIntSet t) => Maybe (DisjointProof 'Int 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. (KnownIntSet s, KnownIntSet t) => SomeIntSetWith (UnionProof 'Int s t)
- 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. (KnownIntSet s, KnownIntSet t) => SomeIntSetWith (DifferenceProof 'Int s t)
- 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. (KnownIntSet s, KnownIntSet t) => SomeIntSetWith (IntersectionProof 'Int s t)
- 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)
- filter :: forall s. KnownIntSet s => (Element s -> Bool) -> SomeIntSetWith (SupersetProof 'Int s)
- partition :: forall s. KnownIntSet s => (Element s -> Bool) -> Some2IntSetWith (PartitionProof 'Int s Int)
- 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. KnownIntSet s => (Element s -> Bool) -> Some2IntSetWith (PartialPartitionProof 'Int s)
- 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. KnownIntSet s => Int -> Some2IntSetWith (SplitProof 'Int s (Element s))
- 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. KnownIntSet s => (Element s -> Int) -> SomeIntSetWith (MapProof 'Int s Int Int)
- 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 m. (KnownIntSet s, Monoid m) => (Element s -> m) -> m
- foldr :: forall s a. KnownIntSet s => (Element s -> a -> a) -> a -> a
- foldl :: forall s a. KnownIntSet s => (a -> Element s -> a) -> a -> a
- foldr' :: forall s a. KnownIntSet s => (Element s -> a -> a) -> a -> a
- foldl' :: forall s a. KnownIntSet s => (a -> Element s -> a) -> a -> a
- minView :: forall s. KnownIntSet s => Either (EmptyProof 'Int s) (Element s, SomeIntSetWith (SupersetProof 'Int s))
- maxView :: forall s. KnownIntSet s => Either (EmptyProof 'Int s) (Element s, SomeIntSetWith (SupersetProof 'Int s))
- toList :: forall s. KnownIntSet s => [Element s]
- toDescList :: forall s. KnownIntSet s => [Element s]
- asSet :: forall s. KnownIntSet s => Set s Int
- asHashSet :: forall s. KnownIntSet s => HashSet s Int
- castElement :: forall s t a. (forall x. Refined (InSet 'Int s) x -> Refined (InSet 'Int t) x) -> (forall x. Refined (InSet 'Int t) x -> Refined (InSet 'Int s) x) -> Coercion (Refined (InSet 'Int s) a) (Refined (InSet 'Int t) a)
- cast :: forall s t. (forall x. Coercion (Refined (InSet 'Int s) x) (Refined (InSet 'Int t) x)) -> Coercion (IntSet s) (IntSet t)
- castFlavor :: forall (f :: Flavor) (g :: Flavor) s a. Coercion (Refined (InSet f s) a) (Refined (InSet g s) a)
Set type
type KnownIntSet s = Reifies s IntSet Source #
type IntSet s = Dict (KnownIntSet s) Source #
A IntSet
whose contents are tracked by the type parameter
s
. This is a "singleton": for a given s
there's only one value of this
type.
Since this is just a Dict
, you can freely convert between the value
(IntSet
) and the constraint (KnownIntSet
). This library prefers to use
the constraint.
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
|
Disambiguate the choice of implementation for sets and maps.
type Element s = Refined (InSet 'Int s) Int Source #
is an Element
sInt
that has been verified to be an element of s
.
Thus,
is a "refinement" type of Element
sInt
, 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 Int
can be obtained with unrefine
. An Int
can be
validated into an
with Element
smember
.
revealPredicate :: forall s. KnownIntSet s => Dict (Predicate (InSet 'Int s) Int) 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.TypeableTypeable
s
Existentials and common proofs
data SomeIntSet where Source #
An existential wrapper for an as-yet-unknown set. Pattern maching on it gives you a way to refer to the set, e.g.
casefromIntSet
... ofSomeIntSet
@s _ -> doSomethingWith @s casefromIntSet
... ofSomeIntSet
(_ ::Proxy#
s) -> doSomethingWith @s
SomeIntSet :: forall s. KnownIntSet s => Proxy# s -> SomeIntSet |
withIntSet :: forall r. SomeIntSet -> (forall s. KnownIntSet s => Proxy s -> r) -> r Source #
Apply an unknown set to a continuation that can accept any set. This gives
you a way to refer to the set (the parameter s
), e.g.:
withIntSet
(fromIntSet
...) $ (_ ::Proxy
s) -> doSomethingWith @s
data SomeIntSetWith p 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.
SomeIntSetWith :: forall s p. KnownIntSet s => !(p s) -> SomeIntSetWith p |
withIntSetWith :: forall r p. SomeIntSetWith p -> (forall s. KnownIntSet s => 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 Some2IntSetWith p where Source #
An existential wrapper for an as-yet-unknown pair of sets, together with
a proof of some fact p
relating them.
Some2IntSetWith :: forall s t p. (KnownIntSet s, KnownIntSet t) => !(p s t) -> Some2IntSetWith p |
with2IntSetWith :: forall r p. Some2IntSetWith p -> (forall s t. (KnownIntSet s, KnownIntSet t) => 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 :: SomeIntSetWith (EmptyProof 'Int) Source #
An empty set.
singleton :: Int -> SomeIntSetWith (SingletonProof 'Int Int) 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 |
fromIntSet :: IntSet -> SomeIntSet Source #
Construct a set from a regular IntSet
.
fromTraversable :: forall t. Traversable t => t Int -> SomeIntSetWith (FromTraversableProof 'Int t Int) 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. KnownIntSet s => Int -> SomeIntSetWith (InsertProof 'Int Int s) 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. KnownIntSet s => Int -> SomeIntSetWith (SupersetProof 'Int s) Source #
Delete an element from a set.
Query
member :: forall s. KnownIntSet s => Int -> Maybe (Element s) Source #
If an element is in the set, return the proof that it is.
lookupLT :: forall s. KnownIntSet s => Int -> Maybe (Element s) Source #
Find the largest element smaller than the given one.
lookupGT :: forall s. KnownIntSet s => Int -> Maybe (Element s) Source #
Find the smallest element greater than the given one.
lookupLE :: forall s. KnownIntSet s => Int -> Maybe (Element s) Source #
Find the largest element smaller or equal to the given one.
lookupGE :: forall s. KnownIntSet s => Int -> Maybe (Element s) Source #
Find the smallest element greater or equal to the given one.
null :: forall s. KnownIntSet s => Maybe (EmptyProof 'Int s) Source #
If the set is empty, return the proof that it is.
isSubsetOf :: forall s t. (KnownIntSet s, KnownIntSet t) => Maybe (SubsetProof 'Int 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. (KnownIntSet s, KnownIntSet t) => Maybe (DisjointProof 'Int 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. (KnownIntSet s, KnownIntSet t) => SomeIntSetWith (UnionProof 'Int s t) 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. (KnownIntSet s, KnownIntSet t) => SomeIntSetWith (DifferenceProof 'Int s t) 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. (KnownIntSet s, KnownIntSet t) => SomeIntSetWith (IntersectionProof 'Int s t) Source #
Intersection of two sets.
data IntersectionProof f s t r Source #
Proof that intersecting s
and t
gives r
.
Filter
filter :: forall s. KnownIntSet s => (Element s -> Bool) -> SomeIntSetWith (SupersetProof 'Int s) Source #
Return a subset of elements that satisfy the given predicate.
partition :: forall s. KnownIntSet s => (Element s -> Bool) -> Some2IntSetWith (PartitionProof 'Int s Int) 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. KnownIntSet s => (Element s -> Bool) -> Some2IntSetWith (PartialPartitionProof 'Int s) 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. KnownIntSet s => Int -> Some2IntSetWith (SplitProof 'Int s (Element s)) 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. KnownIntSet s => (Element s -> Int) -> SomeIntSetWith (MapProof 'Int s Int Int) 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 m. (KnownIntSet s, Monoid m) => (Element s -> 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. KnownIntSet s => (Element s -> a -> a) -> a -> a Source #
Right associative fold with a lazy accumulator.
foldl :: forall s a. KnownIntSet s => (a -> Element s -> a) -> a -> a Source #
Left associative fold with a lazy accumulator.
foldr' :: forall s a. KnownIntSet s => (Element s -> a -> a) -> a -> a Source #
Right associative fold with a strict accumulator.
foldl' :: forall s a. KnownIntSet s => (a -> Element s -> a) -> a -> a Source #
Left associative fold with a strict accumulator.
Min/Max
minView :: forall s. KnownIntSet s => Either (EmptyProof 'Int s) (Element s, SomeIntSetWith (SupersetProof 'Int s)) 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. KnownIntSet s => Either (EmptyProof 'Int s) (Element s, SomeIntSetWith (SupersetProof 'Int s)) 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. KnownIntSet s => [Element s] Source #
List of elements in the set in ascending order.
toDescList :: forall s. KnownIntSet s => [Element s] Source #
List of elements in the set in descending order.
asSet :: forall s. KnownIntSet s => Set s Int Source #
Convert an IntSet
into a Set
, retaining its set of elements, which can
be converted with castFlavor
.
asHashSet :: forall s. KnownIntSet s => HashSet s Int Source #
Convert an IntSet
into a HashSet
, retaining its set of elements, which
can be converted with castFlavor
.
Casts
castElement :: forall s t a. (forall x. Refined (InSet 'Int s) x -> Refined (InSet 'Int t) x) -> (forall x. Refined (InSet 'Int t) x -> Refined (InSet 'Int s) x) -> Coercion (Refined (InSet 'Int s) a) (Refined (InSet 'Int 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. (forall x. Coercion (Refined (InSet 'Int s) x) (Refined (InSet 'Int t) x)) -> Coercion (IntSet s) (IntSet t) 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
'Int
s s r ->Coercion
(IntSet
r) (IntSet
s) castIntersection (IntersectionProof
p1 p2) =cast
$castElement
(andLeft
. p1) (p2id
id
)