【问题标题】:Multiparameter typeclasses and illegal instance declarations多参数类型类和非法实例声明
【发布时间】:2015-12-16 17:44:33
【问题描述】:

我制作了一个这样的 Convertible 类:

class Convertible a b where
  convert :: a -> b

instance (Convertible a b, Functor f) => Convertible (f a) (f b) where
  convert = fmap convert

但是,如果我想将两个转换串在一起,我必须创建一个新实例,这很烦人。所以我尝试添加这个:

instance (Convertible a b, Convertible b c) => Convertible a c where
  convert = convert . convert

编译器抱怨:

Variable ‘b’ occurs more often than in the instance head
  in the constraint: Convertible a b
(Use UndecidableInstances to permit this)
In the instance declaration for ‘Convertible a c’
Variable ‘b’ occurs more often than in the instance head
  in the constraint: Convertible b c
(Use UndecidableInstances to permit this)
In the instance declaration for ‘Convertible a c’

此时我明白编译器为何抱怨我了,我真的不想打开 UndecidableInstances。我目前设置实例的方式是,每个 a 只有一个 Convertible a b 实例。我希望添加一个函数依赖 a -> b 可以缓解这种情况,但现在编译器抱怨仿函数实例:

Illegal instance declaration for ‘Convertible (f a) (f b)’
  The coverage condition fails in class ‘Convertible’
    for functional dependency: ‘a -> b’
  Reason: lhs type ‘f a’ does not determine rhs type ‘f b’
  Using UndecidableInstances might help
In the instance declaration for ‘Convertible (f a) (f b)’

关于如何使它工作的任何想法?或者,如果有必要,可能会有更好的设计?我想我可能只需要明确说明要采用哪种转换路径。

【问题讨论】:

标签: haskell typeclass


【解决方案1】:

我认为这需要UndecidableInstances:

instance (Convertible a b, Convertible b c) => Convertible a c where

给定a,由于函数依赖,我们可以计算出b。但是,不能保证这样的ba 更小/更简单!它可以是例如b ~ [[a]],在这种情况下,我们将检查Convertible a c 的问题简化为检查Convertible [[a]] c。这很容易导致实例搜索期间不终止,因为类参数没有减少。

相关说明:如果满足函数依赖,则只有一种类型b可以转换为a。在这种情况下,为什么需要传递性?没有任何其他 a 可以转换为。换句话说,在传递性情况下,您需要有c ~ b,否则您将让a 确定bc,这违反了函数依赖关系。 (我猜你毕竟并不真正想要函数依赖。)

无关说明:还要注意实例重叠——上面的实例看起来很麻烦。您可能还必须使用OverlappingInstances 和/或IncoherentInstances,这两者都可能导致头痛。

【讨论】:

  • 绝对语无伦次。一旦你必须应用传递性两次,GHC 就会宣布不连贯,这肯定不是这个混乱中不连贯的唯一来源。这就是 GHC 的强制机制需要使用自己的专用实例创建机制的原因之一,这与通常的机制完全不同。
猜你喜欢
  • 2011-08-25
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 1970-01-01
相关资源
最近更新 更多