Связанное семейство типов не работает, работает в автономном режиме

Когда у меня есть такой код:

class C where
  type T t1 t2
  ...

instance C (X t) where
  type T (X t) (t a b) = a
  ...

Получаю ошибку (с головой GHC):

• Polymorphic type indexes of associated type ‘T’
    (i.e. ones independent of the class type variables)
    must be distinct type variables

Предположительно это связано с тем, что (t a b) не является простой переменной, как предполагает ошибка.

Но я могу просто реорганизовать код следующим образом:

type family T t1 t2

class C where
  ...

type instance T (X t) (t a b) = a

instance C (X t) where
  ....

А то теперь вроде все нормально работает.

Из-за немного более запутанного синтаксиса, теряю ли я что-нибудь, извлекая определения семейств типов из классов, или определения внутри класса являются просто синтаксическим сахаром, поэтому их удаление является относительно бесплатным обходным решением?


person Clinton    schedule 21.07.2016    source источник
comment
Какие параметры для class C? Я думаю, это может быть важно.   -  person chi    schedule 21.07.2016
comment
Насколько я понимаю, в настоящее время ассоциированные семейства типов в значительной степени являются синтаксическим сахаром. Я не совсем уверен, что они должны были быть добавлены как таковые.   -  person dfeuer    schedule 21.07.2016


Ответы (1)


Этот

type family T t1 t2
type instance T (X t) (t a b) = a

примерно так работает

class K t1 t1 where
   type T t1 t2
instance K (X t) (t a b) where
   type T (X t) (t a b) = a

Обратите внимание, что все переменные t1,t2 являются параметрами класса K. Действительно, это требуется, когда переменные встречаются более одного раза (т.е. нелинейно), как гласит опубликованная ошибка:

• Polymorphic type indexes of associated type ‘T’
    (i.e. ones independent of the class type variables)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    must be distinct type variables

Итак, либо вы добавляете все эти переменные типа в свой класс, либо - с тем же эффектом - вы перемещаете семейство типов за пределы класса.


Это компилируется в GHC 8.0.

{-# LANGUAGE TypeFamilies, PolyKinds #-}

data X (t :: k) = X

class C t1 where
  type T t1 t2

instance C (X (t :: * -> * -> *)) where
  type T (X t) (t a b) = a
person chi    schedule 21.07.2016