Почему эти заявления семейных инстанций противоречат друг другу?

Я получаю ошибку для этого кода, и я не понимаю, где конфликт.

{-# 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

Когда я загружаю свой код в GHC, я получаю следующую ошибку:

λ> :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.

2 ответа

Решение

В таком случае, как

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

GHC учитывает только правую часть стрелки экземпляра при сопоставлении экземпляров. То есть ограничения не учитываются. Так Gene g перекрывается с любым другим экземпляром, и, в частности, один для Gene [a] выше.

Перекрывающиеся экземпляры допускаются при определенных условиях, но перекрывающиеся связанные типы или семейства типов не допускаются (они будут, в некоторых ограниченных случаях, в будущих выпусках GHC). Таким образом, вы получаете ошибку на двух Sequence деклараций.

Информацию о разрешении перекрывающихся семейств типов в будущих GHC смотрите в этом билете. Также стоит отметить, что в случае семейств закрытых типов допускается некоторое (большинство? Все?) Перекрытие. Например, следующее не работает как семейство открытого типа:

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

но компилируется как семейство закрытого типа:

type family NextListElt (xs :: [*]) (a :: *) :: * where
  NextListElt (a ': b ': xs) a = b
  NextListElt (b ': c ': xs) a = NextListElt (c ': xs) a
Другие вопросы по тегам