首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解决重叠实例

如何解决重叠实例
EN

Stack Overflow用户
提问于 2016-04-28 11:55:49
回答 1查看 5.8K关注 0票数 11

我有以下代码(转换类似于转换)

代码语言:javascript
复制
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

当然,在我试图将Either a b转换为Either a b并获得以下错误消息时,这些实例会重叠(ParsingErrorEither something somethingElse的类型别名)

代码语言:javascript
复制
    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

我尝试了OVERLAPSOVERLAPPINGOVERLAPPABLE的不同组合,但都没有效果。我怎么才能解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-28 14:26:56

您必须更改其中一个实例定义:

代码语言:javascript
复制
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

无论在其他实例上使用哪种重叠,代码都会工作。在第二个实例中,您实际上不需要任何实用程序。

原始代码的问题是,实例实际上是不连贯的,而不仅仅是重叠的,所以{-# OVERLAPS / OVERLAPPING / OVERLAPPABLE #-}的任何组合都不会拯救您--您需要使用{-# INCOHERENT #-},这是不可取的,我也不推荐使用。GHC将告诉您这种与错误消息不一致的情况:

代码语言:javascript
复制
>: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'

本质上,为了从重叠实例中选择,一个实例必须是您要匹配的类型的“最特定的”。详细内容在用户指南中给出。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36913922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档