我有一个multiparam类型类,它提供了一个有意义的函数交换参数:
class Swappable a b where
swappable :: a -> b -> Bool
Run Code Online (Sandbox Code Playgroud)
所以,如果a和b形式Swappable a b,然后b和a应该形成Swappable b a.为每个普通实例编写一个交换实例将是一件苦差事,所以我天真地写道
instance Swappable a b => Swappable b a where
swappable b a = swappable a b
Run Code Online (Sandbox Code Playgroud)
哪个不能编译,出现以下错误:
• 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
| ^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
现在,我并不反对开启FlexibleInstances,但我不明白为什么我首先需要它.所有类型变量都出现一次,并且都是不同的.那么为什么我会收到这个错误?
All instance types must be of the form (T a1 ... an)
Run Code Online (Sandbox Code Playgroud)
表示您的实例必须是表单
instance Swappable (T a1 .. an) (U b1 .. bn) where ...
Run Code Online (Sandbox Code Playgroud)
where T和U是类型构造函数.没有该扩展,您不能只有单个变量a,也不能b在顶部没有构造函数.
FlexibleInstances无论如何,它是无害的,默认情况下应该可以开启.也许Haskell报告的未来版本将包含它.
相反,我会更关注重叠.instance Swappable b a => Swappable a b将与任何其他实例重叠.它还需要不可判定的实例.我不确定你想要实现的是一个好主意.