Copyright | (C) 2013 Richard Eisenberg |
---|---|
License | BSD-style (see LICENSE) |
Maintainer | Ryan Scott |
Stability | experimental |
Portability | non-portable |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
This module exports the basic definitions to use singletons. See also
Prelude.Singletons
from the singletons-base
library, which re-exports this module alongside many singled definitions
based on the Prelude.
You may also want to read the original papers presenting this library, available at https://richarde.dev/papers/2012/singletons/paper.pdf and https://richarde.dev/papers/2014/promotion/promotion.pdf.
Synopsis
- type family Sing :: k -> Type
- newtype SLambda (f :: k1 ~> k2) = SLambda {}
- (@@) :: forall k1 k2 (f :: k1 ~> k2) (t :: k1). Sing f -> Sing t -> Sing (f @@ t)
- class SingI a where
- class (forall x. SingI x => SingI (f x)) => SingI1 f where
- sing1 :: (SingI1 f, SingI x) => Sing (f x)
- class (forall x y. (SingI x, SingI y) => SingI (f x y)) => SingI2 f where
- sing2 :: (SingI2 f, SingI x, SingI y) => Sing (f x y)
- class SingKind k where
- type KindOf (a :: k) = k
- type SameKind (a :: k) (b :: k) = () :: Constraint
- data SingInstance (a :: k) where
- SingInstance :: SingI a => SingInstance a
- data SomeSing k where
- singInstance :: forall k (a :: k). Sing a -> SingInstance a
- pattern Sing :: forall k (a :: k). () => SingI a => Sing a
- withSingI :: Sing n -> (SingI n => r) -> r
- withSomeSing :: forall k r. SingKind k => Demote k -> (forall (a :: k). Sing a -> r) -> r
- pattern FromSing :: SingKind k => forall (a :: k). Sing a -> Demote k
- usingSingI1 :: forall f x r. (SingI1 f, SingI x) => (SingI (f x) => r) -> r
- usingSingI2 :: forall f x y r. (SingI2 f, SingI x, SingI y) => (SingI (f x y) => r) -> r
- singByProxy :: SingI a => proxy a -> Sing a
- singByProxy1 :: (SingI1 f, SingI x) => proxy (f x) -> Sing (f x)
- singByProxy2 :: (SingI2 f, SingI x, SingI y) => proxy (f x y) -> Sing (f x y)
- demote :: forall {k} (a :: k). (SingKind k, SingI a) => Demote k
- demote1 :: forall {k1} {k2} (f :: k1 -> k2) (x :: k1). (SingKind k2, SingI1 f, SingI x) => Demote k2
- demote2 :: forall {k1} {k2} {k3} (f :: k1 -> k2 -> k3) (x :: k1) (y :: k2). (SingKind k3, SingI2 f, SingI x, SingI y) => Demote k3
- singByProxy# :: SingI a => Proxy# a -> Sing a
- singByProxy1# :: (SingI1 f, SingI x) => Proxy# (f x) -> Sing (f x)
- singByProxy2# :: (SingI2 f, SingI x, SingI y) => Proxy# (f x y) -> Sing (f x y)
- withSing :: SingI a => (Sing a -> b) -> b
- withSing1 :: (SingI1 f, SingI x) => (Sing (f x) -> b) -> b
- withSing2 :: (SingI2 f, SingI x, SingI y) => (Sing (f x y) -> b) -> b
- singThat :: forall k (a :: k). (SingKind k, SingI a) => (Demote k -> Bool) -> Maybe (Sing a)
- singThat1 :: forall k1 k2 (f :: k1 -> k2) (x :: k1). (SingKind k2, SingI1 f, SingI x) => (Demote k2 -> Bool) -> Maybe (Sing (f x))
- singThat2 :: forall k1 k2 k3 (f :: k1 -> k2 -> k3) (x :: k1) (y :: k2). (SingKind k3, SingI2 f, SingI x, SingI y) => (Demote k3 -> Bool) -> Maybe (Sing (f x y))
- newtype WrappedSing :: forall k. k -> Type where
- WrapSing :: forall k (a :: k). {..} -> WrappedSing a
- newtype SWrappedSing :: forall k (a :: k). WrappedSing a -> Type where
- SWrapSing :: forall k (a :: k) (ws :: WrappedSing a). {..} -> SWrappedSing ws
- type family UnwrapSing (ws :: WrappedSing (a :: k)) :: Sing a where ...
- data TyFun :: Type -> Type -> Type
- type (~>) a b = TyFun a b -> Type
- type TyCon1 = TyCon :: (k1 -> k2) -> k1 ~> k2
- type TyCon2 = TyCon :: (k1 -> k2 -> k3) -> k1 ~> (k2 ~> k3)
- type TyCon3 = TyCon :: (k1 -> k2 -> k3 -> k4) -> k1 ~> (k2 ~> (k3 ~> k4))
- type TyCon4 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> k5)))
- type TyCon5 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> k6))))
- type TyCon6 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> k7)))))
- type TyCon7 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7 -> k8) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> k8))))))
- type TyCon8 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7 -> k8 -> k9) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> (k8 ~> k9)))))))
- type family Apply (f :: k1 ~> k2) (x :: k1) :: k2
- type (@@) a b = Apply a b
- data family TyCon :: (k1 -> k2) -> unmatchable_fun
- type family ApplyTyCon :: (k1 -> k2) -> k1 ~> unmatchable_fun where ...
- data ApplyTyConAux1 :: (k1 -> k2) -> k1 ~> k2
- data ApplyTyConAux2 :: (k1 -> k2 -> k3) -> k1 ~> unmatchable_fun
- singFun1 :: forall f. SingFunction1 f -> Sing f
- singFun2 :: forall f. SingFunction2 f -> Sing f
- singFun3 :: forall f. SingFunction3 f -> Sing f
- singFun4 :: forall f. SingFunction4 f -> Sing f
- singFun5 :: forall f. SingFunction5 f -> Sing f
- singFun6 :: forall f. SingFunction6 f -> Sing f
- singFun7 :: forall f. SingFunction7 f -> Sing f
- singFun8 :: forall f. SingFunction8 f -> Sing f
- unSingFun1 :: forall f. Sing f -> SingFunction1 f
- unSingFun2 :: forall f. Sing f -> SingFunction2 f
- unSingFun3 :: forall f. Sing f -> SingFunction3 f
- unSingFun4 :: forall f. Sing f -> SingFunction4 f
- unSingFun5 :: forall f. Sing f -> SingFunction5 f
- unSingFun6 :: forall f. Sing f -> SingFunction6 f
- unSingFun7 :: forall f. Sing f -> SingFunction7 f
- unSingFun8 :: forall f. Sing f -> SingFunction8 f
- pattern SLambda2 :: forall f. SingFunction2 f -> Sing f
- applySing2 :: forall {a1} {a2} {b} (f :: a1 ~> (a2 ~> b)). Sing f -> SingFunction2 f
- pattern SLambda3 :: forall f. SingFunction3 f -> Sing f
- applySing3 :: forall {a1} {a2} {a3} {b} (f :: a1 ~> (a2 ~> (a3 ~> b))). Sing f -> SingFunction3 f
- pattern SLambda4 :: forall f. SingFunction4 f -> Sing f
- applySing4 :: forall {a1} {a2} {a3} {a4} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> b)))). Sing f -> SingFunction4 f
- pattern SLambda5 :: forall f. SingFunction5 f -> Sing f
- applySing5 :: forall {a1} {a2} {a3} {a4} {a5} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> b))))). Sing f -> SingFunction5 f
- pattern SLambda6 :: forall f. SingFunction6 f -> Sing f
- applySing6 :: forall {a1} {a2} {a3} {a4} {a5} {a6} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> b)))))). Sing f -> SingFunction6 f
- pattern SLambda7 :: forall f. SingFunction7 f -> Sing f
- applySing7 :: forall {a1} {a2} {a3} {a4} {a5} {a6} {a7} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> b))))))). Sing f -> SingFunction7 f
- pattern SLambda8 :: forall f. SingFunction8 f -> Sing f
- applySing8 :: forall {a1} {a2} {a3} {a4} {a5} {a6} {a7} {a8} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> (a8 ~> b)))))))). Sing f -> SingFunction8 f
- type SingFunction1 (f :: a1 ~> b) = forall t. Sing t -> Sing (f @@ t)
- type SingFunction2 (f :: a1 ~> (a2 ~> b)) = forall t1 t2. Sing t1 -> Sing t2 -> Sing ((f @@ t1) @@ t2)
- type SingFunction3 (f :: a1 ~> (a2 ~> (a3 ~> b))) = forall t1 t2 t3. Sing t1 -> Sing t2 -> Sing t3 -> Sing (((f @@ t1) @@ t2) @@ t3)
- type SingFunction4 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> b)))) = forall t1 t2 t3 t4. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing ((((f @@ t1) @@ t2) @@ t3) @@ t4)
- type SingFunction5 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> b))))) = forall t1 t2 t3 t4 t5. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing (((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5)
- type SingFunction6 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> b)))))) = forall t1 t2 t3 t4 t5 t6. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing t6 -> Sing ((((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5) @@ t6)
- type SingFunction7 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> b))))))) = forall t1 t2 t3 t4 t5 t6 t7. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing t6 -> Sing t7 -> Sing (((((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5) @@ t6) @@ t7)
- type SingFunction8 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> (a8 ~> b)))))))) = forall t1 t2 t3 t4 t5 t6 t7 t8. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing t6 -> Sing t7 -> Sing t8 -> Sing ((((((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5) @@ t6) @@ t7) @@ t8)
- data Proxy (t :: k) = Proxy
- data DemoteSym0 :: Type ~> Type
- type DemoteSym1 x = Demote x
- data SameKindSym0 :: forall k. k ~> (k ~> Constraint)
- data SameKindSym1 :: forall k. k -> k ~> Constraint
- type SameKindSym2 (x :: k) (y :: k) = SameKind x y
- data KindOfSym0 :: forall k. k ~> Type
- type KindOfSym1 (x :: k) = KindOf x
- data (~>@#@$) :: Type ~> (Type ~> Type)
- data (~>@#@$$) :: Type -> Type ~> Type
- type (~>@#@$$$) x y = x ~> y
- data ApplySym0 :: forall a b. (a ~> b) ~> (a ~> b)
- data ApplySym1 :: forall a b. (a ~> b) -> a ~> b
- type ApplySym2 (f :: a ~> b) (x :: a) = Apply f x
- data (@@@#@$) :: forall a b. (a ~> b) ~> (a ~> b)
- data (@@@#@$$) :: forall a b. (a ~> b) -> a ~> b
- type (@@@#@$$$) (f :: a ~> b) (x :: a) = f @@ x
Main singleton definitions
type family Sing :: k -> Type Source #
The singleton kind-indexed type family.
Instances
type Sing Source # | |
Defined in Data.Singletons | |
type Sing Source # | |
Defined in Data.Singletons | |
type Sing Source # | |
Defined in Data.Singletons.Sigma |
newtype SLambda (f :: k1 ~> k2) Source #
The singleton type for functions. Functions have somewhat special
treatment in singletons
(see the Haddocks for (
for more information
about this), and as a result, the ~>
)Sing
instance for SLambda
is one of the
only such instances defined in the singletons
library rather than, say,
singletons-base
.
(@@) :: forall k1 k2 (f :: k1 ~> k2) (t :: k1). Sing f -> Sing t -> Sing (f @@ t) infixl 9 Source #
An infix synonym for applySing
A SingI
constraint is essentially an implicitly-passed singleton.
In contrast to the SingKind
class, which is parameterized over data types
promoted to the kind level, the SingI
class is parameterized over values
promoted to the type level. To explain this distinction another way, consider
this code:
f = fromSing (sing @(T :: K))
Here, f
uses methods from both SingI
and SingKind
. However, the shape
of each constraint is rather different: using sing
requires a 'SingI T'
constraint, whereas using fromSing
requires a 'SingKind K' constraint.
If you need to satisfy this constraint with an explicit singleton, please
see withSingI
or the Sing
pattern synonym.
Produce the singleton explicitly. You will likely need the ScopedTypeVariables
extension to use this method the way you want.
Instances
SingI a => SingI ('WrapSing s :: WrappedSing a) Source # | |
(forall (a :: k1). SingI a => SingI (f a), (ApplyTyCon :: (k1 -> kr) -> TyFun k1 kr -> Type) ~ (ApplyTyConAux1 :: (k1 -> kr) -> TyFun k1 kr -> Type)) => SingI (TyCon1 f :: TyFun k1 kr -> Type) Source # | |
(forall (a :: k1) (b :: k2). (SingI a, SingI b) => SingI (f a b), (ApplyTyCon :: (k2 -> kr) -> TyFun k2 kr -> Type) ~ (ApplyTyConAux1 :: (k2 -> kr) -> TyFun k2 kr -> Type)) => SingI (TyCon2 f :: TyFun k1 (k2 ~> kr) -> Type) Source # | |
(SingI fst, SingI b) => SingI (a ':&: b :: Sigma s t) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3). (SingI a, SingI b, SingI c) => SingI (f a b c), (ApplyTyCon :: (k3 -> kr) -> TyFun k3 kr -> Type) ~ (ApplyTyConAux1 :: (k3 -> kr) -> TyFun k3 kr -> Type)) => SingI (TyCon3 f :: TyFun k1 (k2 ~> (k3 ~> kr)) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4). (SingI a, SingI b, SingI c, SingI d) => SingI (f a b c d), (ApplyTyCon :: (k4 -> kr) -> TyFun k4 kr -> Type) ~ (ApplyTyConAux1 :: (k4 -> kr) -> TyFun k4 kr -> Type)) => SingI (TyCon4 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> kr))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5). (SingI a, SingI b, SingI c, SingI d, SingI e) => SingI (f a b c d e), (ApplyTyCon :: (k5 -> kr) -> TyFun k5 kr -> Type) ~ (ApplyTyConAux1 :: (k5 -> kr) -> TyFun k5 kr -> Type)) => SingI (TyCon5 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> kr)))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f') => SingI (f a b c d e f'), (ApplyTyCon :: (k6 -> kr) -> TyFun k6 kr -> Type) ~ (ApplyTyConAux1 :: (k6 -> kr) -> TyFun k6 kr -> Type)) => SingI (TyCon6 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> kr))))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6) (g :: k7). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f', SingI g) => SingI (f a b c d e f' g), (ApplyTyCon :: (k7 -> kr) -> TyFun k7 kr -> Type) ~ (ApplyTyConAux1 :: (k7 -> kr) -> TyFun k7 kr -> Type)) => SingI (TyCon7 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> kr)))))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6) (g :: k7) (h :: k8). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f', SingI g, SingI h) => SingI (f a b c d e f' g h), (ApplyTyCon :: (k8 -> kr) -> TyFun k8 kr -> Type) ~ (ApplyTyConAux1 :: (k8 -> kr) -> TyFun k8 kr -> Type)) => SingI (TyCon8 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> (k8 ~> kr))))))) -> Type) Source # | |
class (forall x. SingI x => SingI (f x)) => SingI1 f where Source #
A version of the SingI
class lifted to unary type constructors.
class (forall x y. (SingI x, SingI y) => SingI (f x y)) => SingI2 f where Source #
A version of the SingI
class lifted to binary type constructors.
class SingKind k where Source #
The SingKind
class is a kind class. It classifies all kinds
for which singletons are defined. The class supports converting between a singleton
type and the base (unrefined) type which it is built from.
For a SingKind
instance to be well behaved, it should obey the following laws:
toSing
.fromSing
≡SomeSing
(\x ->withSomeSing
xfromSing
) ≡id
The final law can also be expressed in terms of the FromSing
pattern
synonym:
(\(FromSing
sing) ->FromSing
sing) ≡id
type Demote k = (r :: Type) | r -> k Source #
Get a base type from the promoted kind. For example,
Demote Bool
will be the type Bool
. Rarely, the type and kind do not
match. For example, Demote Nat
is Natural
.
fromSing :: Sing (a :: k) -> Demote k Source #
Convert a singleton to its unrefined version.
toSing :: Demote k -> SomeSing k Source #
Convert an unrefined type to an existentially-quantified singleton type.
Instances
SingKind (WrappedSing a) Source # | |
Defined in Data.Singletons type Demote (WrappedSing a) = (r :: Type) Source # fromSing :: forall (a0 :: WrappedSing a). Sing a0 -> Demote (WrappedSing a) Source # toSing :: Demote (WrappedSing a) -> SomeSing (WrappedSing a) Source # | |
(SingKind k1, SingKind k2) => SingKind (k1 ~> k2) Source # | Note that this instance's |
Working with singletons
type KindOf (a :: k) = k Source #
Convenient synonym to refer to the kind of a type variable:
type KindOf (a :: k) = k
type SameKind (a :: k) (b :: k) = () :: Constraint Source #
Force GHC to unify the kinds of a
and b
. Note that SameKind a b
is
different from KindOf a ~ KindOf b
in that the former makes the kinds
unify immediately, whereas the latter is a proposition that GHC considers
as possibly false.
data SingInstance (a :: k) where Source #
A SingInstance
wraps up a SingI
instance for explicit handling.
SingInstance :: SingI a => SingInstance a |
data SomeSing k where Source #
An existentially-quantified singleton. This type is useful when you want a singleton type, but there is no way of knowing, at compile-time, what the type index will be. To make use of this type, you will generally have to use a pattern-match:
foo :: Bool -> ... foo b = case toSing b of SomeSing sb -> {- fancy dependently-typed code with sb -}
An example like the one above may be easier to write using withSomeSing
.
singInstance :: forall k (a :: k). Sing a -> SingInstance a Source #
Get an implicit singleton (a SingI
instance) from an explicit one.
pattern Sing :: forall k (a :: k). () => SingI a => Sing a Source #
An explicitly bidirectional pattern synonym for implicit singletons.
As an expression: Constructs a singleton Sing a
given a
implicit singleton constraint SingI a
.
As a pattern: Matches on an explicit Sing a
witness bringing
an implicit SingI a
constraint into scope.
withSingI :: Sing n -> (SingI n => r) -> r Source #
Convenience function for creating a context with an implicit singleton available.
:: forall k r. SingKind k | |
=> Demote k | The original datatype |
-> (forall (a :: k). Sing a -> r) | Function expecting a singleton |
-> r |
Convert a normal datatype (like Bool
) to a singleton for that datatype,
passing it into a continuation.
pattern FromSing :: SingKind k => forall (a :: k). Sing a -> Demote k Source #
An explicitly bidirectional pattern synonym for going between a singleton and the corresponding demoted term.
As an expression: this takes a singleton to its demoted (base) type.
>>>
:t FromSing \@Bool
FromSing \@Bool :: Sing a -> Bool>>>
FromSing SFalse
False
As a pattern: It extracts a singleton from its demoted (base) type.
singAnd ::Bool
->Bool
->SomeSing
Bool
singAnd (FromSing
singBool1) (FromSing
singBool2) =SomeSing
(singBool1 %&& singBool2)
instead of writing it with withSomeSing
:
singAnd bool1 bool2 =withSomeSing
bool1 $ singBool1 ->withSomeSing
bool2 $ singBool2 ->SomeSing
(singBool1 %&& singBool2)
singByProxy :: SingI a => proxy a -> Sing a Source #
Allows creation of a singleton when a proxy is at hand.
singByProxy1 :: (SingI1 f, SingI x) => proxy (f x) -> Sing (f x) Source #
Allows creation of a singleton for a unary type constructor when a proxy is at hand.
singByProxy2 :: (SingI2 f, SingI x, SingI y) => proxy (f x y) -> Sing (f x y) Source #
Allows creation of a singleton for a binary type constructor when a proxy is at hand.
demote :: forall {k} (a :: k). (SingKind k, SingI a) => Demote k Source #
A convenience function that takes a type as input and demotes it to its
value-level counterpart as output. This uses SingKind
and SingI
behind
the scenes, so
.demote
= fromSing
sing
This function is intended to be used with TypeApplications
. For example:
>>>
demote @True
True
>>>
demote @(Nothing :: Maybe Ordering)
Nothing
>>>
demote @(Just EQ)
Just EQ
>>>
demote @'(True,EQ)
(True,EQ)
demote1 :: forall {k1} {k2} (f :: k1 -> k2) (x :: k1). (SingKind k2, SingI1 f, SingI x) => Demote k2 Source #
A convenience function that takes a unary type constructor and its
argument as input, applies them, and demotes the result to its
value-level counterpart as output. This uses SingKind
, SingI1
, and
SingI
behind the scenes, so
.demote1
= fromSing
sing1
This function is intended to be used with TypeApplications
. For example:
>>>
demote1 @Just @EQ
Just EQ
>>>
demote1 @('(,) True) @EQ
(True,EQ)
demote2 :: forall {k1} {k2} {k3} (f :: k1 -> k2 -> k3) (x :: k1) (y :: k2). (SingKind k3, SingI2 f, SingI x, SingI y) => Demote k3 Source #
A convenience function that takes a binary type constructor and its
arguments as input, applies them, and demotes the result to its
value-level counterpart as output. This uses SingKind
, SingI2
, and
SingI
behind the scenes, so
.demote2
= fromSing
sing2
This function is intended to be used with TypeApplications
. For example:
>>>
demote2 @'(,) @True @EQ
(True,EQ)
singByProxy# :: SingI a => Proxy# a -> Sing a Source #
Allows creation of a singleton when a proxy#
is at hand.
singByProxy1# :: (SingI1 f, SingI x) => Proxy# (f x) -> Sing (f x) Source #
Allows creation of a singleton for a unary type constructor when a
proxy#
is at hand.
singByProxy2# :: (SingI2 f, SingI x, SingI y) => Proxy# (f x y) -> Sing (f x y) Source #
Allows creation of a singleton for a binary type constructor when a
proxy#
is at hand.
withSing :: SingI a => (Sing a -> b) -> b Source #
A convenience function useful when we need to name a singleton value
multiple times. Without this function, each use of sing
could potentially
refer to a different singleton, and one has to use type signatures (often
with ScopedTypeVariables
) to ensure that they are the same.
withSing1 :: (SingI1 f, SingI x) => (Sing (f x) -> b) -> b Source #
A convenience function useful when we need to name a singleton value for a
unary type constructor multiple times. Without this function, each use of
sing1
could potentially refer to a different singleton, and one has to use
type signatures (often with ScopedTypeVariables
) to ensure that they are
the same.
withSing2 :: (SingI2 f, SingI x, SingI y) => (Sing (f x y) -> b) -> b Source #
A convenience function useful when we need to name a singleton value for a
binary type constructor multiple times. Without this function, each use of
sing1
could potentially refer to a different singleton, and one has to use
type signatures (often with ScopedTypeVariables
) to ensure that they are
the same.
singThat :: forall k (a :: k). (SingKind k, SingI a) => (Demote k -> Bool) -> Maybe (Sing a) Source #
A convenience function that names a singleton satisfying a certain
property. If the singleton does not satisfy the property, then the function
returns Nothing
. The property is expressed in terms of the underlying
representation of the singleton.
singThat1 :: forall k1 k2 (f :: k1 -> k2) (x :: k1). (SingKind k2, SingI1 f, SingI x) => (Demote k2 -> Bool) -> Maybe (Sing (f x)) Source #
A convenience function that names a singleton for a unary type constructor
satisfying a certain property. If the singleton does not satisfy the
property, then the function returns Nothing
. The property is expressed in
terms of the underlying representation of the singleton.
singThat2 :: forall k1 k2 k3 (f :: k1 -> k2 -> k3) (x :: k1) (y :: k2). (SingKind k3, SingI2 f, SingI x, SingI y) => (Demote k3 -> Bool) -> Maybe (Sing (f x y)) Source #
A convenience function that names a singleton for a binary type constructor
satisfying a certain property. If the singleton does not satisfy the
property, then the function returns Nothing
. The property is expressed in
terms of the underlying representation of the singleton.
WrappedSing
newtype WrappedSing :: forall k. k -> Type where Source #
A newtype around Sing
.
Since Sing
is a type family, it cannot be used directly in type class
instances. As one example, one cannot write a catch-all
instance
. On the other hand,
SDecide
k => TestEquality
(Sing
k)WrappedSing
is a perfectly ordinary data type, which means that it is
quite possible to define an
instance
.SDecide
k => TestEquality
(WrappedSing
k)
WrapSing | |
|
Instances
newtype SWrappedSing :: forall k (a :: k). WrappedSing a -> Type where Source #
The singleton for WrappedSing
s. Informally, this is the singleton type
for other singletons.
SWrapSing | |
|
Instances
ShowSing k => Show (SWrappedSing ws) Source # | |
Defined in Data.Singletons.ShowSing showsPrec :: Int -> SWrappedSing ws -> ShowS # show :: SWrappedSing ws -> String # showList :: [SWrappedSing ws] -> ShowS # |
type family UnwrapSing (ws :: WrappedSing (a :: k)) :: Sing a where ... Source #
UnwrapSing ('WrapSing s) = s |
Aside from being a data type to hang instances off of, WrappedSing
has
another purpose as a general-purpose mechanism for allowing one to write
code that uses singletons of other singletons. For instance, suppose you
had the following data type:
data T :: Type -> Type where
MkT :: forall a (x :: a). Sing
x -> F a -> T a
A naïve attempt at defining a singleton for T
would look something like
this:
data ST :: forall a. T a -> Type where SMkT :: forall a (x :: a) (sx ::Sing
x) (f :: F a).Sing
sx ->Sing
f -> ST (MkT sx f)
But there is a problem here: what exactly is
? If Sing
sxx
were True
,
for instance, then sx
would be STrue
, but it's not clear what
should be. One could define Sing
STrue
SSBool
to be the singleton of
SBool
s, but in order to be thorough, one would have to generate a singleton
for every singleton type out there. Plus, it's not clear when to stop. Should
we also generate SSSBool
, SSSSBool
, etc.?
Instead, WrappedSing
and its singleton SWrappedSing
provide a way to talk
about singletons of other arbitrary singletons without the need to generate a
bazillion instances. For reference, here is the definition of SWrappedSing
:
newtypeSWrappedSing
:: forall k (a :: k).WrappedSing
a -> Type whereSWrapSing
:: forall k (a :: k) (ws ::WrappedSing
a). {sUnwrapSing
::Sing
a } ->SWrappedSing
ws type instanceSing
@(WrappedSing
a) =SWrappedSing
SWrappedSing
is a bit of an unusual singleton in that its field is a
singleton for
, not Sing
@k
. But that's exactly the
point—a singleton of a singleton contains as much type information as the
underlying singleton itself, so we can get away with just WrappedSing
@k
.Sing
@k
As an example of this in action, here is how you would define the singleton
for the earlier T
type:
data ST :: forall a. T a -> Type where SMkT :: forall a (x :: a) (sx ::Sing
x) (f :: F a).Sing
(WrapSing
sx) ->Sing
f -> ST (MkT sx f)
With this technique, we won't need anything like SSBool
in order to
instantiate x
with True
. Instead, the field of type
will simply be a newtype around Sing
(WrapSing
sx)SBool
. In general,
you'll need n layers of WrapSing
if you wish to single a singleton n
times.
Note that this is not the only possible way to define a singleton for T
.
An alternative approach that does not make use of singletons-of-singletons is
discussed at some length
here.
Due to the technical limitations of this approach, however, we do not use it
in singletons
at the moment, instead favoring the
slightly-clunkier-but-more-reliable WrappedSing
approach.
Defunctionalization
data TyFun :: Type -> Type -> Type Source #
Representation of the kind of a type-level function. The difference between term-level arrows and this type-level arrow is that at the term level applications can be unsaturated, whereas at the type level all applications have to be fully saturated.
Instances
(SingKind k1, SingKind k2) => SingKind (k1 ~> k2) Source # | Note that this instance's |
(forall (a :: k1). SingI a => SingI (f a), (ApplyTyCon :: (k1 -> kr) -> TyFun k1 kr -> Type) ~ (ApplyTyConAux1 :: (k1 -> kr) -> TyFun k1 kr -> Type)) => SingI (TyCon1 f :: TyFun k1 kr -> Type) Source # | |
(forall (a :: k1) (b :: k2). (SingI a, SingI b) => SingI (f a b), (ApplyTyCon :: (k2 -> kr) -> TyFun k2 kr -> Type) ~ (ApplyTyConAux1 :: (k2 -> kr) -> TyFun k2 kr -> Type)) => SingI (TyCon2 f :: TyFun k1 (k2 ~> kr) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3). (SingI a, SingI b, SingI c) => SingI (f a b c), (ApplyTyCon :: (k3 -> kr) -> TyFun k3 kr -> Type) ~ (ApplyTyConAux1 :: (k3 -> kr) -> TyFun k3 kr -> Type)) => SingI (TyCon3 f :: TyFun k1 (k2 ~> (k3 ~> kr)) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4). (SingI a, SingI b, SingI c, SingI d) => SingI (f a b c d), (ApplyTyCon :: (k4 -> kr) -> TyFun k4 kr -> Type) ~ (ApplyTyConAux1 :: (k4 -> kr) -> TyFun k4 kr -> Type)) => SingI (TyCon4 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> kr))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5). (SingI a, SingI b, SingI c, SingI d, SingI e) => SingI (f a b c d e), (ApplyTyCon :: (k5 -> kr) -> TyFun k5 kr -> Type) ~ (ApplyTyConAux1 :: (k5 -> kr) -> TyFun k5 kr -> Type)) => SingI (TyCon5 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> kr)))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f') => SingI (f a b c d e f'), (ApplyTyCon :: (k6 -> kr) -> TyFun k6 kr -> Type) ~ (ApplyTyConAux1 :: (k6 -> kr) -> TyFun k6 kr -> Type)) => SingI (TyCon6 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> kr))))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6) (g :: k7). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f', SingI g) => SingI (f a b c d e f' g), (ApplyTyCon :: (k7 -> kr) -> TyFun k7 kr -> Type) ~ (ApplyTyConAux1 :: (k7 -> kr) -> TyFun k7 kr -> Type)) => SingI (TyCon7 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> kr)))))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6) (g :: k7) (h :: k8). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f', SingI g, SingI h) => SingI (f a b c d e f' g h), (ApplyTyCon :: (k8 -> kr) -> TyFun k8 kr -> Type) ~ (ApplyTyConAux1 :: (k8 -> kr) -> TyFun k8 kr -> Type)) => SingI (TyCon8 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> (k8 ~> kr))))))) -> Type) Source # | |
type Apply (TyCon f :: k1 ~> k5) (x :: k1) Source # | |
Defined in Data.Singletons | |
type Apply (~>@#@$) (x :: Type) Source # | |
Defined in Data.Singletons | |
type Apply (SameKindSym0 :: TyFun k (k ~> Constraint) -> Type) (x :: k) Source # | |
Defined in Data.Singletons | |
type Demote (k1 ~> k2) Source # | |
Defined in Data.Singletons | |
type Sing Source # | |
Defined in Data.Singletons | |
type Apply ((@@@#@$) :: TyFun (a ~> b) (a ~> b) -> Type) (f :: a ~> b) Source # | |
type Apply (ApplySym0 :: TyFun (a ~> b) (a ~> b) -> Type) (f :: a ~> b) Source # | |
type (~>) a b = TyFun a b -> Type infixr 0 Source #
Something of kind a
is a defunctionalized type function that is
not necessarily generative or injective. Defunctionalized type functions
(also called "defunctionalization symbols") can be partially applied, even
if the original type function cannot be. For more information on how this
works, see the "Promotion and partial application" section of the
~>
bREADME
.
The singleton for things of kind a
is ~>
bSLambda
. SLambda
values
can be constructed in one of two ways:
- With the
singFun*
family of combinators (e.g.,singFun1
). For example, if you have:
type Id :: a -> a sId :: Sing a -> Sing (Id a)
Then you can construct a value of type
(that is,
Sing
@(a ~>
a)
like so:SLambda
@a @a
sIdFun ::Sing
@(a~>
a) IdSym0 sIdFun = singFun1 @IdSym0 sId
Where IdSym0 :: a
is the defunctionlized version of ~>
aId
.
- Using the
SingI
class. For example,
is another way of definingsing
@IdSym0sIdFun
above. Thesingletons-th
library automatically generatesSingI
instances for defunctionalization symbols such asIdSym0
.
Normal type-level arrows (->)
can be converted into defunctionalization
arrows (
by the use of the ~>
)TyCon
family of types. (Refer to the
Haddocks for TyCon1
to see an example of this in practice.) For this
reason, we do not make an effort to define defunctionalization symbols for
most type constructors of kind a -> b
, as they can be used in
defunctionalized settings by simply applying TyCon{N}
with an appropriate
N
.
This includes the (->)
type constructor itself, which is of kind
. One can turn it into something of kind
Type
-> Type
-> Type
by writing Type
~>
Type
~>
Type
, or something of
kind TyCon2
(->)
by writing Type
-> Type
~>
Type
(where TyCon1
((->) t)t ::
).Type
type TyCon1 = TyCon :: (k1 -> k2) -> k1 ~> k2 Source #
Wrapper for converting the normal type-level arrow into a ~>
.
For example, given:
data Nat = Zero | Succ Nat type family Map (a :: a ~> b) (a :: [a]) :: [b] Map f '[] = '[] Map f (x ': xs) = Apply f x ': Map f xs
We can write:
Map (TyCon1 Succ) [Zero, Succ Zero]
type TyCon2 = TyCon :: (k1 -> k2 -> k3) -> k1 ~> (k2 ~> k3) Source #
Similar to TyCon1
, but for two-parameter type constructors.
type TyCon5 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> k6)))) Source #
type TyCon6 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> k7))))) Source #
type TyCon7 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7 -> k8) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> k8)))))) Source #
type TyCon8 = TyCon :: (k1 -> k2 -> k3 -> k4 -> k5 -> k6 -> k7 -> k8 -> k9) -> k1 ~> (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> (k8 ~> k9))))))) Source #
type family Apply (f :: k1 ~> k2) (x :: k1) :: k2 Source #
Type level function application
Instances
data family TyCon :: (k1 -> k2) -> unmatchable_fun Source #
Workhorse for the TyCon1
, etc., types. This can be used directly
in place of any of the TyConN
types, but it will work only with
monomorphic types. When GHC#14645 is fixed, this should fully supersede
the TyConN
types.
Note that this is only defined on GHC 8.6 or later. Prior to GHC 8.6,
TyCon1
et al. were defined as separate data types.
Instances
(forall (a :: k1). SingI a => SingI (f a), (ApplyTyCon :: (k1 -> kr) -> TyFun k1 kr -> Type) ~ (ApplyTyConAux1 :: (k1 -> kr) -> TyFun k1 kr -> Type)) => SingI (TyCon1 f :: TyFun k1 kr -> Type) Source # | |
(forall (a :: k1) (b :: k2). (SingI a, SingI b) => SingI (f a b), (ApplyTyCon :: (k2 -> kr) -> TyFun k2 kr -> Type) ~ (ApplyTyConAux1 :: (k2 -> kr) -> TyFun k2 kr -> Type)) => SingI (TyCon2 f :: TyFun k1 (k2 ~> kr) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3). (SingI a, SingI b, SingI c) => SingI (f a b c), (ApplyTyCon :: (k3 -> kr) -> TyFun k3 kr -> Type) ~ (ApplyTyConAux1 :: (k3 -> kr) -> TyFun k3 kr -> Type)) => SingI (TyCon3 f :: TyFun k1 (k2 ~> (k3 ~> kr)) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4). (SingI a, SingI b, SingI c, SingI d) => SingI (f a b c d), (ApplyTyCon :: (k4 -> kr) -> TyFun k4 kr -> Type) ~ (ApplyTyConAux1 :: (k4 -> kr) -> TyFun k4 kr -> Type)) => SingI (TyCon4 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> kr))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5). (SingI a, SingI b, SingI c, SingI d, SingI e) => SingI (f a b c d e), (ApplyTyCon :: (k5 -> kr) -> TyFun k5 kr -> Type) ~ (ApplyTyConAux1 :: (k5 -> kr) -> TyFun k5 kr -> Type)) => SingI (TyCon5 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> kr)))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f') => SingI (f a b c d e f'), (ApplyTyCon :: (k6 -> kr) -> TyFun k6 kr -> Type) ~ (ApplyTyConAux1 :: (k6 -> kr) -> TyFun k6 kr -> Type)) => SingI (TyCon6 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> kr))))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6) (g :: k7). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f', SingI g) => SingI (f a b c d e f' g), (ApplyTyCon :: (k7 -> kr) -> TyFun k7 kr -> Type) ~ (ApplyTyConAux1 :: (k7 -> kr) -> TyFun k7 kr -> Type)) => SingI (TyCon7 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> kr)))))) -> Type) Source # | |
(forall (a :: k1) (b :: k2) (c :: k3) (d :: k4) (e :: k5) (f' :: k6) (g :: k7) (h :: k8). (SingI a, SingI b, SingI c, SingI d, SingI e, SingI f', SingI g, SingI h) => SingI (f a b c d e f' g h), (ApplyTyCon :: (k8 -> kr) -> TyFun k8 kr -> Type) ~ (ApplyTyConAux1 :: (k8 -> kr) -> TyFun k8 kr -> Type)) => SingI (TyCon8 f :: TyFun k1 (k2 ~> (k3 ~> (k4 ~> (k5 ~> (k6 ~> (k7 ~> (k8 ~> kr))))))) -> Type) Source # | |
type Apply (TyCon f :: k1 ~> k5) (x :: k1) Source # | |
Defined in Data.Singletons |
type family ApplyTyCon :: (k1 -> k2) -> k1 ~> unmatchable_fun where ... Source #
An "internal" definition used primary in the Apply
instance for
TyCon
.
Note that this only defined on GHC 8.6 or later.
ApplyTyCon @k1 @(k2 -> k3) @unmatchable_fun = ApplyTyConAux2 | |
ApplyTyCon @k1 @k2 @k2 = ApplyTyConAux1 |
data ApplyTyConAux1 :: (k1 -> k2) -> k1 ~> k2 Source #
An "internal" defunctionalization symbol used primarily in the
definition of ApplyTyCon
, as well as the SingI
instances for TyCon1
,
TyCon2
, etc.
Note that this is only defined on GHC 8.6 or later.
Instances
type Apply (ApplyTyConAux1 f :: TyFun k1 k2 -> Type) (x :: k1) Source # | |
Defined in Data.Singletons |
data ApplyTyConAux2 :: (k1 -> k2 -> k3) -> k1 ~> unmatchable_fun Source #
An "internal" defunctionalization symbol used primarily in the
definition of ApplyTyCon
.
Note that this is only defined on GHC 8.6 or later.
Instances
type Apply (ApplyTyConAux2 f :: TyFun k4 k7 -> Type) (x :: k4) Source # | |
Defined in Data.Singletons |
Defunctionalized singletons
When calling a higher-order singleton function, you need to use a
singFun...
function to wrap it. See singFun1
.
singFun1 :: forall f. SingFunction1 f -> Sing f Source #
Use this function when passing a function on singletons as a higher-order function. You will need visible type application to get this to work. For example:
falses = sMap (singFun1 @NotSym0 sNot) (STrue `SCons` STrue `SCons` SNil)
There are a family of singFun...
functions, keyed by the number
of parameters of the function.
singFun2 :: forall f. SingFunction2 f -> Sing f Source #
singFun3 :: forall f. SingFunction3 f -> Sing f Source #
singFun4 :: forall f. SingFunction4 f -> Sing f Source #
singFun5 :: forall f. SingFunction5 f -> Sing f Source #
singFun6 :: forall f. SingFunction6 f -> Sing f Source #
singFun7 :: forall f. SingFunction7 f -> Sing f Source #
singFun8 :: forall f. SingFunction8 f -> Sing f Source #
unSingFun1 :: forall f. Sing f -> SingFunction1 f Source #
This is the inverse of singFun1
, and likewise for the other
unSingFun...
functions.
unSingFun2 :: forall f. Sing f -> SingFunction2 f Source #
unSingFun3 :: forall f. Sing f -> SingFunction3 f Source #
unSingFun4 :: forall f. Sing f -> SingFunction4 f Source #
unSingFun5 :: forall f. Sing f -> SingFunction5 f Source #
unSingFun6 :: forall f. Sing f -> SingFunction6 f Source #
unSingFun7 :: forall f. Sing f -> SingFunction7 f Source #
unSingFun8 :: forall f. Sing f -> SingFunction8 f Source #
SLambda{2...8}
are explicitly bidirectional pattern synonyms for
defunctionalized singletons (
).Sing
(f :: k ~>
k' ~>
k'')
As constructors: Same as singFun{2..8}
. For example, one can turn a
binary function on singletons sTake ::
into a
defunctionalized singleton SingFunction2
TakeSym0
:Sing
(TakeSym :: Nat ~>
[a] ~>
[a])
>>> import Data.List.Singletons >>> :set -XTypeApplications >>> >>> :tSLambda2
SLambda2
::SingFunction2
f ->Sing
f >>> :tSLambda2
@TakeSym0SLambda2
::SingFunction2
TakeSym0 ->Sing
TakeSym0 >>> :tSLambda2
@TakeSym0 sTakeSLambda2
::Sing
TakeSym0
This is useful for functions on singletons that expect a defunctionalized
singleton as an argument, such as sZipWith ::
:SingFunction3
ZipWithSym0
sZipWith :: Sing (f :: a~>
b~>
c) -> Sing (xs :: [a]) -> Sing (ys :: [b]) -> Sing (ZipWith f xs ys :: [c]) sZipWith (SLambda2
@TakeSym0 sTake) :: Sing (xs :: [Nat]) -> Sing (ys :: [[a]]) -> Sing (ZipWith TakeSym0 xs ys :: [[a]])
As patterns: Same as unSingFun{2..8}
. Gets a binary term-level
Haskell function on singletons
from a defunctionalised Sing
(x :: k) -> Sing
(y :: k') -> Sing
(f @@ x @@ y)
. Alternatively, as a record field accessor:Sing
f
applySing2 ::Sing
(f :: k~>
k'~>
k'') ->SingFunction2
f
pattern SLambda2 :: forall f. SingFunction2 f -> Sing f Source #
applySing2 :: forall {a1} {a2} {b} (f :: a1 ~> (a2 ~> b)). Sing f -> SingFunction2 f Source #
pattern SLambda3 :: forall f. SingFunction3 f -> Sing f Source #
applySing3 :: forall {a1} {a2} {a3} {b} (f :: a1 ~> (a2 ~> (a3 ~> b))). Sing f -> SingFunction3 f Source #
pattern SLambda4 :: forall f. SingFunction4 f -> Sing f Source #
applySing4 :: forall {a1} {a2} {a3} {a4} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> b)))). Sing f -> SingFunction4 f Source #
pattern SLambda5 :: forall f. SingFunction5 f -> Sing f Source #
applySing5 :: forall {a1} {a2} {a3} {a4} {a5} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> b))))). Sing f -> SingFunction5 f Source #
pattern SLambda6 :: forall f. SingFunction6 f -> Sing f Source #
applySing6 :: forall {a1} {a2} {a3} {a4} {a5} {a6} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> b)))))). Sing f -> SingFunction6 f Source #
pattern SLambda7 :: forall f. SingFunction7 f -> Sing f Source #
applySing7 :: forall {a1} {a2} {a3} {a4} {a5} {a6} {a7} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> b))))))). Sing f -> SingFunction7 f Source #
pattern SLambda8 :: forall f. SingFunction8 f -> Sing f Source #
applySing8 :: forall {a1} {a2} {a3} {a4} {a5} {a6} {a7} {a8} {b} (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> (a8 ~> b)))))))). Sing f -> SingFunction8 f Source #
These type synonyms are exported only to improve error messages; users should not have to mention them.
type SingFunction2 (f :: a1 ~> (a2 ~> b)) = forall t1 t2. Sing t1 -> Sing t2 -> Sing ((f @@ t1) @@ t2) Source #
type SingFunction3 (f :: a1 ~> (a2 ~> (a3 ~> b))) = forall t1 t2 t3. Sing t1 -> Sing t2 -> Sing t3 -> Sing (((f @@ t1) @@ t2) @@ t3) Source #
type SingFunction4 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> b)))) = forall t1 t2 t3 t4. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing ((((f @@ t1) @@ t2) @@ t3) @@ t4) Source #
type SingFunction5 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> b))))) = forall t1 t2 t3 t4 t5. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing (((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5) Source #
type SingFunction6 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> b)))))) = forall t1 t2 t3 t4 t5 t6. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing t6 -> Sing ((((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5) @@ t6) Source #
type SingFunction7 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> b))))))) = forall t1 t2 t3 t4 t5 t6 t7. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing t6 -> Sing t7 -> Sing (((((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5) @@ t6) @@ t7) Source #
type SingFunction8 (f :: a1 ~> (a2 ~> (a3 ~> (a4 ~> (a5 ~> (a6 ~> (a7 ~> (a8 ~> b)))))))) = forall t1 t2 t3 t4 t5 t6 t7 t8. Sing t1 -> Sing t2 -> Sing t3 -> Sing t4 -> Sing t5 -> Sing t6 -> Sing t7 -> Sing t8 -> Sing ((((((((f @@ t1) @@ t2) @@ t3) @@ t4) @@ t5) @@ t6) @@ t7) @@ t8) Source #
Auxiliary functions
Proxy
is a type that holds no data, but has a phantom parameter of
arbitrary type (or even kind). Its use is to provide type information, even
though there is no value available of that type (or it may be too costly to
create one).
Historically,
is a safer alternative to the
Proxy
:: Proxy
a
idiom.undefined
:: a
>>>
Proxy :: Proxy (Void, Int -> Int)
Proxy
Proxy can even hold types of higher kinds,
>>>
Proxy :: Proxy Either
Proxy
>>>
Proxy :: Proxy Functor
Proxy
>>>
Proxy :: Proxy complicatedStructure
Proxy
Instances
Foldable (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Defined in Data.Foldable fold :: Monoid m => Proxy m -> m # foldMap :: Monoid m => (a -> m) -> Proxy a -> m # foldMap' :: Monoid m => (a -> m) -> Proxy a -> m # foldr :: (a -> b -> b) -> b -> Proxy a -> b # foldr' :: (a -> b -> b) -> b -> Proxy a -> b # foldl :: (b -> a -> b) -> b -> Proxy a -> b # foldl' :: (b -> a -> b) -> b -> Proxy a -> b # foldr1 :: (a -> a -> a) -> Proxy a -> a # foldl1 :: (a -> a -> a) -> Proxy a -> a # elem :: Eq a => a -> Proxy a -> Bool # maximum :: Ord a => Proxy a -> a # minimum :: Ord a => Proxy a -> a # | |
Traversable (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Alternative (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Applicative (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Functor (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Monad (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
MonadPlus (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Monoid (Proxy s) | Since: base-4.7.0.0 |
Semigroup (Proxy s) | Since: base-4.9.0.0 |
Bounded (Proxy t) | Since: base-4.7.0.0 |
Enum (Proxy s) | Since: base-4.7.0.0 |
Ix (Proxy s) | Since: base-4.7.0.0 |
Defined in Data.Proxy | |
Read (Proxy t) | Since: base-4.7.0.0 |
Show (Proxy s) | Since: base-4.7.0.0 |
Eq (Proxy s) | Since: base-4.7.0.0 |
Ord (Proxy s) | Since: base-4.7.0.0 |
Defunctionalization symbols
data DemoteSym0 :: Type ~> Type Source #
Instances
type Apply DemoteSym0 (x :: Type) Source # | |
Defined in Data.Singletons |
type DemoteSym1 x = Demote x Source #
data SameKindSym0 :: forall k. k ~> (k ~> Constraint) Source #
Instances
type Apply (SameKindSym0 :: TyFun k (k ~> Constraint) -> Type) (x :: k) Source # | |
Defined in Data.Singletons |
data SameKindSym1 :: forall k. k -> k ~> Constraint Source #
Instances
type Apply (SameKindSym1 x :: TyFun k Constraint -> Type) (y :: k) Source # | |
Defined in Data.Singletons |
type SameKindSym2 (x :: k) (y :: k) = SameKind x y Source #
data KindOfSym0 :: forall k. k ~> Type Source #
Instances
type Apply (KindOfSym0 :: TyFun k Type -> Type) (x :: k) Source # | |
Defined in Data.Singletons |
type KindOfSym1 (x :: k) = KindOf x Source #
type (~>@#@$$$) x y = x ~> y infixr 0 Source #
type (@@@#@$$$) (f :: a ~> b) (x :: a) = f @@ x infixl 9 Source #