The following code results in an error:
{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, StandaloneDeriving #-}
class Module a b where
(*>) :: a -> b -> b
data D
newtype DWrapper = DW D
instance Module D D
deriving instance Module DWrapper DWrapper
The error:
No instance for (Module DWrapper D) arising from a use of ‘Main.*>’
In the first argument of ‘GHC.Prim.coerce’, namely
‘(Main.*>) :: DWrapper -> D -> D’
In the expression:
GHC.Prim.coerce ((Main.*>) :: DWrapper -> D -> D) ::
DWrapper -> DWrapper -> DWrapper
In an equation for ‘*>’:
(*>)
= GHC.Prim.coerce ((Main.*>) :: DWrapper -> D -> D) ::
DWrapper -> DWrapper -> DWrapper
When typechecking the code for ‘Main.*>’
in a derived instance for ‘Module DWrapper DWrapper’:
To see the code I am typechecking, use -ddump-deriv
So GHC is looking for a Module DWrapper D
instance to derive the requested Module D D
instance. This is reasonable I guess, but not what I intended. Is there a way to tell GHC which instance to derive from? How does GNTD work on MPTCs?
Unfortunately, GeneralizedNewtypeDeriving
only works on the last parameter of a multi-parameter typeclass. Even with standalone deriving:
The stand-alone syntax is generalised for newtypes in exactly the same way that ordinary
deriving
clauses are generalised (Section 7.5.5, “Generalised derived instances for newtypes”). For example:newtype Foo a = MkFoo (State Int a) deriving instance MonadState Int Foo
GHC always treats the last parameter of the instance (
Foo
in this example) as the type whose instance is being derived.
(BTW, I tried searching for any relevant GHC trac bug report or feature request, but couldn't find any.)