问题描述
我定义了一个细粒度函子类(FgFunctor
),以便将约束应用于类型可能会映射到我的Ordered Triple数据类型(OrdTriple
)上的函数,这要求所包含的类型是可排序的.
I have defined a Fine-Grained Functor class (FgFunctor
) in order to apply a constraint to the type of functions that may map over my Ordered Triple datatype (OrdTriple
), which requires the contained type be orderable.
import Data.List (sort)
-- 'fine-grained' functor
class FgFunctor f a b where
fgmap :: (a -> b) -> f a -> f b
data OrdTriple a = OrdTriple a a a deriving Show
instance (Ord a, Ord b) => FgFunctor OrdTriple a b where
fgmap f (OrdTriple n d x) = OrdTriple n' d' x'
where [n', d', x'] = sort [f n, f d, f x]
main :: IO ()
main = do
let test = fgmap (* 10^4) $ OrdTriple 1 6 11
print test
在我将所有其他Functor
都定义为FgFunctor
之前,代码也可以正常工作,就像这样:
The code works fine until I define all other Functor
s to also be FgFunctor
s, like so:
-- all regular functors are also fine-grained ones
instance Functor f => FgFunctor f a b where
fgmap = fmap
有了该实例声明,当我尝试在OrdTriple
类型上使用fgmap
时,编译器就会抱怨实例声明重叠
With that instance declaration, as soon as I try to use fgmap
on my OrdTriple
type, the compiler complains about overlapping instance declarations
Overlapping instances for FgFunctor OrdTriple b0 b0
arising from a use of ‘fgmap’
Matching instances:
instance Functor f => FgFunctor f a b
-- Defined at OrdTriple.hs:15:10
instance (Ord a, Ord b) => FgFunctor OrdTriple a b
-- Defined at OrdTriple.hs:18:10
In the expression: fgmap (* 10 ^ 4)
In the expression: fgmap (* 10 ^ 4) $ OrdTriple 1 6 11
In an equation for ‘test’:
test = fgmap (* 10 ^ 4) $ OrdTriple 1 6 11
但是,它所引用的第一个匹配实例"永远都不适用于OrdTriple
,因为OrdTriple
不是Functor
,因此我正在努力确定是什么导致了假定的重叠.
However, the first 'matching instance' it refers to should never apply to OrdTriple
, as OrdTriple
is not a Functor
, and so I am struggling to determine what is causing the supposed overlap.
推荐答案
当编译器(GHC)查找特定类型的类型类的实例时,它不会考虑每个实例的上下文.这就是为什么即使OrdTriple
不是Functor
的实例,它也为OrdTriple
找到两个FgFunctor
实例的原因.
When the compiler (GHC) looks for instances of a type class for a specific type, it doesn't take contexts of each instance into account. That's why it found two instances of FgFunctor
for OrdTriple
even though OrdTriple
is not an instance of Functor
.
GHC/AdvancedOverlap 向您展示了如何解决这种情况.
GHC/AdvancedOverlap shows you how you can solve this situation.
这篇关于函子超型具有冲突的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!