h&.,o      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ Safe0someHeterogenous lifted equality."This class is stronger version of Eq1 from base class (forall a. Eq a => Eq (f a)) => Eq1 f where liftEq :: (a -> b -> Bool) -> f a -> f b -> Bool as we don't require a a -> b -> Bool function.Morally Eq1 should be a superclass of +, but it cannot be, as GHC wouldn't allow  to be polykinded. 1https://gitlab.haskell.org/ghc/ghc/-/issues/22682Laws  reflexivity x x D Truesymmetry x y D  y x transitivity x y D  y z D True C  x z D True compatibility x y D x [ yextensionality x y D True C f x == f y D True for polymorphic f :: forall x. f x -> a and \ a.Note: P stands for phantom.Safe )*0 some somesome  Safe )*0 "some>Existential. This is type is useful to hide GADTs' parameters.?data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Boolinstance 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 ]1With Church-encoding youcan only use a functions:let y = mkSome TagBoolymkSome TagBoolwithSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String"B"or explicitly work with let x = S $ \f -> f TagIntx mkSome TagIntcase x of S f -> f $ \x' -> case x' of { TagInt -> "I"; TagBool -> "B" } :: String"I"The implementation of 0 is safe.?let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool mapSome f ymkSome TagBoolbut you can also use:withSome y (mkSome . f)mkSome TagBoolread "Some TagBool" :: Some TagmkSome TagBool read "mkSome TagInt" :: Some Tag mkSome TagIntsome Eliminator.someType class for comparable GADT-like structures. When 2 things are equal, must return a witness that their parameter types are equal as well ().someA 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.someA 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 ] from base. ] only checks  type equality.Consider7data Tag a where TagInt1 :: Tag Int; TagInt2 :: Tag Int The correct ] 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  Tag where  = ^ 'this will mean we probably want to have  instance \ Tag where _ [ _ = True Note: In the future version of some4 package (to be released around GHC-9.6 / 9.8) the forall a. Eq (f a)- constraint will be added as a constraint to , with a law relating  and \:  x y = Just Refl C x == y = True D (x :: f a) (y :: f b) x == y D isJust ( x y) D (x, y :: f a) So, the more useful  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 \ instance for Tagderiving instance Eq (Tag a)Note that even if a ~ b, the  (x :: f a) (y :: f b) may be _ (when value terms are inequal).The consistency of  and \ 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)some2Produce 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 xOr 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  https://hackage.haskell.org/package/dependent-sum/docs/Data-Dependent-Sum.htmlData.Dependent.Sum in both examples)some`0-like class for 1-type-parameter GADTs. Unlike !2, this one cannot be mechanically derived from a ` instance because , must choose the phantom type based on the a being parsed. someGReadS 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)!someb)-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: 5instance GShow t where gshowsPrec = defaultGshowsPrec#someIf f has a 'Show (f a)' instance, this function makes a suitable default implementation of ".*somegreadMaybe "InL Refl" mkSome :: Maybe (Some (Sum ((:~:) Int) ((:~:) Bool)))Just (mkSome (InL Refl))greadMaybe "L1 Refl" mkSome :: Maybe (Some ((:~:) Int :+: (:~:) Bool))Just (mkSome (L1 Refl))7greadMaybe "garbage" mkSome :: Maybe (Some ((:~:) Int))Nothing+someIf f has a  instance, this function makes a suitable default implementation of .,someIf f has a  instance, this function makes a suitable default implementation of [.-someIf f has a  instance, this function makes a suitable default implementation of c.dsomeTODO: Think of a better name.This operation forgets the phantom types of a  value.esomeAn implementation of  for a singleton type./some Constructor.0someMap over argument.1some f 2someTraverse over argument.3someMonadic .gsome=gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)"Refl :*: Refl"hsome1gshow (L1 Refl :: ((:~:) Int :+: (:~:) Bool) Int) "L1 Refl"isome=gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)"Pair Refl Refl"jsome4gshow (InL Refl :: Sum ((:~:) Int) ((:~:) Bool) Int) "InL Refl"ksomelsomemsomensomeosomepsomeqsomersomessomeesomeThe name of the singleton type. (Only used for error message purposes.)someHow to turn the singleton type into a value that can be compared with t.# !"#$%&'()*+,-d.e/0123Safe J +,-. +,-.Safe  !"#$%&'()* !"#$% ()*&'Safe0!4some Heterogenous lifted total order."This class is stronger version of Ord1 from base class (forall a. Ord a => Ord (f a)) => Ord1 f where liftCompare :: (a -> b -> Ordering) -> f a -> f b -> Ordering 4545Safe!/0123/0312Safe )*0&=some>Existential. This is type is useful to hide GADTs' parameters.data Tag :: Type -> Type where TagInt :: Tag Int; TagBool :: Tag Boolinstance 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 ]You can either use constructor:let x = Some TagIntx Some TagInt?case x of { Some TagInt -> "I"; Some TagBool -> "B" } :: String"I"or you can use functionslet y = mkSome TagBooly Some TagBoolwithSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String"B"The implementation of C is safe.?let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool mapSome f y Some TagBoolbut you can also use:withSome y (mkSome . f) Some TagBoolread "Some TagBool" :: Some Tag Some TagBool read "mkSome TagInt" :: Some Tag Some TagInt?some Constructor.@some Eliminator.AsomeMonadic @.Bsome f @CsomeMap over argument.DsomeTraverse over argument.Jsome=>?@ABCD=>?@ACBD Trustworthy )*0,+Lsome>Existential. This is type is useful to hide GADTs' parameters.data Tag :: Type -> Type where TagInt :: Tag Int; TagBool :: Tag Boolinstance 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 ]You can either use PatternSynonyms (available with GHC >= 8.0)let x = Some TagIntx Some TagInt?case x of { Some TagInt -> "I"; Some TagBool -> "B" } :: String"I"or you can use functionslet y = mkSome TagBooly Some TagBoolwithSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String"B"The implementation of R is safe.?let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBool mapSome f y Some TagBoolbut you can also use:withSome y (mkSome . f) Some TagBoolread "Some TagBool" :: Some Tag Some TagBool read "mkSome TagInt" :: Some Tag Some TagIntNsome Constructor.Osome Eliminator.PsomeMonadic O.Qsome f ORsomeMap over argument.SsomeTraverse over argument.LMNOPQRS LMMNOPRQS Safe,ZLMNOPQRS LMMNOPRQS      ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = >?@ABCDEFG: ><;=HIJKLMN: ><;=HIJKLMNOPQOPRSTUSTVSWXSYZS[\S]^OP_ ` aS[b c d e f g h i j k l m n oOPp!some-1.0.6-L0CCuJuIOnu2SnBcKemh8UData.EqPData.GADT.DeepSeqData.Some.ChurchData.GADT.CompareData.GADT.Show Data.OrdPData.Some.GADTData.Some.NewtypeData.GADT.Internal Data.SomeEqPeqp$fEqPTYPEStableName $fEqPkConst $fEqPkProxy $fEqPkTypeRep $fEqPk:*: $fEqPk:+: $fEqPk:~~: $fEqPk:~:GNFDatagrnf$fGNFDatakTypeRep$fGNFDatak:~~: $fGNFDatak:~: $fGNFDatak:+: $fGNFDatak:*: $fGNFDatakSum$fGNFDatakProductSomeSwithSomeGComparegcompare GOrderingGLTGEQGGTGEqgeqGRead greadsPrecGReadSGShow gshowsPrecdefaultGshowsPrecgshowsgshowgetGReadResult mkGReadResultgreadsgread greadMaybe defaultGeq defaultEq defaultNeqdefaultComparemkSomemapSomefoldSome traverseSome withSomeMOrdPcomparep $fOrdPkConst $fOrdPkProxy$fOrdPkTypeRep $fOrdPk:*: $fOrdPk:+: $fOrdPk:~~: $fOrdPk:~: $fMonoidSome$fSemigroupSome $fNFDataSome $fOrdSome$fEqSome $fReadSome $fShowSomeghc-prim GHC.Classes==EqbaseData.Type.Equality TestEquality testEquality GHC.MaybeNothingGHC.ReadReadGHC.BaseStringGHC.ShowShow/=weakenOrdering gcompareSingflip $fGShowk:*: $fGShowk:+:$fGShowkProduct $fGShowkSum $fGShowk:~~: $fGEqk:*: $fGEqk:+: $fGEqk:~~:$fGComparek:*:$fGComparek:+:$fGComparek:~~: $fGReadk:+: $fGReadk2:~~:Ord