If it is truly a type class, the value of the dictionary is determined only by type p . In particular, the type cat is defined only by p . This can be expressed using the data type associated with it. In a class definition, the associated data type is written as the data definition without the right side.
Once you express cat as a type, other members can easily be changed for class classes, as shown in Monad and MonadTrans . Note that I prefer to use explicit labels for complex types.
{-# LANGUAGE TypeFamilies, FlexibleInstances, UndecidableInstances #-} class Pipe (p :: * -> * -> (* -> *) -> * -> *) where data Cat p :: (* -> *) -> * -> * -> * -> * isoI :: forall abm r. Iso (->) (pabmr) (Category pmrab) categoryI :: forall ab m. Monad m => CategoryI (Category pmr) instance (Pipe p, Monad m) => Monad (pabm) instance Pipe p => MonadTrans (pab)
source share