GHC complains about overlapping instances when in fact they are not

133 views Asked by At

I have the function toAVector defined like this:

class Elt a => ToAVector v a where
  toAVector :: v a -> A.Array DIM1 a

instance Elt a => ToAVector [] a where
  toAVector l =
    A.fromList (Z :. P.length l) l

instance (Elt a, G.Vector v a) => ToAVector v a where
  toAVector v =
    A.fromFunction (Z :. G.length v) (\(Z :. i) -> v G.! i)
  {-# INLINE toAVector #-}

When trying to use toAVector in another library, I get the error:

Overlapping instances for ToAVector [] Double
  arising from a use of ‘toAVector’
Matching instances:
  instance (A.Elt a, G.Vector v a) => ToAVector v a
    -- Defined in ‘Data.Array.Accelerate.Utils’
  instance A.Elt a => ToAVector [] a
    -- Defined in ‘Data.Array.Accelerate.Utils’

This doesn't make sense to me as [] does not match G.Vector [] a, so how could the instances be overlapped?

1

There are 1 answers

0
leftaroundabout On BEST ANSWER

Instances are only matched by the instance head. So, for the purpose of overlapping or not, what you wrote is no better than

instance ToAVector [] a
instance ToAVector v a

which is clearly overlapping.

To argue another way:

... as [] does not match G.Vector [] a ...

this is never valid reasoning in Haskell, since type classes are open. You can never know something is not an instance of a particular class, because anyone could make it an instance later on.