Tengo un viejo código Haskell que incluye casos de prueba QuickCheck. Las versiones más recientes de QuickCheck (Acabo de actualizar a 2.4.0.1) incluyen instancias de clase de tipo para Arbitrary Word8
y otros. Estos no existían en las versiones 2.0.x anteriores de Test.QuickCheck.Arbitrary.¿Cómo se anulan las instancias de clase de tipo Haskell proporcionadas por el código del paquete?
Si bien es útil en el sentido general, la Arbitrary Word8
generador de paquetes proporcionada no es el que yo quiero usar para mi banco de pruebas:
instance Arbitrary Word8 where
arbitrary = frequency [(2, oneof [return ctrlFrameDelim, return ctrlEscape, return ctrlXon, return ctrlXoff]),
(8, choose (0, 255))]
El código anterior produce un error en la declaración instancia duplicada en tiempo de compilación . Puedo sacar este código y seguir con el generador predeterminado, pero me gustaría saber la forma correcta de resolverlo.
Una posible solución que he considerado (pero no probado) es el aliasing Word8
usando newtype
. Eso causaría muchos cambios en toda la fuente, así que espero que haya una manera más limpia.
EDIT: Como se mencionó en los comentarios a continuación, la respuesta aceptada era muy limpia y fácil de implementar:
newtype EncodedByte = EncodedByte Word8
instance Arbitrary EncodedByte where
arbitrary = liftM EncodedByte $ frequency [(2, elements [ctrlFrameDelim, ctrlEscape, ctrlXon, ctrlXoff]),
(8, choose (0, 255))]
Muchas personas parecen considerar esta solución fea. Pero si permite que un "tipo de datos" signifique más que la representación de valores, me parece totalmente razonable. Por ejemplo, no solo está hablando de 'Word8's, sino de' ControlCode's o algo así. – luqui
que funcionó muy bien. Como resultado, el alias no requirió ningún cambio en cascada. Solo necesitaba proporcionar una declaración adicional "instancia Random SomeNewType" para "elegir". –