Some rings can be equipped with a norm function:
class (Ring.C a) => EuclideanDomain a where norm :: a -> Integer
With this function, the ring can be ordered in the obvious way:
compare x y = compare (norm x) (norm y)
But I'm not sure how to indicate this. I tried to do
instance (EuclideanDomain a, Eq a) => Ord a where
but this gives me some warnings, and when I enable the relevant compiler flags it tells me "Constraint is no smaller than the instance head" - if I enable UndecidableInstances everything goes to hell.
Is there a way to do what I want?
hammar's already provided a solution; I'd like to point out another problem with this example. What you want to express is "Whenever a type is an instance of Eq
and EuclideanDomain
, use this rule to make an instance for Ord
." But this is inexpressible in Haskell. The line
instance (EuclideanDomain a, Eq a) => Ord a where
actually means, "Use this rule to make an Ord
instance for any type. It's an error if instances of EuclideanDomain
and Eq
aren't in scope". That's not good, because this rule will overlap with every other Ord instance.
Basically any time you want to write an instance Class typevar
, you're going to need a newtype.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With