Reputation: 53077
Sorry, this is yet another topic in the same serie. I have a typeclass for things that are isomorphic to lists:
class ListIsomorphic l where
type Elem l a :: Constraint
type Elem l a = ()
toList :: l a -> [a]
fromList :: [a] -> l a
There are two cases for which I'm not managing to create an instance; singly-typed tuples and types that pack multiple elements in a single value.
type Tuple2 a = (a,a)
newtype Pixel a = Pixel a
On this case, Pixel usually holds a Word32
with 4 elements that are extracted with bitwise operations:
red (Pixel pixel) = pixel .&. 0x000000FF
green (Pixel pixel) = shiftR (pixel .&. 0x0000FF00) 8
blue (Pixel pixel) = shiftR (pixel .&. 0x00FF0000) 16
alpha (Pixel pixel) = shiftR (pixel .&. 0xFF000000) 24
While both cases aren't isomorphic to lists (they are fixed length), having an instance would be useful, yet I'm not sure how to justify this to the type system. Writing an instance for tuples:
type Tuple2 a = (a,a)
instance ListIsomorphic Tuple2 where
fromList [a,b] = (a,b)
toList (a,b) = [a,b]
I get:
Type synonym ‘Tuple2’ should have 1 argument, but has been given none
Writing an instance for Pixel:
instance ListIsomorphic Pixel where
type Elem Pixel_ a = Word32
fromList [r,g,b,a] = rgba r g b a
toList pixel = [red pixel, green pixel, blue pixel, alpha pixel]
I get:
Expected a constraint, but ‘Word32’ has kind ‘*’
Of course, I didn't expect that to work, but that is to say I have no idea how to write it.
Upvotes: 1
Views: 54
Reputation: 120751
The constraint family
type Elem l a :: Constraint
type Elem l a = ()
allows you to restrict the types that may be contained in those containers. In the case of Tuple2
, or lists themselves, this isn't necessary at all, because these can contain any type of element.
In the case e.g. of Storable
vectors, you need primitive types that can actually be stored in a C array.
In the case of Pixel
, you can only store one single type, namely Word32
. That means you need an equational constraint:
instance ListIsomorphic Pixel where
type Elem Pixel a = a~Word32
Upvotes: 3