Haskell 约束不小于实例头 [英] Haskell Constraint is no smaller than the instance head

查看:24
本文介绍了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

但这给了我一些警告,当我启用相关的编译器标志时,它告诉我约束不小于实例头" - 如果我启用 UndecidableInstances,一切都会变得糟糕.

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 已经提供了解决方案;我想指出这个例子的另一个问题.你想表达的是当一个类型是EqEuclideanDomain的实例时,用这个规则为Ord创建一个实例."但这在 Haskell 中是无法表达的.线

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

实际上的意思是,使用此规则为任何类型创建 Ord 实例.如果 EuclideanDomainEq 的实例不是不在范围内".这不太好,因为这条规则会与所有其他 Ord 实例重叠.

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.

基本上任何时候你想写一个实例Class typevar,你都需要一个新类型.

Basically any time you want to write an instance Class typevar, you're going to need a newtype.

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