Haskell约束不小于实例头

Haskell约束不小于实例头

本文介绍了Haskell约束不小于实例头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一些戒指可以配备一个标准功能:

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

有了这个函数,戒指可以按照明显的顺序排列:

  compare xy = compare(norm x)(norm y)

但我不确定如何表明这一点。我试图做到这一点:(b)
$ b

  instance(EuclideanDomain a,Eq a)=> Ord a其中

但这给了我一些警告,当我启用相关的编译器标志时,它告诉我约束不小于实例头 - 如果启用UndecidableInstances,一切都会到地狱。



有没有办法做我想做的事?

解决方案

hammar已经提供了解决方案;我想指出这个例子的另一个问题。你想表达的是每当一个类型是 Eq EuclideanDomain 的一个实例时,使用这个规则来创建一个 Ord 的实例。但这在Haskell中是不可压缩的。该行

  instance(EuclideanDomain a,Eq a)=> Ord a其中

其实意味着,使用此规则来制作 Ord 实例,如果 EuclideanDomain Eq 的实例不在范围。这是不好的,因为这个规则将与其他Ord实例重叠。



基本上任何时候你想写一个实例 class typevar ,你将需要一个新类型。


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.

这篇关于Haskell约束不小于实例头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 02:23