Assume I have a parametric type defined like this:
newtype FancyComplex a b = FancyComplex (a, b)
I intend to never use this newtype for any other parameters than numeric ones.
I mean that for whatever implementation I might do, I know that parameters a and b will always be an instance of Num .
I read in this question that you can do this: Can a typeclass constraint be used in a newtype definition?
{-# LANGUAGE RankNTypes #-}
newtype (Num a, Num b) => FancyComplex a b = FancyComplex (a, b)
However this is not enough. If I write any class like this:
class StupidClass x where add :: x -> x -> x
Then I should be able to write
instance StupidClass (FancyComplex a b) where
add (FancyComplex (a, b)) (FancyComplex (a', b')) = FancyComplex (a+a', b+b')
But no GHC will tell me saying I did not enforce the Num requirement.
So I am forced to do this everytime:
instance (Num a, Num b) => StupidClass (FancyComplex a b) where
add (FancyComplex (a, b)) (FancyComplex (a', b')) = FancyComplex (a+a', b+b')
All that writing the constraint in the newtype definition does, is force me to write the constraint explicitly every time. Ok this is still useful in case I forget. But of course I would expect not to have to rewrite the constraint everytime.
How can I automatically and implicitly inherit constraints from the newtype definition? Is this possible? if not, is there a reason why not?
Currently my weak workaround is to define a type alias type FancyComplexReqs a b = (Num a, Num b)
Thanks