Haskell: определения экземпляров для семейств типов

Допустим, у нас есть следующий код:

<code>class C t where
  g :: t

instance C Int where
  g = 42
</code>

Просто. Мы также можем определить функции на Int, например, так:

<code>f1 :: Int -> Int
f1 x = x * x
</code>

Я работал с семействами типов, в частности потому, чтоData.Has использует их, и я хочу вставить их вIxSet.

Но здесь я собираюсь представить упрощенный пример. Допустим, мы хотим определить новый типX, что похоже на Int. Мы могли бы сделать это:

<code>type family X
type instance X = Int
</code>

Затем мы можем определить функции наX вот так:

<code>f2 :: X -> X
f2 x = x * x + 1
</code>

Пока проблем нет. Теперь давайте попробуем определить экземплярC Xкак мы сделали дляC Int:

<code>instance C X where
  g = 43
</code>

Ой, теперь у нас есть следующая ошибка:

Illegal type synonym family application in instance: X
In the instance declaration for 'C X'

Теперь давайте попробуем что-то немного другое:

<code>newtype NewX = NewX X

instance C NewX where
  g = 43
</code>

Теперь у нас есть другая ошибка, а именно:

No instance for (Num NewX)
arising from the literal '43'

Кажется, чтоnewtype Ключевое слово исключает любую информацию о том, к каким классам принадлежал предыдущий класс. Однако, кажется, что я не могу избежатьnewtype, поскольку я не могу использовать семейства типов в определениях экземпляров.

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

Background information:

Причина, по которой мне нужно это работает, заключается в следующем:

<code>import Data.Has
import Data.IxSet

data Col1 = Col1; type instance TypeOf Col1 = Text
data Col2 = Col2; type instance TypeOf Col2 = Text

type Row = FieldOf Col1 :&: FieldOf Col2;

instance Indexable Row where
  empty = ixSet [ixFun $ (\x -> [ Col1 ^. x ]) ] -- Maybe add some more indexes later
</code>

Это не с:

Illegal type synonym family application in instance: Row
In the instance declaration for 'Indexable Row'

ИзготовлениеRow newtype вызывает следующую ошибку:

No instance for (Contains (Labelled Col1 Text) Row) arising from a use of `^.' Possible fix: add an instance declaration for (Contains (Labelled Col1 Text) Row)

Единственный способ, которым я могу обойти это, - это добавить длинное производное предложение следующим образом:

<code>newtype Row = Row (FieldOf Col1 :&: FieldOf Col2)
  deriving 
  (
    Contains (Labelled Col1 Text), -- Add this for every column
    Contains (Labelled Col2 Text)  -- ...
  )
</code>

Даже то, что позволяет мне "typedef"Contains (Labelled x (TypeOf x)) сказатьHasCol x было бы полезно.

Ответы на вопрос(2)

Ваш ответ на вопрос