I'm trying to show
something of type Tagged s b
(Data.Tagged) in a module that also imports from the accelerate library. Unfortunately, the accelerate library defines the show instance
instance Kit acc => Show (acc aenv a) where
in Data.Array.Accelerate.Pretty.hs. Reading around a bit, there's nothing I can do to avoid importing this instance, which obviously overlaps with the Data.Tagged Show
instance.
In fact, the generic accelerate instance prevents me from printing anything of kind *->*->*
.
Here's a simple example that demonstrates the problem:
{-# 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)
The error:
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'
I have a few questions:
- I thought
OverlappingInstances
would allow me to resolve the instance, but I get the same error. IncoherentInstances
should definitely let me compile...right? But it doesn't.Why does GHC report the Data.Tagged show instance as
Show (Tagged k s b)
when the instance (copied from Data.Tagged) is:instance Show b => Show (Tagged s b) where
I believe I have seen before where I was only able to resolve overlapping instances by adding an explicit type signature (to force GHC to choose the most specific instance), but as my example is at the top level and involves no polymorphism, I don't know how much more explicit I can be about the types.
My impression is that GHC should be able to choose the Data.Tagged instance since (I think) Tagged
is not an instance of Accelerate.Base.Kit
and therefore doesn't meet the instance constraints (I know we only match on the RHS of the instance, but GHC should be able to figure out that one of the instances couldn't possibly apply...)
EDIT
I created a bug report here, and the offending instance is now removed in the repo head. There's a great answer to #3 below, but I'm still interested in knowing why OverlappingInstances
/IncoherentInstances
didn't work.
I only know the answer to 3.
When a type is compiled with
-XPolyKinds
and no restriction on the kind of a type variable, GHC prints the type very badly. After the type name, it prints a list of kinds of all the polymorphic type variables, then the type variables. So thek
showing up in the type signature means that the type variables
can be of any kind. (Due to the way it's used,b
must have kind*
, so it's not kind-polymorphic, so its kind isn't listed.)As an example of how ridiculous this can get, here's an example from the haddock docs of a library I'm working on now..
It's using a promoted 5-tuple, too. That just makes it extra-silly, since that means the tuple shows up in both the kind and the type.