{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeInType #-} {-# LANGUAGE UndecidableInstances #-} module T15419 where import Data.Kind data Prod a b data Proxy p = Proxy ----- data family Sing :: forall k. k -> Type data instance Sing x = STuple ----- type family Rep1 (f :: k -> Type) :: k -> Type type instance Rep1 ((,) a) = Prod a type family From1 (f :: Type -> Type) a (z :: f a) :: Rep1 f a type family To1 (f :: Type -> Type) a (z :: Rep1 f a) :: f a class Generic1 (f :: Type -> Type) where sFrom1 :: forall (a :: Type) (z :: f a). Proxy z -> Sing (From1 f a z) sTo1 :: forall (a :: Type) (r :: Rep1 f a). Proxy r -> Proxy (To1 f a r :: f a) instance Generic1 ((,) a) where sFrom1 Proxy = undefined sTo1 Proxy = undefined ----- type family Fmap (g :: b) (x :: f a) :: f b type instance Fmap (g :: b) (x :: (u, a)) = To1 ((,) u) b (Fmap g (From1 ((,) u) a x)) class PFunctor (f :: Type -> Type) where sFmap :: forall a b (g :: b) (x :: f a). Proxy g -> Sing x -> Proxy (Fmap g x) instance PFunctor (Prod a) where sFmap _ STuple = undefined sFmap1 :: forall (f :: Type -> Type) (u :: Type) (b :: Type) (g :: b) (x :: f u). (Generic1 f, PFunctor (Rep1 f), Fmap g x ~ To1 f b (Fmap g (From1 f u x)) ) => Proxy g -> Proxy x -> Proxy (Fmap g x) sFmap1 sg sx = sTo1 (sFmap sg (sFrom1 sx)) sFmap2 :: forall (p :: Type) (a :: Type) (b :: Type) (g :: b) (x :: (p, a)). Proxy g -> Proxy x -> Proxy (Fmap g x) sFmap2 = sFmap1