some-1.0.4.1: Existential type: Some
Safe HaskellSafe
LanguageHaskell2010

Data.GADT.Internal

Synopsis

Documentation

>>> :set -XKindSignatures -XGADTs -XTypeOperators -XStandaloneDeriving -XQuantifiedConstraints
>>> import Data.Type.Equality
>>> import Data.Functor.Sum
>>> import Data.Maybe (isJust, isNothing)
>>> import GHC.Generics

class GShow t where Source #

Show-like class for 1-type-parameter GADTs. GShow t => ... is equivalent to something like (forall a. Show (t a)) => .... The easiest way to create instances would probably be to write (or derive) an instance Show (T a), and then simply say:

instance GShow t where gshowsPrec = defaultGshowsPrec

Methods

gshowsPrec :: Int -> t a -> ShowS Source #

Instances

Instances details
GShow (TypeRep :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a :: k0). Int -> TypeRep a -> ShowS Source #

GShow ((:~:) a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :~: a0) -> ShowS Source #

GShow (GOrdering a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> GOrdering a a0 -> ShowS Source #

(GShow a, GShow b) => GShow (Product a b :: k -> Type) Source #
>>> gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)
"Pair Refl Refl"
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> Product a b a0 -> ShowS Source #

(GShow a, GShow b) => GShow (Sum a b :: k -> Type) Source #
>>> gshow (InL Refl :: Sum ((:~:) Int) ((:~:) Bool) Int)
"InL Refl"
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> Sum a b a0 -> ShowS Source #

GShow ((:~~:) a :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :~~: a0) -> ShowS Source #

(GShow a, GShow b) => GShow (a :*: b :: k -> Type) Source #
>>> gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)
"Refl :*: Refl"

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :*: b) a0 -> ShowS Source #

(GShow a, GShow b) => GShow (a :+: b :: k -> Type) Source #
>>> gshow (L1 Refl :: ((:~:) Int :+: (:~:) Bool) Int)
"L1 Refl"

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> (a :+: b) a0 -> ShowS Source #

defaultGshowsPrec :: Show (t a) => Int -> t a -> ShowS Source #

If f has a 'Show (f a)' instance, this function makes a suitable default implementation of gshowsPrec.

Since: 1.0.4

gshows :: GShow t => t a -> ShowS Source #

gshow :: GShow t => t a -> String Source #

type GReadS t = String -> [(Some t, String)] Source #

GReadS t is equivalent to ReadS (forall b. (forall a. t a -> b) -> b), which is in turn equivalent to ReadS (Exists t) (with data Exists t where Exists :: t a -> Exists t)

getGReadResult :: Some tag -> (forall a. tag a -> b) -> b Source #

mkGReadResult :: tag a -> Some tag Source #

class GRead t where Source #

Read-like class for 1-type-parameter GADTs. Unlike GShow, this one cannot be mechanically derived from a Read instance because greadsPrec must choose the phantom type based on the String being parsed.

Methods

greadsPrec :: Int -> GReadS t Source #

Instances

