Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Constraint is no smaller than the instance head

Tags:

haskell

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?

like image 864
Xodarap Avatar asked Aug 26 '11 00:08

Xodarap


1 Answers

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.

like image 198
John L Avatar answered Sep 21 '22 09:09

John L