h$Q      !"#$%&'()*+,-./0123456789:;<=>?@ABSafe'(.XsomesomeSafe'(.3some>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)someC0-like class for 1-type-parameter GADTs. Unlike 2, this one cannot be mechanically derived from a C instance because , must choose the phantom type based on the D 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)someE)-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 F.someIf f has a  instance, this function makes a suitable default implementation of G.HsomeTODO: Think of a better name.This operation forgets the phantom types of a   value. some Constructor.!someMap over argument."some I #someTraverse over argument.$someMonadic .Jsome=gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)"Pair Refl Refl"Ksome4gshow (InL Refl :: Sum ((:~:) Int) ((:~:) Bool) Int) "InL Refl"   H !"#$Safe    Safe  SafeC !"#$ !$"#Safe '(.V%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 I (+someMap over argument.,someTraverse over argument.2some%&'()*+,%&'()+*, Trustworthy '(.4some>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 TagInt6some Constructor.7some Eliminator.8someMonadic 7.9some I 7:someMap over argument.;someTraverse over argument.456789:; 455678:9;Safe456789:; 455678:9;      !"#$%&'()*+,-)-+*,./01234)-+*,./012345675895:;<=><=?@58ABC!some-1.0.3-EkurWqTp0mZLHswRnbJS58Data.GADT.DeepSeqData.Some.ChurchData.GADT.CompareData.GADT.ShowData.Some.GADTData.Some.NewtypeData.GADT.Internal Data.SomeGNFDatagrnf$fGNFDatakTypeRep $fGNFDatak:~: $fGNFDatakSum$fGNFDatakProductSomeSwithSomeGComparegcompare 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