!dl`>      !"#$%&'()*+,-./0123456789:;<=SafepSafe &'-2HSUVX9some>Existential. This is type is useful to hide GADTs' parameters.?data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Booloinstance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool"hclassify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> []binstance 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 TagBoolJwithSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String"B"or explicitly work with let x = S $ \f -> f TagIntx mkSome TagIntRcase 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.NA handy idiom for using this would be to pattern-bind in the Maybe monad, eg.: pextract :: 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 Data.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 ? 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)some@)-like class for 1-type-parameter GADTs. GShow t => ..." is equivalent to something like (forall a. Show (t a)) => ...R. 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 = showsPrecsomeKgreadMaybe "InL Refl" mkSome :: Maybe (Some (Sum ((:~:) Int) ((:~:) Bool)))Just (mkSome (InL Refl))7greadMaybe "garbage" mkSome :: Maybe (Some ((:~:) Int))NothingsomeIf f has a  L instance, this function makes a suitable default implementation of '(==)'.someIf f has a  L instance, this function makes a suitable default implementation of '(/=)'.AsomeTODO: Think of a better name.This operation forgets the phantom types of a   value.some Constructor.someMap over argument. some B !someTraverse over argument.Csome=gshow (Pair Refl Refl :: Product ((:~:) Int) ((:~:) Int) Int)"Pair Refl Refl"Dsome4gshow (InL Refl :: Sum ((:~:) Int) ((:~:) Bool) Int) "InL Refl" A !Safe:k    Safe;  Safe; ! !Safe&'-HSXMv"some>Existential. This is type is useful to hide GADTs' parameters.?data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Booloinstance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool"hclassify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> []binstance 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 TagBoolJwithSome 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.&some B %'someMap over argument.(someTraverse over argument..some"#$%&'("#$%'&( Trustworthy %&'-HSXg_0some>Existential. This is type is useful to hide GADTs' parameters.?data Tag :: * -> * where TagInt :: Tag Int; TagBool :: Tag Booloinstance GShow Tag where gshowsPrec _ TagInt = showString "TagInt"; gshowsPrec _ TagBool = showString "TagBool"hclassify s = case s of "TagInt" -> [mkGReadResult TagInt]; "TagBool" -> [mkGReadResult TagBool]; _ -> []binstance 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 TagBoolJwithSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String"B"The implementation of 5 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 TagInt2some Constructor.3some Eliminator.4some B 35someMap over argument.6someTraverse over argument.012345601123546Safe`^012345601123546E      !"#$%&'()*  ')(*+,-./01  ')(*+,-./01234256278925:;<=#some-1.0.0.1-IC1Vrnqu4hPJRPACJNxwAvData.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 $fMonoidSome$fSemigroupSome $fNFDataSome $fOrdSome$fEqSome $fReadSome $fShowSomebaseGHC.ReadReadGHC.BaseStringGHC.ShowShowweakenOrderingflip$fGShowkProduct $fGShowkSum