Question

I'm getting an error for this code, and I don't understand where the conflict is.

{-# LANGUAGE TypeFamilies, FlexibleContexts, FlexibleInstances,
    UndecidableInstances #-}

import Codec.Gray (integralToGray, grayToIntegral)
import Data.List (foldl', unfoldr)
import Data.Word (Word8)
import Prelude hiding (read)

class Gene g where
  type Sequence g
  write :: Sequence g -> g -> Sequence g
  read :: Sequence g -> Maybe (g, Sequence g)

instance (Gene a, Sequence a ~ [k], Integral k, Gene k, Sequence k ~ [k]) => Gene [a] where
  type Sequence [a] = Sequence a -- LINE 15
  write xs gs = Nothing -- stub
  read xs = Nothing -- stub


class (Enum g, Bounded g) => Word8Enum g where
  writeEnum :: [Word8] -> g -> [Word8]
  writeEnum xs g = Nothing -- stub

  readEnum :: g -> [Word8] -> Maybe (g, [Word8])
  readEnum _ [] = Nothing
  readEnum model (x:xs) = Nothing -- stub

instance (Word8Enum g) => Gene g where
  type Sequence g = [Word8] -- LINE 29
  write = writeEnum
  read = readEnum undefined

When I load my code into GHC, I get the following error:

λ> :l amy4
[1 of 1] Compiling Main             ( amy4.hs, interpreted )

amy4.hs:15:8:
    Conflicting family instance declarations:
      type Sequence [a] -- Defined at amy4.hs:15:8
      type Sequence g -- Defined at amy4.hs:29:8
Failed, modules loaded: none.
Was it helpful?

Solution 2

In an instance such as

instance (Word8Enum g) => Gene g where
   ...

GHC considers only the right hand side of the instance arrow when matching instances. I.e., constraints aren't considered. So Gene g overlaps with any other instance, and in particular the one for Gene [a] above.

Overlapping instances are allowed under certain conditions, but overlapping associated types or type families are not (they will be, in some restricted cases, in upcoming releases of GHC). Therefore, you get the error on the two Sequence declarations.

OTHER TIPS

For information about allowing overlapping type families in future GHCs, see this ticket. It's also worth pointing out that with closed type families, some (most? all?) overlap is allowed. For example, the following does not work as an open type family:

type family NextListElt (xs :: [*]) (a :: *) :: *
type instance NextListElt (a ': b ': xs) a = b
type instance NextListElt (b ': c ': xs) a = NextListElt (c ': xs) a

but compiles as a closed type family:

type family NextListElt (xs :: [*]) (a :: *) :: * where
  NextListElt (a ': b ': xs) a = b
  NextListElt (b ': c ': xs) a = NextListElt (c ': xs) a
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top