{-# language TypeFamilies, DataKinds, UndecidableSuperClasses, UndecidableInstances, TypeFamilyDependencies, QuantifiedConstraints #-} module M where import GHC.TypeLits data FArray (n :: Nat) instance Num (FArray n) class Tensor r where type TensorOf (n :: Nat) r = t | t -> n r type Primal r instance Tensor Float where type TensorOf n Float = FArray n type Primal Float = Float class c (TensorOf n r) => CTensorOf c n r where instance c (TensorOf n r) => CTensorOf c n r where foo :: (forall n. CTensorOf Num n r) => TensorOf n r -> TensorOf n r foo x = x foo2 :: (p ~ Primal r, forall n. CTensorOf Num n p) => TensorOf n r -> TensorOf n (Primal r) -> TensorOf n (Primal r) foo2 _ x = x bar :: FArray n -> FArray n bar x = foo x