Deconstrucción polimórfica de Haskell

I'm started working with Juicy Pixels library and have some problem with deconstructing.

There are type:

data DynamicImage =
    ImageY8   (Image Pixel8)
    | ImageYA8  (Image PixelYA8)
    | ImageRGB8 (Image PixelRGB8)
    | ImageRGBA8 (Image PixelRGBA8) 
    | ImageYCbCr8 (Image PixelYCbCr8)

where Pixel* is instances of Pixel a clase

There are some functions that work with Imagen a type and i wish to extract Imagen a de Imagen dinámica, but i can't

When i try to do something like

img :: (Pixel a) => DynamicImage -> Image a
img (ImageY8 i) = i
img (ImageYA8 i) = i  
img (ImageRGB8 i) = i
img (ImageRGBA8 i) = i  
img (ImageYCbCr8 i) = i

interpreter thwors an errors like

Couldn't match type `PixelYCbCr8' with `GHC.Word.Word8'
Expected type: Image b
  Actual type: Image Pixel8
In the expression: i
In an equation for `img': img (ImageY8 i) = i

Is there any other way to extract Imagen a ¿datos?

preguntado el 28 de agosto de 12 a las 11:08

1 Respuestas

Your approach does not work because the type signature of img promises to provide an Image for cada a, not just one particular chosen by img misma.

One possibility is to change the type signature to also take the function that will handle the polymorphic image, and use RankNTypes para permitir que:

withImg :: DynamicImage -> (forall a. Pixel a => Image a -> b) -> b
withImg (ImageY8 i) f = f i
withImg (ImageYA8 i) f = f i  
withImg (ImageRGB8 i) f = f i
withImg (ImageRGBA8 i) f = f i  
withImg (ImageYCbCr8 i) f = f i

This ensures that the function passed to withImg aceptará cualquier Image as an argument, without any further information about it.

Respondido 28 ago 12, 11:08

This is actually a transformation of exists a. Pixel a => DynamicImage -> Image a into continuation-passing style. - Llama de Ptharien

True, but that is not a valid Haskell type. Is there a non-continuation-passing-style variant that works in Haskell? - Joachim Breitner

data SomeImage = forall a. Pixel a => SomeImage (Image a) (que necesita -XExistentialQuantification). - Vito

Also, it's transformation of (A) DynamicImage -> (exists a. Pixel a => Image a) - note the position of exists. (B) exists a. Pixel a => DynamicImage -> Image a is a bit stronger in the sense that you can go from b a a, pero no al revés. - Vito

Ok, you can introduce a new type. But to actually use the functions mentioned in the original question, which take a "Pixel a" and not a SomeImage, you’d again have to do a CPS transformation. - Joachim Breitner

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.