Haskell: definições de instância para famílias de tipos

Vamos dizer que temos o seguinte código:

<code>class C t where
  g :: t

instance C Int where
  g = 42
</code>

Simples. Podemos também definir funções no Int, assim:

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

Eu tenho trabalhado com famílias tipográficas, em particular porqueData.Has usa-os e quero inseri-los em umIxSet.

Mas aqui vou apresentar um exemplo simplificado. Vamos dizer que queremos definir um novo tipoX, isso é semelhante a um Int. Nós poderíamos fazer isso:

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

Podemos então definir funções emX igual a:

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

Sem problemas até agora. Agora vamos tentar definir uma instânciaC Xcomo fizemos paraC Int:

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

Uh oh, agora temos o seguinte erro:

Aplicação de família de sinônimos de tipo ilegal no exemplo:X
Na declaração de instância para'C X'

Agora vamos tentar algo um pouco diferente:

<code>newtype NewX = NewX X

instance C NewX where
  g = 43
</code>

Agora temos outro erro, a saber:

Nenhuma instância para(Num NewX)
decorrente do literal'43'

Parece que onewtype A palavra-chave elimina qualquer informação sobre quais classes a classe anterior pertencia também. No entanto, parece que não posso evitarnewtype, como não posso usar famílias de tipos nas definições de instância.

Existe uma maneira melhor de fazer isso sem ter que reescrever as definições de instância com referências de ocorrências explícitas adicionais que, de outra forma, seriam inferidas?

Informação de fundo:

A razão pela qual eu preciso que isso funcione é o seguinte:

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

Isso falha com:

Aplicação de família de sinônimos de tipo ilegal no exemplo:Row
Na declaração de instância para'Indexable Row'

FazerRow a newtype causa o seguinte erro:

Nenhuma instância para (contém (linha Labeled Col1 Text)) resultante de um uso de `^. ' Correção possível: adicione uma declaração de instância para (Contém (Linha Label Col1 Text))

A única maneira de contornar isso é adicionando uma cláusula de derivação longa da seguinte maneira:

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

Mesmo algo que me permite "typedef"Contains (Labelled x (TypeOf x)) dizerHasCol x seria útil.

questionAnswers(2)

yourAnswerToTheQuestion