我已经定义了一个Fine-Grained Functor类(Range
),以便将约束应用于可以映射到我的Ordered Triple数据类型(FgFunctor
)的函数类型,这需要包含的类型可以订购。
OrdTriple
代码正常工作,直到我将所有其他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
s,如下所示:
FgFunctor
使用该实例声明,只要我尝试在-- all regular functors are also fine-grained ones
instance Functor f => FgFunctor f a b where
fgmap = fmap
类型上使用fgmap
,编译器就会抱怨重叠的实例声明
OrdTriple
但是,它引用的第一个“匹配实例”应该永远不适用于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
,所以我很难确定是什么导致了假设重叠。
答案 0 :(得分:5)
当编译器(GHC)查找特定类型的类型类的实例时,它不会考虑每个实例的上下文。这就是为什么它为FgFunctor
找到OrdTriple
的两个实例,即使OrdTriple
不是Functor
的实例。
GHC/AdvancedOverlap向您展示如何解决这种情况。