如何为元组和打包类型创建ListIsomorphic实例?

时间:2015-08-22 00:21:47

标签: haskell typeclass

对不起,这是同一系列中的另一个主题。对于与列表同构的事物,我有一个类型类:

class ListIsomorphic l where
    type Elem l a :: Constraint
    type Elem l a = ()

    toList    :: l a -> [a]
    fromList  :: [a] -> l a

我有两种情况无法创建实例;单个类型的元组和在单个值中包含多个元素的类型。

type Tuple2 a   = (a,a)
newtype Pixel a = Pixel a

在这种情况下,Pixel通常包含一个Word32,其中包含4个按位操作提取的元素:

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

虽然这两种情况都不与列表同构(它们是固定长度),但是有一个实例会很有用,但我不确定如何证明这种类型系统是正确的。为元组编写实例:

type Tuple2 a = (a,a)
instance ListIsomorphic Tuple2 where
    fromList [a,b] = (a,b)
    toList   (a,b) = [a,b]

我明白了:

Type synonym ‘Tuple2’ should have 1 argument, but has been given none

为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]

我明白了:

Expected a constraint, but ‘Word32’ has kind ‘*’

当然,我并不期望这样做,但也就是说我不知道​​如何写它。

1 个答案:

答案 0 :(得分:3)

约束族

type Elem l a :: Constraint
type Elem l a = ()

允许您限制这些容器中可能包含的类型。对于Tuple2,或列出自己,这根本不是必需的,因为它们可以包含任何类型的元素。
在例如这种情况下在Storable向量中,您需要可以实际存储在C数组中的基本类型。
对于Pixel,您只能存储一种类型,即Word32。这意味着您需要等式约束

instance ListIsomorphic Pixel where
    type Elem Pixel a = a~Word32