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"
You can either use PatternSynonyms
let x = Some TagIntxSome TagInt
case x of { Some TagInt -> "I"; Some TagBool -> "B" } :: String"I"
or you can use functions
let y = mkSome TagBoolySome TagBool
withSome y $ \y' -> case y' of { TagInt -> "I"; TagBool -> "B" } :: String"B"
The implementation of mapSome is safe.
let f :: Tag a -> Tag a; f TagInt = TagInt; f TagBool = TagBoolmapSome f ySome TagBool
but you can also use:
withSome y (mkSome . f)Some TagBool