解决外部库中的重叠实例

时间:2013-08-06 03:37:37

标签: haskell namespaces multiple-instances overlapping-instances

我正在尝试show某个类型为Tagged s bData.Tagged)的内容,该模块也会从accelerate库中导入。不幸的是,加速库定义了show instance

instance Kit acc => Show (acc aenv a) where

在Data.Array.Accelerate.Pretty.hs中。稍微阅读一下,我无法避免导入此实例,这显然与Data.Tagged Show实例重叠。 事实上,通用加速实例阻止我打印任何类型的*->*->*

这是一个演示问题的简单示例:

{-# LANGUAGE FlexibleContexts, OverlappingInstances, IncoherentInstances #-}

import Data.Array.Accelerate
import Data.Tagged

main :: (Show (Tagged Int Int)) => IO ()
main = let x = Tagged 3
   in print (x::Tagged Int Int)

错误:

    Overlapping instances for Show (Tagged * Int Int)
      arising from a use of `print'
    Matching instances:
      instance Show b => Show (Tagged k s b) -- Defined in `Data.Tagged'
      instance [overlap ok] accelerate-0.13.0.5:Data.Array.Accelerate.Trafo.Base.Kit
                          acc =>
                        Show (acc aenv a)
    -- Defined in `Data.Array.Accelerate.Pretty'

我有几个问题:

  1. 我认为OverlappingInstances会允许我解析实例,但我得到同样的错误。
  2. IncoherentInstances应该肯定让我编译......对吗?但事实并非如此。
  3. 为什么GHC将Data.Tagged节目实例报告为Show (Tagged k s b) 当实例(从Data.Tagged复制)是:

    instance Show b => Show (Tagged s b) where
    
  4. 我相信我之前看到过我只能通过添加显式类型签名来解决重叠实例(强制GHC选择最具体的实例),但由于我的示例位于顶级并且不涉及多态,我不知道我对这些类型有多明确。

    我的印象是GHC应该能够选择Data.Tagged实例,因为(我认为)Tagged不是Accelerate.Base.Kit的实例,因此不符合实例约束(我知道)我们只匹配实例的RHS,但GHC应该能够发现其中一个实例不可能适用......)

    修改

    我创建了一个错误报告here,现在在回购头中删除了有问题的实例。下面的#3有一个很好的答案,但我仍然有兴趣知道为什么OverlappingInstances / IncoherentInstances不起作用。

1 个答案:

答案 0 :(得分:5)

我只知道3的答案。

当使用-XPolyKinds编译类型并且对类型变量的类型没有限制时,GHC会非常严重地打印类型。在类型名称之后,它会打印所有多态类型变量的种类列表,然后是类型变量。因此,类型签名中显示的k意味着类型变量s可以是任何类型。 (由于使用它的方式,b必须有*种类,所以它不是多种多样的,所以它的类型不会被列出。)

作为一个可以获得多么荒谬的例子,这里是我现在正在处理的图书馆的黑线鳕文档的一个例子。

(SingI Nat a, SingI Nat b, SingI Nat c, SingI Nat d, SingI Nat e) => StaticSize ((,,,,) Nat Nat Nat Nat Nat) ((,,,,) Nat Nat Nat Nat Nat a b c d e)

它也使用了升级的5元组。这只会让它变得非常愚蠢,因为这意味着元组在种类和类型中都显示出来。