我有以下代码。Class1
实例说明一个类的直接超类是什么,SuperClass1
自动遍历Class1
查找所有超类。(我省略了这些类的实际方法,因为它们与我的问题无关。)
{-# LANGUAGE PolyKinds, RankNTypes, ConstraintKinds, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, FunctionalDependencies #-}
class Class1 b h | h -> b
instance Class1 Functor Applicative
instance Class1 Applicative Monad
class SuperClass1 b h
instance {-# OVERLAPPING #-} SuperClass1 b b
instance {-# OVERLAPPABLE #-} (SuperClass1 b c, Class1 c h) => SuperClass1 b h
这很好用!现在我想像这样使用它:
newtype HFree c f a = HFree { runHFree :: forall g. c g => (forall b. f b -> g b) -> g a }
instance SuperClass1 Functor c => Functor (HFree c f)
instance SuperClass1 Applicative c => Applicative (HFree c f)
instance SuperClass1 Monad c => Monad (HFree c f)
test :: (a -> b) -> HFree Monad f a -> HFree Monad f b
test = fmap
(即我可以给出一个 for 的实例,Functor
只要Hfree c f
是Functor
的超类c
。)
这在 Applicative 实例中给出了这个错误(与 Monad 实例类似):
• Overlapping instances for SuperClass1 Functor c1
arising from the superclasses of an instance declaration
Matching instances:
instance [overlappable] forall k k k (b :: k) (c :: k) (h :: k).
(SuperClass1 b c, Class1 c h) =>
SuperClass1 b h
-- Defined at superclass.hs:17:31
instance [overlapping] forall k (b :: k). SuperClass1 b b
-- Defined at superclass.hs:16:30
(The choice depends on the instantiation of ‘c1, k1’
To pick the first instance above, use IncoherentInstances
when compiling the other instance declarations)
• In the instance declaration for ‘Applicative (HFree c f)’
据我了解,Applicative 实例需要 Functor 实例,所以 Applicative 实例也需要SuperClass1 Functor c
Functor 的约束。事实上,如果我添加这个,错误就会消失。(这是我目前拥有的:http: //hackage.haskell.org/package/free-functors-0.7/docs/Data-Functor-HFree.html)
但不知何故,GHC 足够聪明,可以理解这SuperClass1 Applicative c
意味着SuperClass1 Functor c
,因为它不会抱怨缺少约束。相反,它会卡在重叠实例错误上。如果有办法修复错误,那就太好了,但我不知道怎么做!