Tengo una docena de nuevos tipos como este:
newtype MyBool = MyBool Bool
newtype MyInt = MyInt Int
Quiero reutilizar instancias existentes:
instance MArray IOUArray Int IO where ...
instance MArray (STUArray s) Int (ST s) where ...
Implementar estas instancias y tener todo el código repetitivo es lo último que quiero.
Encontré algo que se parece mucho a lo que estoy tratando de lograr:
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
deriving instance MArray IOUArray MyInt IO
deriving instance MArray (STUArray s) MyInt (ST s)
Sin embargo, falla con:
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’
¿Cómo hacer que esto funcione?
Si no es posible, ¿cuál es la forma menos dolorosa de obtener esas instancias?
type role IOUArray nominal nominal
por lo que no podemos coaccionar de array-of-int a array-of-myint. (Me pregunto por qué tenemos tales roles.)Storable
instancia diferente para sus representaciones sin caja (por ejemplo, usando un número más corto que unInt
entero para almacenar sin cajanewtype Age = Age Int
).Respuestas:
De la documentación :
Dado que el último parámetro de clase en su caso no es
Int
/MyInt
, sino más bienIO
/ , desafortunadamenteST s
no tiene suerteGeneralizedNewtypeDeriving
.fuente
De acuerdo, estás un poco atrapado aquí porque algunas opciones de diseño en el
array
paquete lo han dificultado, pero aquí hay un enfoque que puede ayudar a minimizar las repeticiones.Puede introducir una familia de tipos para asignar sus nuevos tipos a su representación subyacente:
y luego introducir newtype variantes de la
IOUArray
ySTUArray
de la matriz tipos:y use ESTOS para obtener
MArray
instancias apropiadas para sus nuevos tipos:Ahora, debería poder usar
NTIOUArray
yNTSTUArray
reemplazar el habitualIOUArray
ySTUArray
para los tipos de elementos integrados y de tipo newtype:Cualquier
IArray
instancia se puede generar automáticamente mediantevia
derivación (que funciona porque el tipo de elemento es el último argumento de laIArray
restricción):o podría usar la misma técnica anterior con un
NTIArray
nuevo tipo.Algún código de muestra:
fuente
Okay, you're kind of stuck here because some design choices in the array package have made it difficult.
? No entiendo qué falla con la derivación y qué significa el siguiente error. `No se puede hacer una instancia derivada de 'MArray IOUArray MyInt IO' (incluso con astucia GeneralizedNewtypeDeriving): no se puede reducir el tipo de representación lo suficiente en la instancia de derivación independiente para 'MArray IOUArray MyInt IO' '