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 nominalpor lo que no podemos coaccionar de array-of-int a array-of-myint. (Me pregunto por qué tenemos tales roles.)Storableinstancia diferente para sus representaciones sin caja (por ejemplo, usando un número más corto que unIntentero 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 sno tiene suerteGeneralizedNewtypeDeriving.fuente
De acuerdo, estás un poco atrapado aquí porque algunas opciones de diseño en el
arraypaquete 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
IOUArrayySTUArrayde la matriz tipos:y use ESTOS para obtener
MArrayinstancias apropiadas para sus nuevos tipos:Ahora, debería poder usar
NTIOUArrayyNTSTUArrayreemplazar el habitualIOUArrayySTUArraypara los tipos de elementos integrados y de tipo newtype:Cualquier
IArrayinstancia se puede generar automáticamente medianteviaderivación (que funciona porque el tipo de elemento es el último argumento de laIArrayrestricción):o podría usar la misma técnica anterior con un
NTIArraynuevo 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' '