
On Tue, Apr 08, 2014 at 10:17:50AM +0200, jean-christophe mincke wrote:
class PP m where create :: a -> m a
data A a = A a instance PP A where create a = A a
class CB a where fb :: a -> a
data B m a = B (m a) instance (PP m) => PP (B m) where create a = let a' = fb a in B (create a')
Thanks for the clarified example. The failure here is not a technicality. There's a very good reason it can't work this way: 'create' is required to be parametrically polymorphic in 'a' but 'fb' is specialised to the *particular* 'a' in the typeclass constraint. Thus you can't use 'fb' to implement 'create'!
class PP' m a where create' :: a -> m a
instance (PP m) => PP' m a where create' = create
instance (PP m, CB a) => PP' (B m) a where create' a = let a' = fb a in B (create a')
create' is not required to be parametric, hence you can use 'fb' in its implementation. Without knowing more about your specific use case it's hard to know what to suggest. Personally speaking though, I am not a fan of complicated typeclass algebra, and prefer to create and pass dictionaries explicitly for all but the most trivial cases. Tom