我有一个多参数类型类,它提供了一个有意义的函数,可以将其参数互换:
class Swappable a b where
swappable :: a -> b -> Bool
因此,如果
a
和b
形成Swappable a b
,则b
和a
应该形成Swappable b a
。为每个普通实例编写一个交换实例会很麻烦,所以我天真地写道instance Swappable a b => Swappable b a where
swappable b a = swappable a b
不会编译并显示以下错误:
• Illegal instance declaration for ‘Swappable b a’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for ‘Swappable b a’
|
12 | instance Swappable a b => Swappable b a where
| ^^^^^^^^^^^^^
现在,我并不反对打开
FlexibleInstances
,但我不明白为什么我首先需要它。那里的所有类型变量都出现一次,并且都是不同的。那么,为什么会出现此错误? 最佳答案
All instance types must be of the form (T a1 ... an)
表示您的实例必须采用以下形式
instance Swappable (T a1 .. an) (U b1 .. bn) where ...
其中
T
和U
是类型构造函数。没有该扩展名,就不能只有一个变量a
和b
,而没有顶部的构造函数。无论如何,
FlexibleInstances
是无害的,并且可以说默认情况下应将其打开。也许Haskell报告的未来修订版将包含该报告。相反,我会更担心重叠。
instance Swappable b a => Swappable a b
将与任何其他实例重叠。它还将需要不确定的实例。我不确定您要达到的目标是一个好主意。