Haskell Constraint is no smaller than the instance head

后端 未结 2 1306
面向向阳花
面向向阳花 2020-12-05 00:13

Some rings can be equipped with a norm function:

class (Ring.C a) => EuclideanDomain a where
  norm :: a -> Integer

With this functio

2条回答
  •  执笔经年
    2020-12-05 00:35

    In order to avoid infinite loops, the compiler normally requires that the constraints of an instance are "smaller" than the instance itself, so that the algorithm will terminate. Your instance does not make a any smaller in the constraints, so that's what the compiler is complaining about.

    The UndecidableInstances extension lifts this restriction, leaving it up to you to prove that it will terminate. It's thus possible to send the compiler into an infinite loop when using this extension.

    The common solution to this is to add a newtype:

    newtype ByNorm a = ByNorm a
    
    instance (EuclideanDomain a, Eq a) => Ord (ByNorm a) where
        compare (ByNorm x) (ByNorm y) = compare (norm x) (norm y)
    

    Now the constraints are smaller than the instance head, as they strip off the newtype. No extension required.

提交回复
热议问题