我正在尝试show
某个类型为Tagged s b
(Data.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'
我有几个问题:
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应该能够发现其中一个实例不可能适用......)
修改
我创建了一个错误报告here,现在在回购头中删除了有问题的实例。下面的#3有一个很好的答案,但我仍然有兴趣知道为什么OverlappingInstances
/ IncoherentInstances
不起作用。
答案 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元组。这只会让它变得非常愚蠢,因为这意味着元组在种类和类型中都显示出来。