-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Combinators for manipulating dependently-typed predicates. -- -- This library provides combinators and typeclasses for working and -- manipulating type-level predicates in Haskell, which are represented -- as matchable type-level functions k ~> Type from the -- singletons library. See Data.Type.Predicate for a good -- starting point, and the documentation for Predicate on how to -- define predicates. @package decidable @version 0.3.1.1 -- | Combinators for working with type-level predicates, along with -- typeclasses for canonical proofs and deciding functions. module Data.Type.Predicate -- | A type-level predicate in Haskell. We say that the predicate P :: -- Predicate k is true/satisfied by input x :: k if -- there exists a value of type P @@ x, and that it -- false/disproved if such a value cannot exist. (Where @@ is -- Apply, the singleton library's type-level function application -- for mathcable functions). In some contexts, this is also known as a -- dependently typed "view". -- -- See Provable and Decidable for more information on how -- to use, prove and decide these predicates. -- -- The kind k ~> Type is the kind of "matchable" -- type-level functions in Haskell. They are type-level functions that -- are encoded as dummy type constructors ("defunctionalization symbols") -- that can be decidedly "matched" on for things like typeclass -- instances. -- -- There are two ways to define your own predicates: -- --
    --
  1. Using the predicate combinators and predicate transformers in this -- library and the singletons library, which let you construct -- pre-made predicates and sometimes create predicates from other -- predicates.
  2. --
  3. Manually creating a data type that acts as a matchable -- predicate.
  4. --
-- -- For an example of the latter, we can create the "not p" predicate, -- which takes a predicate p as input and returns the negation -- of the predicate: -- --
--   -- First, create the data type with the kind signature you want
--   data Not :: Predicate k -> Predicate k
--   
--   -- Then, write the Apply instance, to specify the type of the
--   -- witnesses of that predicate
--   instance Apply (Not p) a = (p @@ a) -> Void
--   
-- -- See the source of Data.Type.Predicate and -- Data.Type.Predicate.Logic for simple examples of hand-made -- predicates. For example, we have the always-true predicate -- Evident: -- --
--   data Evident :: Predicate k
--   instance Apply Evident a = Sing a
--   
-- -- And the "and" predicate combinator: -- --
--   data (&&&) :: Predicate k -> Predicate k -> Predicate k
--   instance Apply (p &&& q) a = (p @@ a, q @@ a)
--   
-- -- Typically it is recommended to create predicates from the supplied -- predicate combinators (TyPred can be used for any type -- constructor to turn it into a predicate, for instance) whenever -- possible. type Predicate k = k ~> Type -- | A Wit p a is a value of type p @@ a --- that -- is, it is a proof or witness that p is satisfied for -- a. -- -- It essentially turns a k ~> Type ("matchable" -- Predicate k) /back into/ a k -> -- Type predicate. newtype Wit p a Wit :: (p @@ a) -> Wit p a [getWit] :: Wit p a -> p @@ a -- | Convert a normal -> type constructor into a -- Predicate. -- --
--   TyPred :: (k -> Type) -> Predicate k
--   
type TyPred = (TyCon1 :: (k -> Type) -> Predicate k) -- | The always-true predicate. -- --
--   Evident :: Predicate k
--   
data Evident :: Predicate k -- | EqualTo a is a predicate that the input is equal to -- a. -- --
--   EqualTo :: k -> Predicate k
--   
type EqualTo (a :: k) = (TyPred ((:~:) a) :: Predicate k) -- | Convert a tradtional k ~> Bool predicate into a -- Predicate. -- --
--   BoolPred :: (k ~> Bool) -> Predicate k
--   
type BoolPred (p :: k ~> Bool) = (PMap p (EqualTo 'True) :: Predicate k) -- | The always-false predicate -- -- Could also be defined as ConstSym1 Void, but this -- defintion gives us a free Decidable instance. -- --
--   Impossible :: Predicate k
--   
type Impossible = (Not Evident :: Predicate k) -- | In f as is a predicate that a given input a -- is a member of collection as. type In (f :: Type -> Type) (as :: f k) = ElemSym1 f as -- | Pre-compose a function to a predicate -- --
--   PMap :: (k ~> j) -> Predicate j -> Predicate k
--   
type PMap (f :: k ~> j) (p :: Predicate j) = (p .@#@$$$ f :: Predicate k) -- | Not p is the predicate that p is not true. data Not :: Predicate k -> Predicate k -- | Decide Not p based on decisions of p. decideNot :: forall p a. () => Decision (p @@ a) -> Decision (Not p @@ a) -- | A proving function for predicate p; in some contexts, also -- called a "view function". See Provable for more information. type Prove p = forall a. Sing a -> p @@ a -- | We say that p implies q (p --> q) -- if, given p a, we can always prove q @@ a. type p --> q = forall a. Sing a -> p @@ a -> q @@ a infixr 1 --> -- | This is implication -->#, but only in a specific context -- h. type ( p --># q ) h = forall a. Sing a -> p @@ a -> h (q @@ a) infixr 1 --># -- | A typeclass for provable predicates (constructivist tautologies). In -- some context, these are also known as "views". -- -- A predicate is provable if, given any input a, you can -- generate a proof of p @@ a. Essentially, it means that a -- predicate is "always true". -- -- We can call a type a view if, for any input a, there is -- some constructor of p @@ a that can we can use to -- "categorize" a. -- -- This typeclass associates a canonical proof function for every -- provable predicate, or a canonical view function for any view. -- -- It confers two main advatnages: -- --
    --
  1. The proof functionview for every predicateview is available -- via the same name
  2. --
  3. We can write Provable instances for polymorphic predicate -- transformers (predicates parameterized on other predicates) easily, by -- refering to Provable instances of the transformed -- predicates.
  4. --
class Provable p -- | The canonical proving function for predicate p (or a -- canonical view function for view p). -- -- Note that prove is ambiguously typed, so you always need -- to call by specifying the predicate you want to prove using -- TypeApplications syntax: -- --
--   prove @MyPredicate
--   
-- -- See proveTC and ProvableTC for a version that isn't -- ambiguously typed, but only works when p is a type -- constructor. prove :: Provable p => Prove p -- | Disprovable p is a constraint that p can be -- disproven. type Disprovable p = Provable (Not p) -- | The deciding/disproving function for Disprovable p. -- -- Must be called by applying the Predicate to disprove: -- --
--   disprove @p
--   
disprove :: forall p. Disprovable p => Prove (Not p) -- | If T :: k -> Type is a type constructor, then -- ProvableTC T is a constraint that T is -- "decidable", in that you have a canonical function: -- --
--   proveTC :: Sing a -> T a
--   
-- -- Is essentially Provable, except with type constructors -- k -> Type instead of matchable type-level functions -- (that are k ~> Type). Useful because proveTC -- doesn't require anything fancy like TypeApplications to use. -- -- Also is in this library for compatiblity with "traditional" predicates -- that are GADT type constructors. type ProvableTC p = Provable (TyPred p) -- | The canonical proving function for DecidableTC t. -- -- Note that because t must be an injective type constructor, -- you can use this without explicit type applications; the instance of -- ProvableTC can be inferred from the result type. proveTC :: forall t a. ProvableTC t => Sing a -> t a -- | Implicatons p --> q can be lifted "through" a -- TFunctor into an f p --> f q. class TFunctor f tmap :: forall p q. TFunctor f => (p --> q) -> f p --> f q -- | Compose two implications. compImpl :: forall p q r. () => (p --> q) -> (q --> r) -> p --> r -- | A decision function for predicate p. See Decidable for -- more information. type Decide p = forall a. Sing a -> Decision (p @@ a) -- | Like implication -->, but knowing p @@ a can only -- let us decidably prove q a is true or false. type p -?> q = forall a. Sing a -> p @@ a -> Decision (q @@ a) infixr 1 -?> -- | Like -?>, but only in a specific context h. type ( p -?># q ) h = forall a. Sing a -> p @@ a -> h (Decision (q @@ a)) infixr 1 -?># -- | A typeclass for decidable predicates. -- -- A predicate is decidable if, given any input a, you can -- either prove or disprove p @@ a. A Decision (p @@ -- a) is a data type that has a branch p @@ a and -- Refuted (p @@ a). -- -- This typeclass associates a canonical decision function for every -- decidable predicate. -- -- It confers two main advatnages: -- --
    --
  1. The decision function for every predicate is available via the -- same name
  2. --
  3. We can write Decidable instances for polymorphic predicate -- transformers (predicates parameterized on other predicates) easily, by -- refering to Decidable instances of the transformed -- predicates.
  4. --
class Decidable p -- | The canonical decision function for predicate p. -- -- Note that decide is ambiguously typed, so you always -- need to call by specifying the predicate you want to prove using -- TypeApplications syntax: -- --
--   decide @MyPredicate
--   
-- -- See decideTC and DecidableTC for a version that isn't -- ambiguously typed, but only works when p is a type -- constructor. decide :: Decidable p => Decide p -- | The canonical decision function for predicate p. -- -- Note that decide is ambiguously typed, so you always -- need to call by specifying the predicate you want to prove using -- TypeApplications syntax: -- --
--   decide @MyPredicate
--   
-- -- See decideTC and DecidableTC for a version that isn't -- ambiguously typed, but only works when p is a type -- constructor. decide :: (Decidable p, Provable p) => Decide p -- | If T :: k -> Type is a type constructor, then -- DecidableTC T is a constraint that T is -- "decidable", in that you have a canonical function: -- --
--   decideTC :: Sing a -> Decision (T a)
--   
-- -- Is essentially Decidable, except with type constructors -- k -> Type instead of matchable type-level functions -- (that are k ~> Type). Useful because -- decideTC doesn't require anything fancy like TypeApplications -- to use. -- -- Also is in this library for compatiblity with "traditional" predicates -- that are GADT type constructors. type DecidableTC p = Decidable (TyPred p) -- | The canonical deciding function for DecidableTC t. -- -- Note that because t must be an injective type constructor, -- you can use this without explicit type applications; the instance of -- DecidableTC can be inferred from the result type. decideTC :: forall t a. DecidableTC t => Sing a -> Decision (t a) -- | Implicatons p -?> q can be lifted "through" a -- DFunctor into an f p -?> f q. class DFunctor f dmap :: forall p q. DFunctor f => (p -?> q) -> f p -?> f q -- | A Decision about a type a is either a proof of -- existence or a proof that a cannot exist. data () => Decision a -- | Witness for a Proved :: a -> Decision a -- | Proof that no a exists Disproved :: Refuted a -> Decision a -- | Flip the contents of a decision. Turn a proof of a into a -- disproof of not-a. -- -- Note that this is not reversible in general in constructivist logic -- See doubleNegation for a situation where it is. flipDecision :: Decision a -> Decision (Refuted a) -- | Map over the value inside a Decision. mapDecision :: (a -> b) -> (b -> a) -> Decision a -> Decision b -- | Helper function for a common pattern of eliminating the disproved -- branch of Decision to certaintify the proof. elimDisproof :: Decision a -> Refuted (Refuted a) -> a -- | Converts a Decision to a Maybe. Drop the witness of -- disproof of a, returning Just if Proved (with -- the proof) and Nothing if Disproved. forgetDisproof :: Decision a -> Maybe a -- | Drop the witness of proof of a, returning Nothing if -- Proved and Just if Disproved (with the disproof). forgetProof :: Decision a -> Maybe (Refuted a) -- | Boolean test if a Decision is Proved. isProved :: Decision a -> Bool -- | Boolean test if a Decision is Disproved. isDisproved :: Decision a -> Bool -- | Change the target of a Refuted with a contravariant mapping -- function. mapRefuted :: (a -> b) -> Refuted b -> Refuted a instance forall k (as :: [k]). (Data.Singletons.Decide.SDecide k, Data.Singletons.SingI as) => Data.Type.Predicate.Decidable (Data.Type.Predicate.In [] as) instance forall k (as :: GHC.Maybe.Maybe k). (Data.Singletons.Decide.SDecide k, Data.Singletons.SingI as) => Data.Type.Predicate.Decidable (Data.Type.Predicate.In GHC.Maybe.Maybe as) instance forall k j (as :: Data.Either.Either j k). (Data.Singletons.Decide.SDecide k, Data.Singletons.SingI as) => Data.Type.Predicate.Decidable (Data.Type.Predicate.In (Data.Either.Either j) as) instance forall k (as :: GHC.Base.NonEmpty k). (Data.Singletons.Decide.SDecide k, Data.Singletons.SingI as) => Data.Type.Predicate.Decidable (Data.Type.Predicate.In GHC.Base.NonEmpty as) instance forall k j (as :: (j, k)). (Data.Singletons.Decide.SDecide k, Data.Singletons.SingI as) => Data.Type.Predicate.Decidable (Data.Type.Predicate.In ((,) j) as) instance forall k (as :: Data.Functor.Identity.Identity k). (Data.Singletons.Decide.SDecide k, Data.Singletons.SingI as) => Data.Type.Predicate.Decidable (Data.Type.Predicate.In Data.Functor.Identity.Identity as) instance Data.Type.Predicate.Provable (Data.Type.Predicate.Not Data.Type.Predicate.Impossible) instance forall k1 (p :: k1 Data.Singletons.~> *). Data.Type.Predicate.Decidable p => Data.Type.Predicate.Decidable (Data.Type.Predicate.Not p) instance forall k (a :: k). (Data.Singletons.Decide.SDecide k, Data.Singletons.SingI a) => Data.Type.Predicate.Decidable (Data.Type.Predicate.EqualTo a) instance Data.Type.Predicate.Decidable Data.Type.Predicate.Evident instance Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred Data.Singletons.WrappedSing) instance forall u (p :: u Data.Singletons.~> *). Data.Type.Predicate.Decidable p => Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Vinyl.Core.Rec (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Vinyl.Core.Rec Data.Singletons.WrappedSing)) instance forall k (p :: k Data.Singletons.~> *). Data.Type.Predicate.Decidable p => Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PMaybe (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PMaybe Data.Singletons.WrappedSing)) instance forall k (p :: k Data.Singletons.~> *). Data.Type.Predicate.Decidable p => Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.NERec (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.NERec Data.Singletons.WrappedSing)) instance forall k (p :: k Data.Singletons.~> *). Data.Type.Predicate.Decidable p => Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PIdentity (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PIdentity Data.Singletons.WrappedSing)) instance forall k j (p :: k Data.Singletons.~> *). Data.Type.Predicate.Decidable p => Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PEither (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PEither Data.Singletons.WrappedSing)) instance forall k j (p :: k Data.Singletons.~> *). Data.Type.Predicate.Decidable p => Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PTup (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Decidable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PTup Data.Singletons.WrappedSing)) instance forall j k1 (p :: j Data.Singletons.~> *) (f :: k1 Data.Singletons.~> j). (Data.Type.Predicate.Decidable p, Data.Singletons.SingI f) => Data.Type.Predicate.Decidable (Data.Type.Predicate.PMap f p) instance Data.Type.Predicate.Provable Data.Type.Predicate.Evident instance Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred Data.Singletons.WrappedSing) instance forall u (p :: u Data.Singletons.~> *). Data.Type.Predicate.Provable p => Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Vinyl.Core.Rec (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Vinyl.Core.Rec Data.Singletons.WrappedSing)) instance forall k (p :: k Data.Singletons.~> *). Data.Type.Predicate.Provable p => Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PMaybe (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PMaybe Data.Singletons.WrappedSing)) instance forall k (p :: k Data.Singletons.~> *). Data.Type.Predicate.Provable p => Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.NERec (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.NERec Data.Singletons.WrappedSing)) instance forall k (p :: k Data.Singletons.~> *). Data.Type.Predicate.Provable p => Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PIdentity (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PIdentity Data.Singletons.WrappedSing)) instance forall k j (p :: k Data.Singletons.~> *). Data.Type.Predicate.Provable p => Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PEither (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PEither Data.Singletons.WrappedSing)) instance forall k j (p :: k Data.Singletons.~> *). Data.Type.Predicate.Provable p => Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PTup (Data.Type.Predicate.Wit p))) instance Data.Type.Predicate.Provable (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PTup Data.Singletons.WrappedSing)) instance forall j k1 (p :: j Data.Singletons.~> *) (f :: k1 Data.Singletons.~> j). (Data.Type.Predicate.Provable p, Data.Singletons.SingI f) => Data.Type.Predicate.Provable (Data.Type.Predicate.PMap f p) -- | Logical and algebraic connectives for predicates, as well as common -- logical combinators. module Data.Type.Predicate.Logic -- | The always-true predicate. -- --
--   Evident :: Predicate k
--   
data Evident :: Predicate k -- | The always-false predicate -- -- Could also be defined as ConstSym1 Void, but this -- defintion gives us a free Decidable instance. -- --
--   Impossible :: Predicate k
--   
type Impossible = (Not Evident :: Predicate k) -- | Not p is the predicate that p is not true. data Not :: Predicate k -> Predicate k -- | Decide Not p based on decisions of p. decideNot :: forall p a. () => Decision (p @@ a) -> Decision (Not p @@ a) -- | p &&& q is a predicate that both -- p and q are true. data (&&&) :: Predicate k -> Predicate k -> Predicate k infixr 3 &&& -- | Decide p &&& q based on decisions of -- p and q. decideAnd :: forall p q a. () => Decision (p @@ a) -> Decision (q @@ a) -> Decision ((p &&& q) @@ a) -- | p ||| q is a predicate that either p and -- q are true. data (|||) :: Predicate k -> Predicate k -> Predicate k infixr 2 ||| -- | Decide p ||| q based on decisions of p and -- q. -- -- Prefers p over q. decideOr :: forall p q a. () => Decision (p @@ a) -> Decision (q @@ a) -> Decision ((p ||| q) @@ a) -- | Left-biased "or". In proofs, prioritize a proof of the left side over -- a proof of the right side. type p ^|| q = p ||| Not p &&& q -- | Right-biased "or". In proofs, prioritize a proof of the right side -- over a proof of the left side. type p ||^ q = p &&& Not q ||| q -- | p ^^^ q is a predicate that either p and -- q are true, but not both. type p ^^^ q = (p &&& Not q) ||| (Not p &&& q) -- | Decide p ^^^ q based on decisions of p and -- q. decideXor :: forall p q a. () => Decision (p @@ a) -> Decision (q @@ a) -> Decision ((p ^^^ q) @@ a) -- | p ==> q is true if q is provably true under the -- condition that p is true. data (==>) :: Predicate k -> Predicate k -> Predicate k infixr 1 ==> -- | If q is provable, then so is p ==> q. -- -- This can be used as an easy plug-in Provable instance for p -- ==> q if q is Provable: -- --
--   instance Provable (p ==> MyPred) where
--       prove = proveImplies @MyPred
--   
-- -- This instance isn't provided polymorphically because of overlapping -- instance issues. proveImplies :: Prove q -> Prove (p ==> q) -- | Implies p q is a constraint that p ==> -- q is Provable; that is, you can prove that p -- implies q. type Implies p q = Provable (p ==> q) -- | Two-way implication, or logical equivalence type p <==> q = p ==> q &&& q ==> p infixr 1 <==> -- | Equiv p q is a constraint that p <==> -- q is Provable; that is, you can prove that p is -- logically equivalent to q. type Equiv p q = Provable (p <==> q) -- | Compose two implications. compImpl :: forall p q r. () => (p --> q) -> (q --> r) -> p --> r -- | From Impossible a, you can prove anything. -- Essentially a lifted version of absurd. explosion :: Impossible --> p -- | Evident can be proven from all predicates. atom :: p --> Evident -- | We cannot have both p and Not p. -- -- (Renamed in v0.1.4.0; used to be excludedMiddle) complementation :: forall p. (p &&& Not p) --> Impossible -- | Logical double negation. Only possible if p is -- Decidable. -- -- This is because in constructivist logic, not (not p) does not imply p. -- However, p implies not (not p) (see negateTwice), and not (not -- (not p)) implies not p (see tripleNegation) doubleNegation :: forall p. Decidable p => Not (Not p) --> p -- | In constructivist logic, not (not (not p)) implies not p. tripleNegation :: forall p. Not (Not (Not p)) --> Not p -- | In constructivist logic, p implies not (not p). negateTwice :: p --> Not (Not p) -- | If p implies q, then not q implies not p. contrapositive :: (p --> q) -> Not q --> Not p -- | Reverse direction of contrapositive. Only possible if -- q is Decidable on its own, without the help of -- p, which makes this much less useful. contrapositive' :: forall p q. Decidable q => (Not q --> Not p) -> p --> q -- | If p &&& q is true, then so is p. projAndFst :: (p &&& q) --> p -- | If p &&& q is true, then so is q. projAndSnd :: (p &&& q) --> q -- | If p is true, then so is p ||| q. injOrLeft :: forall p q. p --> (p ||| q) -- | If q is true, then so is p ||| q. injOrRight :: forall p q. q --> (p ||| q) instance forall k1 (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Decidable (Data.Type.Predicate.Impossible Data.Type.Predicate.Logic.==> p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable (Data.Type.Predicate.Impossible Data.Type.Predicate.Logic.==> p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). (Data.Type.Predicate.Decidable (p Data.Type.Predicate.Logic.==> q), Data.Type.Predicate.Decidable q) => Data.Type.Predicate.Decidable (Data.Type.Predicate.Not q Data.Type.Predicate.Logic.==> Data.Type.Predicate.Not p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable (p Data.Type.Predicate.Logic.==> q) => Data.Type.Predicate.Provable (Data.Type.Predicate.Not q Data.Type.Predicate.Logic.==> Data.Type.Predicate.Not p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Decidable ((p Data.Type.Predicate.Logic.&&& q) Data.Type.Predicate.Logic.==> p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable ((p Data.Type.Predicate.Logic.&&& q) Data.Type.Predicate.Logic.==> p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Decidable ((p Data.Type.Predicate.Logic.&&& q) Data.Type.Predicate.Logic.==> q) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable ((p Data.Type.Predicate.Logic.&&& q) Data.Type.Predicate.Logic.==> q) instance forall k1 (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Decidable ((p Data.Type.Predicate.Logic.&&& p) Data.Type.Predicate.Logic.==> p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable ((p Data.Type.Predicate.Logic.&&& p) Data.Type.Predicate.Logic.==> p) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Decidable (p Data.Type.Predicate.Logic.==> (p Data.Type.Predicate.Logic.||| q)) instance forall k1 (p :: Data.Type.Predicate.Predicate k1) (q :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable (p Data.Type.Predicate.Logic.==> (p Data.Type.Predicate.Logic.||| q)) instance forall k1 (q :: Data.Type.Predicate.Predicate k1) (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Decidable (q Data.Type.Predicate.Logic.==> (p Data.Type.Predicate.Logic.||| q)) instance forall k1 (q :: Data.Type.Predicate.Predicate k1) (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable (q Data.Type.Predicate.Logic.==> (p Data.Type.Predicate.Logic.||| q)) instance forall k1 (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Decidable (p Data.Type.Predicate.Logic.==> (p Data.Type.Predicate.Logic.||| p)) instance forall k1 (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable (p Data.Type.Predicate.Logic.==> (p Data.Type.Predicate.Logic.||| p)) instance forall k1 (p :: Data.Type.Predicate.Predicate k1). Data.Type.Predicate.Provable ((p Data.Type.Predicate.Logic.&&& Data.Type.Predicate.Not p) Data.Type.Predicate.Logic.==> Data.Type.Predicate.Impossible) instance forall k1 (p :: k1 Data.Singletons.~> *) (q :: k1 Data.Singletons.~> *). (Data.Type.Predicate.Decidable p, Data.Type.Predicate.Decidable q) => Data.Type.Predicate.Decidable (p Data.Type.Predicate.Logic.||| q) instance forall k1 (p :: k1 Data.Singletons.~> *) (q :: k1 Data.Singletons.~> *). (Data.Type.Predicate.Decidable p, Data.Type.Predicate.Decidable q) => Data.Type.Predicate.Decidable (p Data.Type.Predicate.Logic.&&& q) instance forall k1 (p :: k1 Data.Singletons.~> *) (q :: k1 Data.Singletons.~> *). (Data.Type.Predicate.Provable p, Data.Type.Predicate.Provable q) => Data.Type.Predicate.Provable (p Data.Type.Predicate.Logic.&&& q) -- | A type family for "containers", intended for allowing lifting of -- predicates on k to be predicates on containers f k. module Data.Type.Universe type family Elem (f :: Type -> Type) = (i :: f k -> k -> Type) | i -> f -- | In f as is a predicate that a given input a -- is a member of collection as. type In (f :: Type -> Type) (as :: f k) = ElemSym1 f as -- | Typeclass for a type-level container that you can quantify or lift -- type-level predicates over. class FProd f => Universe (f :: Type -> Type) -- | decideAny, but providing an Elem. idecideAny :: forall k (p :: k ~> Type) (as :: f k). Universe f => (forall a. Elem f as a -> Sing a -> Decision (p @@ a)) -> Sing as -> Decision (Any f p @@ as) -- | decideAll, but providing an Elem. idecideAll :: forall k (p :: k ~> Type) (as :: f k). Universe f => (forall a. Elem f as a -> Sing a -> Decision (p @@ a)) -> Sing as -> Decision (All f p @@ as) allProd :: forall p g. Universe f => (forall a. Sing a -> (p @@ a) -> g a) -> All f p --> TyPred (Prod f g) prodAll :: forall p g as. Universe f => (forall a. g a -> p @@ a) -> Prod f g as -> All f p @@ as -- | Split a Sing as into a proof that all a in -- as exist. singAll :: forall f k (as :: f k). Universe f => Sing as -> All f Evident @@ as -- | Witness an item in a type-level list by providing its index. -- -- The number of ISs correspond to the item's position in the -- list. -- --
--   IZ         :: Index '[5,10,2] 5
--   IS IZ      :: Index '[5,10,2] 10
--   IS (IS IZ) :: Index '[5,10,2] 2
--   
data () => Index (a :: [k]) (b :: k) [IZ] :: forall {k} (b :: k) (as :: [k]). Index (b ': as) b [IS] :: forall {k} (bs :: [k]) (b :: k) (b1 :: k). Index bs b -> Index (b1 ': bs) b -- | Witness an item in a type-level Maybe by proving the -- Maybe is Just. data () => IJust (a :: Maybe k) (b :: k) [IJust] :: forall {k} (b :: k). IJust ('Just b) b -- | Witness an item in a type-level Either j by proving -- the Either is Right. data () => IRight (a :: Either j k) (b :: k) [IRight] :: forall {k} {j} (b :: k). IRight ('Right b :: Either j k) b -- | Witness an item in a type-level NonEmpty by either indicating -- that it is the "head", or by providing an index in the "tail". data () => NEIndex (a :: NonEmpty k) (b :: k) [NEHead] :: forall {k} (b :: k) (as :: [k]). NEIndex (b ':| as) b [NETail] :: forall {k} (as :: [k]) (b :: k) (b1 :: k). Index as b -> NEIndex (b1 ':| as) b -- | Trivially witness an item in the second field of a type-level tuple. data () => ISnd (a :: (j, k)) (b :: k) [ISnd] :: forall {j} {k} (a1 :: j) (b :: k). ISnd '(a1, b) b -- | Trivially witness the item held in an Identity. data () => IIdentity (a :: Identity k) (b :: k) [IId] :: forall {k} (b :: k). IIdentity ('Identity b) b -- | An All f p is a predicate testing a collection as -- :: f a for the fact that all items in as satisfy -- p. Represents the "forall" quantifier over a given universe. -- -- This is mostly useful for its Decidable, Provable, and -- TFunctor instances, which lets you lift predicates on -- p to predicates on All f p. data All f :: Predicate k -> Predicate (f k) -- | A WitAll p as is a witness that the predicate p -- a is true for all items a in the type-level collection -- as. newtype WitAll f p (as :: f k) WitAll :: (forall a. Elem f as a -> p @@ a) -> WitAll f p (as :: f k) [runWitAll] :: WitAll f p (as :: f k) -> forall a. Elem f as a -> p @@ a -- | A NotAll f p is a predicate on a collection -- as that at least one a in as does not -- satisfy predicate p. type NotAll f p = (Not (All f p) :: Predicate (f k)) -- | An Any f p is a predicate testing a collection as -- :: f a for the fact that at least one item in as -- satisfies p. Represents the "exists" quantifier over a given -- universe. -- -- This is mostly useful for its Decidable and TFunctor -- instances, which lets you lift predicates on p to predicates -- on Any f p. data Any f :: Predicate k -> Predicate (f k) -- | A WitAny p as is a witness that, for at least one item -- a in the type-level collection as, the predicate -- p a is true. data WitAny f :: (k ~> Type) -> f k -> Type [WitAny] :: Elem f as a -> (p @@ a) -> WitAny f p as -- | A None f p is a predicate on a collection as -- that no a in as satisfies predicate p. type None f p = (Not (Any f p) :: Predicate (f k)) -- | Predicate that a given as :: f k is empty and has no items in -- it. type Null f = (None f Evident :: Predicate (f k)) -- | Predicate that a given as :: f k is not empty, and has at -- least one item in it. type NotNull f = (Any f Evident :: Predicate (f k)) -- | Test that a Maybe is Just. type IsJust = (NotNull Maybe :: Predicate (Maybe k)) -- | Test that a Maybe is Nothing. type IsNothing = (Null Maybe :: Predicate (Maybe k)) -- | Test that an Either is Right type IsRight = (NotNull (Either j) :: Predicate (Either j k)) -- | Test that an Either is Left type IsLeft = (Null (Either j) :: Predicate (Either j k)) -- | Lifts a predicate p on an individual a into a -- predicate that on a collection as that is true if and only if -- any item in as satisfies the original predicate. -- -- That is, it turns a predicate of kind k ~> Type into a -- predicate of kind f k ~> Type. -- -- Essentially tests existential quantification. decideAny :: forall f k (p :: k ~> Type). Universe f => Decide p -> Decide (Any f p) -- | Lifts a predicate p on an individual a into a -- predicate that on a collection as that is true if and only if -- all items in as satisfies the original predicate. -- -- That is, it turns a predicate of kind k ~> Type into a -- predicate of kind f k ~> Type. -- -- Essentially tests universal quantification. decideAll :: forall f k (p :: k ~> Type). Universe f => Decide p -> Decide (All f p) -- | If p a is true for all values a in as, then -- we have All p as. Basically witnesses the definition -- of All. genAll :: forall f k (p :: k ~> Type). Universe f => Prove p -> Prove (All f p) -- | genAll, but providing an Elem. igenAll :: forall f k (p :: k ~> Type) (as :: f k). Universe f => (forall a. Elem f as a -> Sing a -> p @@ a) -> Sing as -> All f p @@ as -- | Split a Sing as into a proof that all a in -- as exist. splitSing :: forall f k (as :: f k). Universe f => Sing as -> All f (TyPred Sing) @@ as -- | Automatically generate a witness for a member, if possible pickElem :: forall f k (as :: f k) a. (Universe f, SingI as, SingI a, SDecide k) => Decision (Elem f as a) instance forall k (f :: * -> *) (p :: k Data.Singletons.~> *). (Data.Type.Universe.Universe f, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Decidable (Data.Type.Universe.NotNull f Data.Type.Predicate.Logic.==> Data.Type.Universe.Any f p) instance forall k (p :: k Data.Singletons.~> *) (f :: * -> *). Data.Type.Predicate.Provable p => Data.Type.Predicate.Provable (Data.Type.Universe.NotNull f Data.Type.Predicate.Logic.==> Data.Type.Universe.Any f p) instance forall k (f :: * -> *) (p :: k Data.Singletons.~> *). (Data.Type.Universe.Universe f, Data.Type.Predicate.Decidable p) => Data.Type.Predicate.Decidable (Data.Type.Universe.Any f p) instance forall k (f :: * -> *) (p :: k Data.Singletons.~> *). (Data.Type.Universe.Universe f, Data.Type.Predicate.Decidable p) => Data.Type.Predicate.Decidable (Data.Type.Universe.All f p) instance forall k (f :: * -> *) (p :: k Data.Singletons.~> *). (Data.Type.Universe.Universe f, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Provable (Data.Type.Universe.All f p) instance Data.Type.Universe.Universe f => Data.Type.Predicate.TFunctor (Data.Type.Universe.Any f) instance Data.Type.Universe.Universe f => Data.Type.Predicate.TFunctor (Data.Type.Universe.All f) instance Data.Type.Universe.Universe f => Data.Type.Predicate.DFunctor (Data.Type.Universe.All f) instance Data.Type.Universe.Universe [] instance Data.Type.Universe.Universe GHC.Maybe.Maybe instance Data.Type.Universe.Universe (Data.Either.Either j) instance Data.Type.Universe.Universe GHC.Base.NonEmpty instance Data.Type.Universe.Universe ((,) j) instance Data.Type.Universe.Universe Data.Functor.Identity.Identity -- | Higher-level predicates for quantifying predicates over universes and -- sets. module Data.Type.Predicate.Quantification -- | An Any f p is a predicate testing a collection as -- :: f a for the fact that at least one item in as -- satisfies p. Represents the "exists" quantifier over a given -- universe. -- -- This is mostly useful for its Decidable and TFunctor -- instances, which lets you lift predicates on p to predicates -- on Any f p. data Any f :: Predicate k -> Predicate (f k) -- | A WitAny p as is a witness that, for at least one item -- a in the type-level collection as, the predicate -- p a is true. data WitAny f :: (k ~> Type) -> f k -> Type [WitAny] :: Elem f as a -> (p @@ a) -> WitAny f p as -- | A None f p is a predicate on a collection as -- that no a in as satisfies predicate p. type None f p = (Not (Any f p) :: Predicate (f k)) -- | It is impossible for any value in a collection to be -- Impossible. anyImpossible :: Universe f => Any f Impossible --> Impossible -- | Lifts a predicate p on an individual a into a -- predicate that on a collection as that is true if and only if -- any item in as satisfies the original predicate. -- -- That is, it turns a predicate of kind k ~> Type into a -- predicate of kind f k ~> Type. -- -- Essentially tests existential quantification. decideAny :: forall f k (p :: k ~> Type). Universe f => Decide p -> Decide (Any f p) -- | decideAny, but providing an Elem. idecideAny :: forall k (p :: k ~> Type) (as :: f k). Universe f => (forall a. Elem f as a -> Sing a -> Decision (p @@ a)) -> Sing as -> Decision (Any f p @@ as) -- | Lifts a predicate p on an individual a into a -- predicate that on a collection as that is true if and only if -- no item in as satisfies the original predicate. -- -- That is, it turns a predicate of kind k ~> Type into a -- predicate of kind f k ~> Type. decideNone :: forall f k (p :: k ~> Type). Universe f => Decide p -> Decide (None f p) -- | decideNone, but providing an Elem. idecideNone :: forall f k (p :: k ~> Type) (as :: f k). Universe f => (forall a. Elem f as a -> Sing a -> Decision (p @@ a)) -> Sing as -> Decision (None f p @@ as) -- | If there exists an a s.t. p a, and if p -- implies q, then there must exist an a s.t. q -- a. entailAny :: forall f p q. Universe f => (p --> q) -> Any f p --> Any f q -- | entailAny, but providing an Elem. ientailAny :: forall f p q as. (Universe f, SingI as) => (forall a. Elem f as a -> Sing a -> (p @@ a) -> q @@ a) -> (Any f p @@ as) -> Any f q @@ as -- | If p implies q under some context h, and if -- there exists some a such that p a, then there must -- exist some a such that p q under that context -- h. -- -- h might be something like, say, Maybe, to give -- predicate that is either provably true or unprovably false. -- -- Note that it is not possible to do this with p a -> -- Decision (q a). This is if the p a -> -- Decision (q a) implication is false, there it doesn't mean -- that there is no a such that q a, -- necessarily. There could have been an a where p does -- not hold, but q does. entailAnyF :: forall f p q h. (Universe f, Functor h) => (p --># q) h -> (Any f p --># Any f q) h -- | entailAnyF, but providing an Elem. ientailAnyF :: forall f p q as h. Functor h => (forall a. Elem f as a -> (p @@ a) -> h (q @@ a)) -> (Any f p @@ as) -> h (Any f q @@ as) -- | An All f p is a predicate testing a collection as -- :: f a for the fact that all items in as satisfy -- p. Represents the "forall" quantifier over a given universe. -- -- This is mostly useful for its Decidable, Provable, and -- TFunctor instances, which lets you lift predicates on -- p to predicates on All f p. data All f :: Predicate k -> Predicate (f k) -- | A WitAll p as is a witness that the predicate p -- a is true for all items a in the type-level collection -- as. newtype WitAll f p (as :: f k) WitAll :: (forall a. Elem f as a -> p @@ a) -> WitAll f p (as :: f k) [runWitAll] :: WitAll f p (as :: f k) -> forall a. Elem f as a -> p @@ a -- | A NotAll f p is a predicate on a collection -- as that at least one a in as does not -- satisfy predicate p. type NotAll f p = (Not (All f p) :: Predicate (f k)) -- | Lifts a predicate p on an individual a into a -- predicate that on a collection as that is true if and only if -- all items in as satisfies the original predicate. -- -- That is, it turns a predicate of kind k ~> Type into a -- predicate of kind f k ~> Type. -- -- Essentially tests universal quantification. decideAll :: forall f k (p :: k ~> Type). Universe f => Decide p -> Decide (All f p) -- | decideAll, but providing an Elem. idecideAll :: forall k (p :: k ~> Type) (as :: f k). Universe f => (forall a. Elem f as a -> Sing a -> Decision (p @@ a)) -> Sing as -> Decision (All f p @@ as) -- | If for all a we have p a, and if p implies -- q, then for all a we must also have p a. entailAll :: forall f p q. Universe f => (p --> q) -> All f p --> All f q -- | entailAll, but providing an Elem. ientailAll :: forall f p q as. (Universe f, SingI as) => (forall a. Elem f as a -> Sing a -> (p @@ a) -> q @@ a) -> (All f p @@ as) -> All f q @@ as -- | If p implies q under some context h, and if -- we have p a for all a, then we must have q -- a for all a under context h. entailAllF :: forall f p q h. (Universe f, Applicative h) => (p --># q) h -> (All f p --># All f q) h -- | entailAllF, but providing an Elem. ientailAllF :: forall f p q as h. (Universe f, Applicative h, SingI as) => (forall a. Elem f as a -> (p @@ a) -> h (q @@ a)) -> (All f p @@ as) -> h (All f q @@ as) -- | If we have p a for all a, and p a can be -- used to test for q a, then we can test all as for -- q a. decideEntailAll :: forall f p q. Universe f => (p -?> q) -> All f p -?> All f q -- | entailAllF, but providing an Elem. idecideEntailAll :: forall f p q as. (Universe f, SingI as) => (forall a. Elem f as a -> (p @@ a) -> Decision (q @@ a)) -> (All f p @@ as) -> Decision (All f q @@ as) -- | If something is true for all xs, then it must be true for at least one -- x in xs, provided that xs is not empty. allToAny :: (All f p &&& NotNull f) --> Any f p -- | If p is false for all a in as, then no -- a in as satisfies p. allNotNone :: All f (Not p) --> None f p -- | If no a in as satisfies p, then p -- is false for all a in as. Requires -- Decidable p to interrogate the input disproof. noneAllNot :: forall f p. (Universe f, Decidable p) => None f p --> All f (Not p) -- | If any a in as does not satisfy p, then not -- all a in as satisfy p. anyNotNotAll :: Any f (Not p) --> NotAll f p -- | If not all a in as satisfy p, then there -- must be at least one a in as that does not satisfy -- p. Requires Decidable p in order to locate -- that specific a. notAllAnyNot :: forall f p. (Universe f, Decidable p) => NotAll f p --> Any f (Not p) -- | Manipulate "parameterized predicates". See ParamPred and -- Found for more information. module Data.Type.Predicate.Param -- | A parameterized predicate. See Found for more information. type ParamPred k v = k -> Predicate v -- | Found (IsTC t) @@ x is true if x was made -- using the unary type constructor t. -- -- For example: -- --
--   type IsJust = (Found (IsTC 'Just) :: Predicate (Maybe v))
--   
-- -- makes a predicate where IsJust @@ x is true if x is -- Just, and false if x is Nothing. -- -- For a more general version, see EqBy -- -- The kind of IsTC is: -- --
--   IsTC :: (v -> k) -> ParamPred k v
--   Found (IsTC t) :: Predicate k
--   
-- -- Applied to specific things: -- --
--   IsTC 'Just :: ParamPred (Maybe v) v
--   Found (IsTC 'Just') :: Predicate (Maybe v)
--   
type IsTC t = EqBy (TyCon1 t) -- | Found (EqBy f) @@ x is true if there exists some value -- when, with f applied to it, is equal to x. -- -- See IsTC for a useful specific application. -- --
--   EqBy :: (v ~> k) -> ParamPred k v
--   Found (EqBy f) :: Predicate k
--   
data EqBy :: (v ~> k) -> ParamPred k v -- | Flip the arguments of a ParamPred. data FlipPP :: ParamPred v k -> ParamPred k v -- | Promote a Predicate v to a ParamPred k -- v, ignoring the k input. data ConstPP :: Predicate v -> ParamPred k v -- | Pre-compose a function to a ParamPred. Is essentially -- flip (.), but unfortunately defunctionalization -- doesn't work too well with that definition. data PPMap :: (k ~> j) -> ParamPred j v -> ParamPred k v -- | Pre-compose a function to a ParamPred, but on the "value" side. data PPMapV :: (u ~> v) -> ParamPred k u -> ParamPred k v -- | A ParamPred (f k) k. Parameterized on an as :: f -- k, returns a predicate that is true if there exists any a :: -- k in as. -- -- Essentially NotNull. type InP f = (ElemSym1 f :: ParamPred (f k) k) -- | AnyMatch f takes a parmaeterized predicate on -- k (testing for a v) and turns it into a -- parameterized predicate on f k (testing for a v). It -- "lifts" the domain into f. -- -- An AnyMatch f p as is a predicate taking an argument -- a and testing if p a :: Predicate k is -- satisfied for any item in as :: f k. -- -- A ParamPred k v tests if a k can create some -- v. The resulting ParamPred (f k) v tests if -- any k in f k can create some v. data AnyMatch f :: ParamPred k v -> ParamPred (f k) v -- | Convert a normal -> type constructor taking two arguments -- into a ParamPred. -- --
--   TyPP :: (k -> v -> Type) -> ParamPred k v
--   
data TyPP :: (k -> v -> Type) -> ParamPred k v -- | Convert a parameterized predicate into a predicate on the parameter. -- -- A Found p is a predicate on p :: ParamPred -- k v that tests a k for the fact that there exists a -- v where ParamPred k v is satisfied. -- -- Intended as the basic interface for ParamPred, since it turns a -- ParamPred into a normal Predicate, which can have -- Decidable and Provable instances. -- -- For some context, an instance of Provable (Found -- P), where P :: ParamPred k v, means that for any -- input x :: k, we can always find a y :: v such that -- we have P x @@ y. -- -- In the language of quantifiers, it means that forall x :: k, -- there exists a y :: v such that P x @@ y. -- -- For an instance of Decidable (Found P), it -- means that for all x :: k, we can prove or disprove the fact -- that there exists a y :: v such that P x @@ y. data Found :: ParamPred k v -> Predicate k -- | Convert a parameterized predicate into a predicate on the parameter. -- -- A Found p is a predicate on p :: ParamPred -- k v that tests a k for the fact that there cannot -- exist a v where ParamPred k v is -- satisfied. That is, NotFound P @@ x is satisfied if no -- y :: v can exist where P x @@ y is satisfied. -- -- For some context, an instance of Provable (NotFound -- P), where P :: ParamPred k v, means that for any -- input x :: k, we can always reject any y :: v that -- claims to satisfy P x @@ y. -- -- In the language of quantifiers, it means that forall x :: k, -- there does not exist a y :: v such that P x @@ y. -- -- For an instance of Decidable (Found P), it -- means that for all x :: k, we can prove or disprove the fact -- that there does not exist a y :: v such that P x @@ -- y. type NotFound (p :: ParamPred k v) = (Not (Found p) :: Predicate k) -- | A constraint that a ParamPred k v s "selectable". It -- means that for any input x :: k, we can always find a y -- :: v that satisfies P x @@ y. We can "select" that -- y, no matter what. type Selectable p = Provable (Found p) -- | The proving/selecting function for Selectable p. -- -- Because this is ambiguously typed, it must be called by applying the -- ParamPred: -- --
--   select @p
--   
-- -- See selectTC and SelectableTC for a version that isn't -- ambiguously typed, but only works when p is a type -- constructor. select :: forall p. Selectable p => Prove (Found p) -- | A constraint that a ParamPred k v is "searchable". It -- means that for any input x :: k, we can prove or disprove -- that there exists a y :: v that satisfies P x @@ y. -- We can "search" for that y, and prove that it can or cannot -- be found. type Searchable p = Decidable (Found p) -- | The deciding/searching function for Searchable p. -- -- Because this is ambiguously typed, it must be called by applying the -- ParamPred: -- --
--   search @p
--   
-- -- See searchTC and SearchableTC for a version that isn't -- ambiguously typed, but only works when p is a type -- constructor. search :: forall p. Searchable p => Decide (Found p) -- | NotNull f is basically Found (InP -- f). inPNotNull :: Found (InP f) --> NotNull f -- | NotNull f is basically Found (InP -- f). notNullInP :: NotNull f --> Found (InP f) -- | If T :: k -> v -> Type is a type constructor, -- then Selectable T is a constraint that T is -- "selectable", in that you have a canonical function: -- --
--   selectTC :: Sing a -> Σ v (TyPP T x)
--   
-- -- That is, given an x :: k, we can always find a y -- :: k that satisfies T x y. -- -- Is essentially Selectable, except with type constructors -- k -> Type instead of matchable type-level functions -- (that are k ~> Type). Useful because -- selectTC doesn't require anything fancy like TypeApplications -- to use. type SelectableTC t = Provable (Found (TyPP t)) -- | The canonical selecting function for SelectableTC t. -- -- Note that because t must be an injective type constructor, -- you can use this without explicit type applications; the instance of -- SelectableTC can be inferred from the result type. selectTC :: forall t. SelectableTC t => Prove (Found (TyPP t)) -- | If T :: k -> v -> Type is a type constructor, -- then SearchableTC T is a constraint that T is -- "searchable", in that you have a canonical function: -- --
--   searchTC :: Sing x -> Decision (Σ v (TyPP T x))
--   
-- -- That, given an x :: k, we can decide whether or not a y -- :: v exists that satisfies T x y. -- -- Is essentially Searchable, except with type constructors -- k -> Type instead of matchable type-level functions -- (that are k ~> Type). Useful because -- searchTC doesn't require anything fancy like TypeApplications -- to use. type SearchableTC t = Decidable (Found (TyPP t)) -- | The canonical selecting function for Searchable t. -- -- Note that because t must be an injective type constructor, -- you can use this without explicit type applications; the instance of -- SearchableTC can be inferred from the result type. searchTC :: forall t. SearchableTC t => Decide (Found (TyPP t)) -- | Disjunction on two ParamPreds, with appropriate -- Searchable instance. Priority is given to the left predicate. data OrP :: ParamPred k v -> ParamPred k v -> ParamPred k v -- | Conjunction on two ParamPreds, with appropriate -- Searchable and Selectable instances. data AndP :: ParamPred k v -> ParamPred k u -> ParamPred k (v, u) instance forall k1 v u (p :: Data.Type.Predicate.Param.ParamPred k1 v) (q :: Data.Type.Predicate.Param.ParamPred k1 u). (Data.Type.Predicate.Param.Searchable p, Data.Type.Predicate.Param.Searchable q) => Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.AndP p q)) instance forall k1 v u (p :: Data.Type.Predicate.Param.ParamPred k1 v) (q :: Data.Type.Predicate.Param.ParamPred k1 u). (Data.Type.Predicate.Param.Selectable p, Data.Type.Predicate.Param.Selectable q) => Data.Type.Predicate.Provable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.AndP p q)) instance forall k1 v (p :: Data.Type.Predicate.Param.ParamPred k1 v) (q :: Data.Type.Predicate.Param.ParamPred k1 v). (Data.Type.Predicate.Param.Searchable p, Data.Type.Predicate.Param.Searchable q) => Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.OrP p q)) instance forall k v (f :: * -> *) (p :: Data.Type.Predicate.Param.ParamPred k v). (Data.Type.Universe.Universe f, Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found p)) => Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.AnyMatch f p)) instance Data.Type.Universe.Universe f => Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.InP f)) instance Data.Type.Predicate.Decidable (Data.Type.Universe.NotNull f Data.Type.Predicate.Logic.==> Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.InP f)) instance Data.Type.Predicate.Provable (Data.Type.Universe.NotNull f Data.Type.Predicate.Logic.==> Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.InP f)) instance Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.InP f) Data.Type.Predicate.Logic.==> Data.Type.Universe.NotNull f) instance Data.Type.Predicate.Provable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.InP f) Data.Type.Predicate.Logic.==> Data.Type.Universe.NotNull f) instance forall j v (p :: Data.Type.Predicate.Param.ParamPred j v) k (f :: k Data.Singletons.~> j). (Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found p), Data.Singletons.SingI f) => Data.Type.Predicate.Decidable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.PPMap f p)) instance forall j v (p :: Data.Type.Predicate.Param.ParamPred j v) k (f :: k Data.Singletons.~> j). (Data.Type.Predicate.Provable (Data.Type.Predicate.Param.Found p), Data.Singletons.SingI f) => Data.Type.Predicate.Provable (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.PPMap f p)) -- | Useful utilities for situations where you know that a predicate -- P is satisfied for a specific a at compile-time. module Data.Type.Predicate.Auto -- | Automatically generate a witness for predicate p applied to -- input a. -- -- Mostly useful for situations where you know a at -- compile-time, so you can just write auto directly in your -- source code. The choice is intended to mirror the auto -- keyword in languages like Idris. -- -- Very close in nature to the Known typeclass in the -- type-combinators library. -- -- Admittedly this interface is a bit clunky and ad-hoc; at this point -- you can just try writing auto in your code and praying that it -- works. You always have the option, of course, to just manually write -- proofs. If you have any inference rules to suggest, feel free to -- submit a PR! -- -- An important limitation of Auto is the Haskell type system -- prevents "either-or" constraints; this could potentially be -- implemented using compiler plugins. -- -- One consequence of this is that it is impossible to automatically -- derive Any f p and Not (All f -- p). -- -- For these, the compiler needs help; you can use autoAny and -- autoNotAll for these situations. class Auto (p :: Predicate k) (a :: k) -- | Have the compiler generate a witness for p @@ a. -- -- Must be called using type application syntax: -- --
--   auto _ p @a
--   
auto :: Auto p a => p @@ a -- | A version of auto that "just works" with type inference, if the -- predicate is a type constructor. autoTC :: forall t a. Auto (TyPred t) a => t a -- | An AutoNot p a constraint means that p @@ a -- can be proven to not be true at compiletime. type AutoNot (p :: Predicate k) = Auto (Not p) -- | Disprove p @@ a at compiletime. -- --
--   autoNot @_ @p @a :: Not p @@ a
--   
autoNot :: forall k (p :: Predicate k) (a :: k). AutoNot p a => Not p @@ a -- | Helper function to generate an Any f p if you can pick -- out a specific a in as where the predicate is -- provable at compile-time. -- -- This is used to get around a fundamental limitation of Auto as -- a Haskell typeclass. autoAny :: forall f p as a. Auto p a => Elem f as a -> Any f p @@ as -- | Helper function to generate a Not (All f p) if -- you can pick out a specific a in as where the -- predicate is disprovable at compile-time. -- -- This is used to get around a fundamental limitation of Auto as -- a Haskell typeclass. autoNotAll :: forall p f as a. (AutoNot p a, SingI as) => Elem f as a -> Not (All f p) @@ as -- | Helper "predicate transformer" that gives you an instant auto -- for any Provable instance. -- -- For example, say you have predicate P that you know is -- Provable, and you wish to generate a P @@ x, for some -- specific x you know at compile-time. You can use: -- --
--   auto @_ @(AutoProvable P) @x
--   
-- -- to obtain a P @@ x. -- -- AutoProvable is essentially the identity function. data AutoProvable :: Predicate k -> Predicate k -- | Typeclass representing Elems pointing to an a :: k -- that can be generated automatically from type-level collection as -- :: f k. -- -- If GHC knows both the type-level collection and the element you want -- to find at compile-time, this instance should allow it to find it. -- -- Used to help in the instance of Auto for the In -- predicate. -- -- Example usage: -- --
--   autoElem :: Index '[1,6,2,3] 2
--   -- IS (IS IZ)        -- third spot
--   
-- -- And when used with Auto: -- --
--   auto @_ @(In [] '[1,6,2,3]) @2
--   -- IS (IS IZ)
--   
class AutoElem f (as :: f k) (a :: k) -- | Generate the Elem pointing to the a :: in a -- type-level collection as :: f k. autoElem :: AutoElem f as a => Elem f as a -- | Helper class for deriving Auto instances for All -- predicates; each Universe instance is expected to implement -- these if possible, to get free Auto instaces for their -- All predicates. -- -- Also helps for Not Any predicates and Not -- Found AnyMatch predicates. class AutoAll f (p :: Predicate k) (as :: f k) -- | Generate an All for a given predicate over all items in -- as. autoAll :: AutoAll f p as => All f p @@ as instance forall j k (p :: Data.Type.Predicate.Predicate j) (f :: k Data.Singletons.~> j) (a :: k). Data.Type.Predicate.Auto.AutoNot p (f Data.Singletons.@@ a) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Not (Data.Type.Predicate.PMap f p)) a instance forall k (p :: Data.Type.Predicate.Predicate k). Data.Type.Predicate.Auto.AutoAll [] p '[] instance forall a1 (p :: Data.Type.Predicate.Predicate a1) (a2 :: a1) (as :: [a1]). (Data.Type.Predicate.Auto.Auto p a2, Data.Type.Predicate.Auto.AutoAll [] p as) => Data.Type.Predicate.Auto.AutoAll [] p (a2 : as) instance forall k (p :: Data.Type.Predicate.Predicate k). Data.Type.Predicate.Auto.AutoAll GHC.Maybe.Maybe p 'GHC.Maybe.Nothing instance forall a1 (p :: Data.Type.Predicate.Predicate a1) (a2 :: a1). Data.Type.Predicate.Auto.Auto p a2 => Data.Type.Predicate.Auto.AutoAll GHC.Maybe.Maybe p ('GHC.Maybe.Just a2) instance forall k j (p :: Data.Type.Predicate.Predicate k) (e :: j). Data.Type.Predicate.Auto.AutoAll (Data.Either.Either j) p ('Data.Either.Left e) instance forall b (p :: Data.Type.Predicate.Predicate b) (a :: b) j. Data.Type.Predicate.Auto.Auto p a => Data.Type.Predicate.Auto.AutoAll (Data.Either.Either j) p ('Data.Either.Right a) instance forall a1 (p :: Data.Type.Predicate.Predicate a1) (a2 :: a1) (as :: [a1]). (Data.Type.Predicate.Auto.Auto p a2, Data.Type.Predicate.Auto.AutoAll [] p as) => Data.Type.Predicate.Auto.AutoAll GHC.Base.NonEmpty p (a2 'GHC.Base.:| as) instance forall k (p :: Data.Type.Predicate.Predicate k) (a :: k) j (w :: j). Data.Type.Predicate.Auto.Auto p a => Data.Type.Predicate.Auto.AutoAll ((,) j) p '(w, a) instance forall a1 (p :: Data.Type.Predicate.Predicate a1) (a2 :: a1). Data.Type.Predicate.Auto.Auto p a2 => Data.Type.Predicate.Auto.AutoAll Data.Functor.Identity.Identity p ('Data.Functor.Identity.Identity a2) instance forall k (f :: * -> *) (p :: Data.Type.Predicate.Predicate k) (as :: f k). Data.Type.Predicate.Auto.AutoAll f p as => Data.Type.Predicate.Auto.Auto (Data.Type.Universe.All f p) as instance forall k (f :: * -> *) (as :: f k) (p :: Data.Type.Predicate.Predicate k). (Data.Singletons.SingI as, Data.Type.Predicate.Auto.AutoAll f (Data.Type.Predicate.Not p) as) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Not (Data.Type.Universe.Any f p)) as instance forall k v (f :: * -> *) (as :: f k) (p :: Data.Type.Predicate.Param.ParamPred k v). (Data.Singletons.SingI as, Data.Type.Predicate.Auto.AutoAll f (Data.Type.Predicate.Not (Data.Type.Predicate.Param.Found p)) as) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Not (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.AnyMatch f p))) as instance forall k (a :: k) (as :: [k]). Data.Type.Predicate.Auto.AutoElem [] (a : as) a instance forall k (as :: [k]) (a :: k) (b :: k). Data.Type.Predicate.Auto.AutoElem [] as a => Data.Type.Predicate.Auto.AutoElem [] (b : as) a instance forall k (a :: k). Data.Type.Predicate.Auto.AutoElem GHC.Maybe.Maybe ('GHC.Maybe.Just a) a instance forall k j (a :: k). Data.Type.Predicate.Auto.AutoElem (Data.Either.Either j) ('Data.Either.Right a) a instance forall k (a :: k) (as :: [k]). Data.Type.Predicate.Auto.AutoElem GHC.Base.NonEmpty (a 'GHC.Base.:| as) a instance forall k (as :: [k]) (a :: k) (b :: k). Data.Type.Predicate.Auto.AutoElem [] as a => Data.Type.Predicate.Auto.AutoElem GHC.Base.NonEmpty (b 'GHC.Base.:| as) a instance forall k j (w :: j) (a :: k). Data.Type.Predicate.Auto.AutoElem ((,) j) '(w, a) a instance forall k (a :: k). Data.Type.Predicate.Auto.AutoElem Data.Functor.Identity.Identity ('Data.Functor.Identity.Identity a) a instance forall k (f :: * -> *) (as :: f k) (a :: k). Data.Type.Predicate.Auto.AutoElem f as a => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.In f as) a instance forall k (p :: k Data.Singletons.~> *) (a :: k). (Data.Type.Predicate.Provable p, Data.Singletons.SingI a) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Auto.AutoProvable p) a instance forall k (a :: k). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto Data.Type.Predicate.Evident a instance forall k (a :: k). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Not Data.Type.Predicate.Impossible) a instance forall k (a :: k). Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.EqualTo a) a instance forall k (p :: Data.Type.Predicate.Predicate k) (a :: k) (q :: Data.Type.Predicate.Predicate k). (Data.Type.Predicate.Auto.Auto p a, Data.Type.Predicate.Auto.Auto q a) => Data.Type.Predicate.Auto.Auto (p Data.Type.Predicate.Logic.&&& q) a instance forall k (q :: Data.Type.Predicate.Predicate k) (a :: k) (p :: Data.Type.Predicate.Predicate k). Data.Type.Predicate.Auto.Auto q a => Data.Type.Predicate.Auto.Auto (p Data.Type.Predicate.Logic.==> q) a instance forall k (a :: k) (as :: [k]). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto (Data.Type.Universe.NotNull []) (a : as) instance forall k (a :: k). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto Data.Type.Universe.IsJust ('GHC.Maybe.Just a) instance forall k j (a :: k). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto Data.Type.Universe.IsRight ('Data.Either.Right a) instance forall k (a :: k) (as :: [k]). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto (Data.Type.Universe.NotNull GHC.Base.NonEmpty) (a 'GHC.Base.:| as) instance forall k (a :: k) j (w :: j). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto (Data.Type.Universe.NotNull ((,) j)) '(w, a) instance forall k (a :: k). Data.Singletons.SingI a => Data.Type.Predicate.Auto.Auto (Data.Type.Universe.NotNull Data.Functor.Identity.Identity) ('Data.Functor.Identity.Identity a) instance forall j v k (p :: Data.Type.Predicate.Param.ParamPred j v) (f :: k Data.Singletons.~> j) (a :: k). Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Param.Found p) (f Data.Singletons.@@ a) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Param.Found (Data.Type.Predicate.Param.PPMap f p)) a instance forall j v k (p :: Data.Type.Predicate.Param.ParamPred j v) (f :: k Data.Singletons.~> j) (a :: k). Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Param.NotFound p) (f Data.Singletons.@@ a) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.Param.NotFound (Data.Type.Predicate.Param.PPMap f p)) a instance forall j k (p :: Data.Type.Predicate.Predicate j) (f :: k Data.Singletons.~> j) (a :: k). Data.Type.Predicate.Auto.Auto p (f Data.Singletons.@@ a) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.PMap f p) a instance forall u (as :: [u]). Data.Singletons.SingI as => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Vinyl.Core.Rec Data.Singletons.WrappedSing)) as instance forall k (as :: GHC.Maybe.Maybe k). Data.Singletons.SingI as => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PMaybe Data.Singletons.WrappedSing)) as instance forall k (as :: GHC.Base.NonEmpty k). Data.Singletons.SingI as => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.NERec Data.Singletons.WrappedSing)) as instance forall j k (as :: Data.Either.Either j k). Data.Singletons.SingI as => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PEither Data.Singletons.WrappedSing)) as instance forall j k (as :: (j, k)). Data.Singletons.SingI as => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PTup Data.Singletons.WrappedSing)) as instance forall k (as :: Data.Functor.Identity.Identity k). Data.Singletons.SingI as => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PIdentity Data.Singletons.WrappedSing)) as instance forall u (as :: [u]) (p :: u Data.Singletons.~> *). (Data.Singletons.SingI as, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Vinyl.Core.Rec (Data.Type.Predicate.Wit p))) as instance forall k (as :: GHC.Maybe.Maybe k) (p :: k Data.Singletons.~> *). (Data.Singletons.SingI as, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PMaybe (Data.Type.Predicate.Wit p))) as instance forall k (as :: GHC.Base.NonEmpty k) (p :: k Data.Singletons.~> *). (Data.Singletons.SingI as, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.NERec (Data.Type.Predicate.Wit p))) as instance forall j k (as :: Data.Either.Either j k) (p :: k Data.Singletons.~> *). (Data.Singletons.SingI as, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PEither (Data.Type.Predicate.Wit p))) as instance forall j k (as :: (j, k)) (p :: k Data.Singletons.~> *). (Data.Singletons.SingI as, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PTup (Data.Type.Predicate.Wit p))) as instance forall k (as :: Data.Functor.Identity.Identity k) (p :: k Data.Singletons.~> *). (Data.Singletons.SingI as, Data.Type.Predicate.Provable p) => Data.Type.Predicate.Auto.Auto (Data.Type.Predicate.TyPred (Data.Type.Functor.Product.PIdentity (Data.Type.Predicate.Wit p))) as -- | Represent a decidable subset of a type-level collection. module Data.Type.Universe.Subset -- | A Subset f p is a predicate that some decidable subset -- of an input as is true. data Subset f :: (k ~> Type) -> (f k ~> Type) -- | A WitSubset f p as describes a -- decidable subset of type-level collection as. newtype WitSubset f p (as :: f k) WitSubset :: (forall a. Elem f as a -> Decision (p @@ a)) -> WitSubset f p (as :: f k) [runWitSubset] :: WitSubset f p (as :: f k) -> forall a. Elem f as a -> Decision (p @@ a) -- | Create a Subset from a predicate. makeSubset :: forall f k p (as :: f k). Universe f => (forall a. Elem f as a -> Sing a -> Decision (p @@ a)) -> Sing as -> Subset f p @@ as -- | Subset intersection intersection :: forall f p q. () => (Subset f p &&& Subset f q) --> Subset f (p &&& q) -- | Subset union (left-biased) union :: forall f p q. () => (Subset f p &&& Subset f q) --> Subset f (p ||| q) -- | Symmetric subset difference symDiff :: forall f p q. () => (Subset f p &&& Subset f q) --> Subset f (p ^^^ q) -- | Combine two subsets based on a decision function mergeSubset :: forall f k p q r (as :: f k). () => (forall a. Decision (p @@ a) -> Decision (q @@ a) -> Decision (r @@ a)) -> (Subset f p @@ as) -> (Subset f q @@ as) -> Subset f r @@ as -- | Combine two subsets based on a decision function imergeSubset :: forall f k p q r (as :: f k). () => (forall a. Elem f as a -> Decision (p @@ a) -> Decision (q @@ a) -> Decision (r @@ a)) -> (Subset f p @@ as) -> (Subset f q @@ as) -> Subset f r @@ as -- | Map a bidirectional implication over a subset described by that -- implication. -- -- Implication needs to be bidirectional, or otherwise we can't produce a -- decidable subset as a result. mapSubset :: Universe f => (p --> q) -> (q --> p) -> Subset f p --> Subset f q -- | mapSubset, but providing an Elem. imapSubset :: (forall a. Elem f as a -> (p @@ a) -> q @@ a) -> (forall a. Elem f as a -> (q @@ a) -> p @@ a) -> (Subset f p @@ as) -> Subset f q @@ as -- | Turn a Subset into a list (or any Alternative) of -- satisfied predicates. -- -- List is meant to include no duplicates. subsetToList :: forall f p t. (Universe f, Alternative t) => (Subset f p --># Any f p) t -- | Restrict a Subset to a single (arbitrary) member, or fail if -- none exists. subsetToAny :: forall f p. Universe f => Subset f p -?> Any f p -- | Test if a subset is equal to the entire original collection subsetToAll :: forall f p. Universe f => Subset f p -?> All f p -- | Test if a subset is empty. subsetToNone :: forall f p. Universe f => Subset f p -?> None f p -- | Construct an empty subset. emptySubset :: forall f as. (Universe f, SingI as) => Subset f Impossible @@ as -- | Construct a full subset fullSubset :: forall f as. (Universe f, SingI as) => Subset f Evident @@ as instance forall k (f :: * -> *) (p :: k Data.Singletons.~> *). (Data.Type.Universe.Universe f, Data.Type.Predicate.Decidable p) => Data.Type.Predicate.Decidable (Data.Type.Universe.Subset.Subset f p) instance forall k (f :: * -> *) (p :: k Data.Singletons.~> *). (Data.Type.Universe.Universe f, Data.Type.Predicate.Decidable p) => Data.Type.Predicate.Provable (Data.Type.Universe.Subset.Subset f p)