У меня есть следующий код. 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
(Т.е. я могу дать экземпляр Functor
для Hfree c f
когда Functor
является суперкласс c
.)
И это дает эту ошибку в Applicative инстанции (и аналогично для экземпляра Монада):
• 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)’
насколько я понимаю, что происходит, является то, что Прикладное экземпляр требует экземпляр Functor, поэтому аппликативный экземпляр также нуждается в 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
, потому что он не жалуется на недостающую ограничения. Вместо этого он застревает в ошибке совпадающих экземпляров. Было бы здорово, если бы был способ исправить ошибку, но я не могу понять, как это сделать!
ошибка не связанные с 'тест '- экземпляры' Monad' и 'Applicative' терпят неудачу с ошибкой перекрытия, потому что ваши экземпляры перекрываются очень плохо. Единственное ограничение формы 'SuperClass1 a b', которое компилятор сможет решить здесь, это' SuperClass1 a a' - то есть, когда типы априори известны как одно и то же. Во всех других случаях он даст вам сообщение об ошибке. (также обратите внимание, что GHC даже не знает, что 'SuperClass1 Functor c' подразумевает' Functor', когда 'c' держится - насколько это известно,' SuperClass1' фактически не содержит информации) – user2407038
не уверен, связано ли это с тем, что вы 'просить, но читать его как Prolog, '(SuperClass1 bc, Class1 ch) => SuperClass1 bh' должен быть' (Class1 ch, SuperClass1 bc) => SuperClass1 bh'. Смотрите, если это что-то изменит. Съемка в темноте здесь. :) –