【发布时间】: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)’
关于如何使它工作的任何想法?或者,如果有必要,可能会有更好的设计?我想我可能只需要明确说明要采用哪种转换路径。
【问题讨论】:
-
虽然它不太可能帮助您做您想做的事情,但您绝对应该阅读 Breitner 等人的 Safe Zero-cost Coercions for Haskell。