Eu tenho uma dúzia de tipos novos como este:
newtype MyBool = MyBool Bool
newtype MyInt = MyInt Int
Quero reutilizar instâncias existentes:
instance MArray IOUArray Int IO where ...
instance MArray (STUArray s) Int (ST s) where ...
Implementar essas instâncias e ter todo o código padrão é a última coisa que eu quero.
Encontrei algo que parece muito próximo do que estou tentando alcançar:
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
deriving instance MArray IOUArray MyInt IO
deriving instance MArray (STUArray s) MyInt (ST s)
No entanto, ele falha com:
Can't make a derived instance of ‘MArray IOUArray MyInt IO’
(even with cunning GeneralizedNewtypeDeriving):
cannot eta-reduce the representation type enough
In the stand-alone deriving instance for ‘MArray IOUArray MyInt IO’
Como fazer isso funcionar?
Se não for possível, qual é a maneira menos dolorosa de obter essas instâncias?
type role IOUArray nominal nominal
portanto não podemos coagir do array-of-int ao array-of-myint. (Eu me pergunto por que temos tais papéis.)Storable
instância diferente para suas representações sem caixa (por exemplo, usando um número menor que oInt
número inteiro para armazenar sem caixanewtype Age = Age Int
).Respostas:
A partir da documentação :
Como o último parâmetro de classe no seu caso não é
Int
/MyInt
, mas simIO
/ST s
, você está sem sorteGeneralizedNewtypeDeriving
, infelizmente.fonte
Ok, você está meio que preso aqui porque algumas opções de design no
array
pacote dificultaram, mas aqui está uma abordagem que pode ajudar a minimizar o clichê.Você pode introduzir uma família de tipos para mapear seus novos tipos para a representação subjacente:
e, em seguida, introduza variantes newtype dos tipos
IOUArray
eSTUArray
array:e use ESTES para obter
MArray
instâncias apropriadas para seus novos tipos:Agora, você deve poder usar
NTIOUArray
eNTSTUArray
no lugar do habitualIOUArray
eSTUArray
para os tipos de elemento interno e de tipo newtype:Qualquer
IArray
instância pode ser gerada automaticamente usandovia
derivação (que funciona porque o tipo de elemento é o último argumento daIArray
restrição):ou você pode usar a mesma técnica acima com um
NTIArray
novo tipo.Algum código de exemplo:
fonte
Okay, you're kind of stuck here because some design choices in the array package have made it difficult.
? Não entendo o que há de errado na derivação e o que significa o seguinte erro. `Não é possível criar uma instância derivada de 'MArray IOUArray MyInt IO' (mesmo com astuto GeneralizedNewtypeDeriving): não é possível reduzir o tipo de representação o suficiente Na instância independente independente para 'MArray IOUArray MyInt IO' '