我正在尝试在一个也从加速库导入的模块中show
输入某种类型的东西Tagged s b
(Data.Tagged )。不幸的是,加速库定义了显示实例
instance Kit acc => Show (acc aenv a) where
在 Data.Array.Accelerate.Pretty.hs 中。阅读了一下,我无法避免导入这个实例,它显然与 Data.TaggedShow
实例重叠。事实上,通用加速实例阻止我打印任何类型的东西*->*->*
。
这是一个演示问题的简单示例:
{-# 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'
我有几个问题:
- 我以为
OverlappingInstances
可以让我解决实例,但我得到了同样的错误。 IncoherentInstances
绝对应该让我编译...对吗?但事实并非如此。为什么 GHC 将 Data.Tagged 显示实例报告为
Show (Tagged k s b)
实例(从 Data.Tagged 复制)为:instance Show b => Show (Tagged s b) where
我相信我以前见过我只能通过添加显式类型签名来解决重叠实例(以强制 GHC 选择最具体的实例),但由于我的示例处于顶层并且不涉及多态性,所以我没有不知道我对这些类型能说得清楚多少。
我的印象是 GHC 应该能够选择 Data.Tagged 实例,因为(我认为)Tagged
不是实例,Accelerate.Base.Kit
因此不符合实例约束(我知道我们只匹配实例的 RHS,但 GHC 应该能够找出其中一个实例不可能适用...)
编辑
我在这里创建了一个错误报告,现在在 repo 头中删除了有问题的实例。下面的#3 有一个很好的答案,但我仍然想知道为什么OverlappingInstances
/IncoherentInstances
不起作用。