对不起,这是同一系列中的另一个主题。对于与列表同构的事物,我有一个类型类:
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 ‘*’
当然,我并不期望这样做,但也就是说我不知道如何写它。
答案 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