h$ Fx      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGSafe '(.}somesomesomeSafe'(.39! 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 & 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 TagInt some 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.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)someH0-like class for 1-type-parameter GADTs. Unlike 2, this one cannot be mechanically derived from a H instance because , must choose the phantom type based on the I 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)someJ)-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 = defaultGshowsPrecsomeIf 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 K.#someIf f has a  instance, this function makes a suitable default implementation of L.MsomeTODO: Think of a better name.This operation forgets the phantom types of a  value.%some Constructor.&someMap over argument.'some N  (someTraverse over argument.)someMonadic  .Osome=gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)"Refl :*: Refl"Psome1gshow (L1 Refl :: ((:~:) Int :+: (:~:) Bool) Int) "L1 Refl"Qsome=gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)"Pair Refl Refl"Rsome4gshow (InL Refl :: Sum ((:~:) Int) ((:~:) Bool) Int) "InL Refl"SsomeTsomeUsomeVsomeWsomeXsomeYsomeZsome[some"  !"#M$%&'()Safez !"#$ !"# $Safe   Safe %&'() %&)'(Safe '(.*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 ]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 0 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..someMonadic -./some N -0someMap over argument.1someTraverse over argument.7some*+,-./01*+,-.0/1 Trustworthy '(.49some>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 ]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 ? 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.=someMonadic <.>some N ?@ 9::;<=?>@Safec9:;<=>?@ 9::;<=?>@      !"#$%&'()*+,-./012.20/13456789.20/13456789:;<:=>:?@ABCABDE:=FGHIJKLMNOPQRS!some-1.0.4-7SjwzXhLQ55AQa0gck6bNoData.GADT.DeepSeqData.Some.ChurchData.GADT.CompareData.GADT.ShowData.Some.GADTData.Some.NewtypeData.GADT.Internal Data.SomeGNFDatagrnf$fGNFDatakTypeRep$fGNFDatak:~~: $fGNFDatak:~: $fGNFDatak:+: $fGNFDatak:*: $fGNFDatakSum$fGNFDatakProductSomeSwithSomeGComparegcompare GOrderingGLTGEQGGTGEqgeqGRead greadsPrecGReadSGShow gshowsPrecdefaultGshowsPrecgshowsgshowgetGReadResult mkGReadResultgreadsgread greadMaybe defaultGeq defaultEq defaultNeqdefaultComparemkSomemapSomefoldSome traverseSome withSomeM $fMonoidSome$fSemigroupSome $fNFDataSome $fOrdSome$fEqSome $fReadSome $fShowSomebaseGHC.ReadReadGHC.BaseStringGHC.ShowShowghc-prim GHC.Classes==/=weakenOrderingflip $fGShowk:*: $fGShowk:+:$fGShowkProduct $fGShowkSum $fGShowk:~~: $fGEqk:*: $fGEqk:+: $fGEqk:~~:$fGComparek:*:$fGComparek:+:$fGComparek:~~: $fGReadk:+: $fGReadk2:~~: