我有以下代码(转换类似于转换)
instance {-# OVERLAPS #-} Transformable a a where
transform x = x
instance {-# OVERLAPPABLE #-} (Transformable l l', Transformable r r' )
=> Transformable (Either l r) (Either l' r')
where
transform = bimap transform transform
Run Code Online (Sandbox Code Playgroud)
当然,这些情况在我试图改变的情况下重叠Either a b来Either a b,并得到以下错误消息(ParsingError是一个类型别名Either something somethingElse)
Overlapping instances for Transformable
(parsingerror text) (parsingerror text)
arising from a use of ‘makereceipt’
matching instances:
Matching instances: Overlapping instances for Transformable
(ParsingError Text) (ParsingError Text)
arising from a use of ‘makeReceipt’
Matching instances:
instance [overlappable] (Transformable l l', Transformable r r') =>
Transformable (Either l r) (Either l' r')
instance [overlappable] (Transformable l l', Transformable r r') =>
Transformable (Either l r) (Either l' r')
-- Defined at Handler/GLEnterReceiptSheet/ReceiptRow.hs:154:31
instance [overlap ok] Transformable a a
-- Defined at Handler/GLEnterReceiptSheet/ReceiptRow.hs:151:27
Run Code Online (Sandbox Code Playgroud)
我尝试不同的组合OVERLAPS,OVERLAPPING并OVERLAPPABLE但没有任何工程.我怎么解决这个问题?
use*_*038 10
您将不得不更改其中一个实例定义:
class Transformable a b where
transform :: a -> b
-- this one
instance {-# OVERLAPS #-} (a ~ b) => Transformable a b where
transform x = x
instance (Transformable l l', Transformable r r' )
=> Transformable (Either l r) (Either l' r') where
transform = either (Left . transform) (Right . transform)
test0 :: (Transformable a a', Transformable b b') => Either a b -> Either a' b'
test0 = transform
Run Code Online (Sandbox Code Playgroud)
无论您在另一个实例上使用哪个重叠,代码都将起作用.你实际上并不需要在第二个实例上使用任何编译指示.
原始代码的问题在于实例实际上是不连贯的,而不仅仅是重叠,所以没有组合{-# OVERLAPS/OVERLAPPING/OVERLAPPABLE #-}会省去你 - 你需要使用{-# INHCOHERENT #-},这是不可取的,我不建议.GHC将在错误消息中告诉您这种不一致性:
>:t transform :: (Transformable a a', Transformable b b') => Either a b -> Either a' b'
<interactive>:1:1: Warning:
Overlapping instances for Transformable
(Either a1 b1) (Either a'1 b'1)
arising from a use of `transform'
Matching instances:
instance [overlappable] (Transformable l l', Transformable r r') =>
Transformable (Either l r) (Either l' r')
-- Defined at test6.hs:9:31
instance [overlap ok] Transformable a a -- Defined at test6.hs:6:27
(The choice depends on the instantiation of `a1, b1, a'1, b'1'
To pick the first instance above, use IncoherentInstances
when compiling the other instance declarations)
In the expression:
transform ::
(Transformable a a', Transformable b b') =>
Either a b -> Either a' b'
Run Code Online (Sandbox Code Playgroud)
本质上,为了从重叠的实例中挑选,一个实例必须对您要匹配的类型"最具体".用户指南中给出了详细信息.