Instances details
GRead ((:~:) a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

greadsPrec :: Int -> GReadS ((:~:) a) Source #

GRead (GOrdering a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

(GRead a, GRead b) => GRead (Sum a b :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

greadsPrec :: Int -> GReadS (Sum a b) Source #

(GRead a, GRead b) => GRead (a :+: b :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

greadsPrec :: Int -> GReadS (a :+: b) Source #

k1 ~ k2 => GRead ((:~~:) a :: k2 -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

greadsPrec :: Int -> GReadS ((:~~:) a) Source #

gread :: GRead t => String -> (forall a. t a -> b) -> b Source #

greadMaybe :: GRead t => String -> (forall a. t a -> b) -> Maybe b Source #

>>> greadMaybe "InL Refl" mkSome :: Maybe (Some (Sum ((:~:) Int) ((:~:) Bool)))
Just (mkSome (InL Refl))
>>> greadMaybe "L1 Refl" mkSome :: Maybe (Some ((:~:) Int :+: (:~:) Bool))
Just (mkSome (L1 Refl))
>>> greadMaybe "garbage" mkSome :: Maybe (Some ((:~:) Int))
Nothing

class GEq f where Source #

A class for type-contexts which contain enough information to (at least in some cases) decide the equality of types occurring within them.

This class is sometimes confused with TestEquality from base. TestEquality only checks type equality.

Consider

>>> data Tag a where TagInt1 :: Tag Int; TagInt2 :: Tag Int

The correct TestEquality Tag instance is

>>> :{
instance TestEquality Tag where
    testEquality TagInt1 TagInt1 = Just Refl
    testEquality TagInt1 TagInt2 = Just Refl
    testEquality TagInt2 TagInt1 = Just Refl
    testEquality TagInt2 TagInt2 = Just Refl
:}

While we can define

instance GEq Tag where
   geq = testEquality

this will mean we probably want to have

instance Eq Tag where
   _ == _ = True

Note: In the future version of some package (to be released around GHC-9.6 / 9.8) the forall a. Eq (f a) constraint will be added as a constraint to GEq, with a law relating GEq and Eq:

geq x y = Just Refl   ⇒  x == y = True        ∀ (x :: f a) (y :: f b)
x == y                ≡  isJust (geq x y)     ∀ (x, y :: f a)

So, the more useful GEq Tag instance would differentiate between different constructors:

>>> :{
instance GEq Tag where
    geq TagInt1 TagInt1 = Just Refl
    geq TagInt1 TagInt2 = Nothing
    geq TagInt2 TagInt1 = Nothing
    geq TagInt2 TagInt2 = Just Refl
:}

which is consistent with a derived Eq instance for Tag

>>> deriving instance Eq (Tag a)

Note that even if a ~ b, the geq (x :: f a) (y :: f b) may be Nothing (when value terms are inequal).

The consistency of GEq and Eq is easy to check by exhaustion:

>>> let checkFwdGEq :: (forall a. Eq (f a), GEq f) => f a -> f b -> Bool; checkFwdGEq x y = case geq x y of Just Refl -> x == y; Nothing -> True
>>> (checkFwdGEq TagInt1 TagInt1, checkFwdGEq TagInt1 TagInt2, checkFwdGEq TagInt2 TagInt1, checkFwdGEq TagInt2 TagInt2)
(True,True,True,True)
>>> let checkBwdGEq :: (Eq (f a), GEq f) => f a -> f a -> Bool; checkBwdGEq x y = if x == y then isJust (geq x y) else isNothing (geq x y)
>>> (checkBwdGEq TagInt1 TagInt1, checkBwdGEq TagInt1 TagInt2, checkBwdGEq TagInt2 TagInt1, checkBwdGEq TagInt2 TagInt2)
(True,True,True,True)

Methods

geq :: f a -> f b -> Maybe (a :~: b) Source #

Produce a witness of type-equality, if one exists.

A handy idiom for using this would be to pattern-bind in the Maybe monad, eg.:

extract :: GEq tag => tag a -> DSum tag -> Maybe a
extract t1 (t2 :=> x) = do
    Refl <- geq t1 t2
    return x

Or in a list comprehension:

extractMany :: GEq tag => tag a -> [DSum tag] -> [a]
extractMany t1 things = [ x | (t2 :=> x) <- things, Refl <- maybeToList (geq t1 t2)]

(Making use of the DSum type from Data.Dependent.Sum in both examples)

Instances

Instances details
GEq (TypeRep :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

geq :: forall (a :: k0) (b :: k0). TypeRep a -> TypeRep b -> Maybe (a :~: b) Source #

GEq ((:~:) a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

geq :: forall (a0 :: k0) (b :: k0). (a :~: a0) -> (a :~: b) -> Maybe (a0 :~: b) Source #

(GEq a, GEq b) => GEq (Product a b :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

geq :: forall (a0 :: k0) (b0 :: k0). Product a b a0 -> Product a b b0 -> Maybe (a0 :~: b0) Source #

(GEq a, GEq b) => GEq (Sum a b :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

geq :: forall (a0 :: k0) (b0 :: k0). Sum a b a0 -> Sum a b b0 -> Maybe (a0 :~: b0) Source #

GEq ((:~~:) a :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

geq :: forall (a0 :: k0) (b :: k0). (a :~~: a0) -> (a :~~: b) -> Maybe (a0 :~: b) Source #

(GEq a, GEq b) => GEq (a :*: b :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

geq :: forall (a0 :: k0) (b0 :: k0). (a :*: b) a0 -> (a :*: b) b0 -> Maybe (a0 :~: b0) Source #

(GEq f, GEq g) => GEq (f :+: g :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

geq :: forall (a :: k0) (b :: k0). (f :+: g) a -> (f :+: g) b -> Maybe (a :~: b) Source #

defaultGeq :: GCompare f => f a -> f b -> Maybe (a :~: b) Source #

If f has a GCompare instance, this function makes a suitable default implementation of geq.

Since: 1.0.4

defaultEq :: GEq f => f a -> f b -> Bool Source #

If f has a GEq instance, this function makes a suitable default implementation of (==).

defaultNeq :: GEq f => f a -> f b -> Bool Source #

If f has a GEq instance, this function makes a suitable default implementation of (/=).

data GOrdering a b where Source #

A type for the result of comparing GADT constructors; the type parameters of the GADT values being compared are included so that in the case where they are equal their parameter types can be unified.

Constructors

GLT :: GOrdering a b 
GEQ :: GOrdering t t 
GGT :: GOrdering a b 

Instances

Instances details
GRead (GOrdering a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

GShow (GOrdering a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gshowsPrec :: forall (a0 :: k0). Int -> GOrdering a a0 -> ShowS Source #

Show (GOrdering a b) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

showsPrec :: Int -> GOrdering a b -> ShowS #

show :: GOrdering a b -> String #

showList :: [GOrdering a b] -> ShowS #

Eq (GOrdering a b) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

(==) :: GOrdering a b -> GOrdering a b -> Bool #

(/=) :: GOrdering a b -> GOrdering a b -> Bool #

Ord (GOrdering a b) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

compare :: GOrdering a b -> GOrdering a b -> Ordering #

(<) :: GOrdering a b -> GOrdering a b -> Bool #

(<=) :: GOrdering a b -> GOrdering a b -> Bool #

(>) :: GOrdering a b -> GOrdering a b -> Bool #

(>=) :: GOrdering a b -> GOrdering a b -> Bool #

max :: GOrdering a b -> GOrdering a b -> GOrdering a b #

min :: GOrdering a b -> GOrdering a b -> GOrdering a b #

weakenOrdering :: GOrdering a b -> Ordering Source #

TODO: Think of a better name

This operation forgets the phantom types of a GOrdering value.

class GEq f => GCompare f where Source #

Type class for comparable GADT-like structures. When 2 things are equal, must return a witness that their parameter types are equal as well (GEQ).

Methods

gcompare :: f a -> f b -> GOrdering a b Source #

Instances

Instances details
GCompare (TypeRep :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gcompare :: forall (a :: k0) (b :: k0). TypeRep a -> TypeRep b -> GOrdering a b Source #

GCompare ((:~:) a :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gcompare :: forall (a0 :: k0) (b :: k0). (a :~: a0) -> (a :~: b) -> GOrdering a0 b Source #

(GCompare a, GCompare b) => GCompare (Product a b :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gcompare :: forall (a0 :: k0) (b0 :: k0). Product a b a0 -> Product a b b0 -> GOrdering a0 b0 Source #

(GCompare a, GCompare b) => GCompare (Sum a b :: k -> Type) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

gcompare :: forall (a0 :: k0) (b0 :: k0). Sum a b a0 -> Sum a b b0 -> GOrdering a0 b0 Source #

GCompare ((:~~:) a :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gcompare :: forall (a0 :: k0) (b :: k0). (a :~~: a0) -> (a :~~: b) -> GOrdering a0 b Source #

(GCompare a, GCompare b) => GCompare (a :*: b :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gcompare :: forall (a0 :: k0) (b0 :: k0). (a :*: b) a0 -> (a :*: b) b0 -> GOrdering a0 b0 Source #

(GCompare f, GCompare g) => GCompare (f :+: g :: k -> Type) Source #

Since: 1.0.4

Instance details

Defined in Data.GADT.Internal

Methods

gcompare :: forall (a :: k0) (b :: k0). (f :+: g) a -> (f :+: g) b -> GOrdering a b Source #

defaultCompare :: GCompare f => f a -> f b -> Ordering Source #

newtype Some tag Source #

Existential. This is type is useful to hide GADTs' parameters.

>>> data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Bool
>>> instance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool"
>>> classify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> []
>>> instance GRead Tag where greadsPrec _ s = [ (r, rest) | (con, rest) <-  lex s, r <- classify con ]

With Church-encoding youcan only use a functions:

>>> let y = mkSome TagBool
>>> y
mkSome TagBool
>>> withSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String
"B"

or explicitly work with S

>>> let x = S $ \f -> f TagInt
>>> x
mkSome TagInt
>>> case x of S f -> f $ \x' -> case x' of { TagInt -> "I"; TagBool -> "B" } :: String
"I"

The implementation of mapSome is safe.

>>> let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool
>>> mapSome f y
mkSome TagBool

but you can also use:

>>> withSome y (mkSome . f)
mkSome TagBool
>>> read "Some TagBool" :: Some Tag
mkSome TagBool
>>> read "mkSome TagInt" :: Some Tag
mkSome TagInt

Constructors

S 

Fields

  • withSome :: forall r. (forall a. tag a -> r) -> r

    Eliminator.

Instances

Instances details
Applicative m => Monoid (Some m) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

mempty :: Some m #

mappend :: Some m -> Some m -> Some m #

mconcat :: [Some m] -> Some m #

Applicative m => Semigroup (Some m) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

(<>) :: Some m -> Some m -> Some m #

sconcat :: NonEmpty (Some m) -> Some m #

stimes :: Integral b => b -> Some m -> Some m #

GRead f => Read (Some f) Source # 
Instance details

Defined in Data.GADT.Internal

GShow tag => Show (Some tag) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

showsPrec :: Int -> Some tag -> ShowS #

show :: Some tag -> String #

showList :: [Some tag] -> ShowS #

GEq tag => Eq (Some tag) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

(==) :: Some tag -> Some tag -> Bool #

(/=) :: Some tag -> Some tag -> Bool #

GCompare tag => Ord (Some tag) Source # 
Instance details

Defined in Data.GADT.Internal

Methods

compare :: Some tag -> Some tag -> Ordering #

(<) :: Some tag -> Some tag -> Bool #

(<=) :: Some tag -> Some tag -> Bool #

(>) :: Some tag -> Some tag -> Bool #

(>=) :: Some tag -> Some tag -> Bool #

max :: Some tag -> Some tag -> Some tag #

min :: Some tag -> Some tag -> Some tag #

mkSome :: tag a -> Some tag Source #

Constructor.

mapSome :: (forall x. f x -> g x) -> Some f -> Some g Source #

Map over argument.

foldSome :: (forall a. tag a -> b) -> Some tag -> b Source #

traverseSome :: Functor m => (forall a. f a -> m (g a)) -> Some f -> m (Some g) Source #

Traverse over argument.

withSomeM :: Monad m => m (Some tag) -> (forall a. tag a -> m r) -> m r Source #

Monadic withSome.

Since: 1.0.1