Functor超类型具有冲突的实例

Zoe*_*wll 4 haskell

我已经定义了一个Fine-Grained Functor类(FgFunctor),以便将约束应用于可以映射到Ordered Triple数据类型(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
Run Code Online (Sandbox Code Playgroud)

代码工作正常,直到我将所有其他Functors 定义为FgFunctors,如下所示:

-- all regular functors are also fine-grained ones
instance Functor f => FgFunctor f a b where
    fgmap = fmap
Run Code Online (Sandbox Code Playgroud)

使用该实例声明,只要我尝试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
Run Code Online (Sandbox Code Playgroud)

然而,第一个"匹配实例"它指的是不应该适用于OrdTriple,如OrdTriple不是Functor,所以我很努力,以确定是什么原因造成的所谓重叠.

sna*_*nak 5

当编译器(GHC)查找特定类型的类型类的实例时,它不会考虑每个实例的上下文.这就是为什么它发现了两个FgFunctorfor的实例,OrdTriple即使OrdTriple它不是一个实例Functor.

GHC/AdvancedOverlap向您展示如何解决这种情况.