My data types will always have at least two parameters, and the last two parameters are always equal to "q" and "m", respectively:
{-
This program produces an error
Could not deduce (bBase ~ D2 t0) (LINE 1)
When I wrote the instance, of course, I meant bBase ~ D2 t . I think t is not connected in some way (hence the introduction of t0), and I don't know if the GHC can deconstruct this type at all. Or maybe I'm just doing something stupid.
Moreover, this type of decomposition of type decomposition type would not be needed if I made the parameter for Bar look like * β * β *. But then I could not force the restriction Foo:
class (Foo (bq)) => Bar b where -- b has kind * -> * -> * g :: bqm -> qb' -- this signature is now quite simple, and I would have no problem implementing it
This will not work, because q is not a parameter for Bar, and I do not want the parameter to be in Bar.
I found a solution using TWO extra "dummy" related types, but I don't really like them if I don't need them:
class (Foo b, b ~ (BBase b) (BMod b)) => Bar b where -- b has kind * -> * type BBase b :: * -> * -> * type BMod b :: * g :: (Qux (BMod b), Qux q') => bm -> (BBase b) q' m instance (Foo (D2 tq), Integral q) => Bar (D2 tq) where type BBase (D2 tq) = D2 t type BMod (D2 tq) = q g (D2 q) = D2 $ fromIntegral q
This works, but it clearly explicitly deconstructs a type that, it seems to me, is not needed with a simple instance of the instance.
Iβm looking for a solution for any approach: either tell me how I can force class restriction to a βmore appliedβ type, or tell me how to make GHC deconstruction types.
Thanks!