>
> module ShePrelude where
> data SheProxy (ty :: *) (tm :: *) where SheProxy :: SheProxy ty tm
> class SheChecks (ty :: *) (tm :: *) where
> sheTypes :: SheProxy ty tm -> SheSingleton ty tm
> data family SheSingleton ty :: * -> *
> data SheTyLeft x = SheTyLeft x
> data SheTyRight x = SheTyRight x
> data instance SheSingleton (Either s t) dummy where
> SheWitLeft :: SheSingleton s x -> SheSingleton (Either s t) (SheTyLeft x)
> SheWitRight :: SheSingleton t x -> SheSingleton (Either s t) (SheTyRight x)
> instance SheChecks s x => SheChecks (Either s t) (SheTyLeft x) where
> sheTypes _ = SheWitLeft (sheTypes (SheProxy :: SheProxy s x))
> instance SheChecks t x => SheChecks (Either s t) (SheTyRight x) where
> sheTypes _ = SheWitRight (sheTypes (SheProxy :: SheProxy t x))
> data SheTyTrue = SheTyTrue
> data SheTyFalse = SheTyFalse
> data instance SheSingleton Bool dummy where
> SheWitTrue :: SheSingleton Bool SheTyTrue
> SheWitFalse :: SheSingleton Bool SheTyFalse
> instance SheChecks Bool SheTyTrue where
> sheTypes _ = SheWitTrue
> instance SheChecks Bool SheTyFalse where
> sheTypes _ = SheWitFalse
> data SheSpecialNil = SheSpecialNil
> data (:$#$#$#:) x y = (:$#$#$#:) x y
> data instance SheSingleton [t] dummy where
> SheSpecialWitNil :: SheSingleton [t] SheSpecialNil
> (:$%$%$%:) :: SheSingleton t x -> SheSingleton [t] xs ->
> SheSingleton [t] (x :$#$#$#: xs)
> instance SheChecks [t] SheSpecialNil where
> sheTypes _ = SheSpecialWitNil
> instance (SheChecks t x, SheChecks [t] xs) => SheChecks [t] (x :$#$#$#: xs) where
> sheTypes _ = (sheTypes (SheProxy :: SheProxy t x)) :$%$%$%:
> (sheTypes (SheProxy :: SheProxy [t] xs))