h$      !"#$%&'()*+,-./0123456789:;<=>?@Safe.Safe '(.3lsome>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 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.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)someA0-like class for 1-type-parameter GADTs. Unlike 2, this one cannot be mechanically derived from a A instance because , must choose the phantom type based on the B 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)someC)-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 = showsPrecsomegreadMaybe "InL Refl" mkSome :: Maybe (Some (Sum ((:~:) Int) ((:~:) Bool)))Just (mkSome (InL Refl))7greadMaybe "garbage" mkSome :: Maybe (Some ((:~:) Int))NothingsomeIf f has a   instance, this function makes a suitable default implementation of D.someIf f has a   instance, this function makes a suitable default implementation of E.FsomeTODO: Think of a better name.This operation forgets the phantom types of a   value.some Constructor.someMap over argument. some G !someTraverse over argument."someMonadic .Hsome=gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)"Pair Refl Refl"Isome4gshow (InL Refl :: Sum ((:~:) Int) ((:~:) Bool) Int) "InL Refl"  F !"Safe    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 ) 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 G &)someMap over argument.*someTraverse over argument.0some#$%&'()*#$%&')(* Trustworthy '(.Y2some>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 8 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 TagInt4some Constructor.5some Eliminator.6someMonadic 5.7some G 58someMap over argument.9someTraverse over argument.23456789 233456879Safe23456789 233456879      !"#$%&'()*+  '+)(*,-./012  '+)(*,-./012345367389:;<:;=>36?@A!some-1.0.2-DztDdrSEriv1oeWH1exEJrData.GADT.DeepSeqData.Some.ChurchData.GADT.CompareData.GADT.ShowData.Some.GADTData.Some.NewtypeData.GADT.Internal Data.SomeGNFDatagrnf $fGNFDataSum$fGNFDataProductSomeSwithSomeGComparegcompare GOrderingGLTGEQGGTGEqgeqGRead greadsPrecGReadSGShow gshowsPrecgshowsgshowgetGReadResult mkGReadResultgreadsgread greadMaybe defaultEq defaultNeqdefaultComparemkSomemapSomefoldSome traverseSome withSomeM $fMonoidSome$fSemigroupSome $fNFDataSome $fOrdSome$fEqSome $fReadSome $fShowSomebaseGHC.ReadReadGHC.BaseStringGHC.ShowShowghc-prim GHC.Classes==/=weakenOrderingflip$fGShowkProduct $fGShowkSum