为新类型创建实例

时间:2014-01-19 21:10:24

标签: haskell types point

我在Haskell中创建了一个代表像素的类型,如下所示:

data Pixel = Pixel Float Float Int deriving (Eq, Show)

这里,第一个浮点数对应于x轴上像素的位置,第二个浮点数表示y轴上的位置(所以基本上我在“屏幕”上有2个坐标)和Int这是它的灰色值。

我想为Eq创建Pixel的{​​{1}}实例,如果它们的灰度值相同,则像素彼此相等,无论其位置如何。

到目前为止,我已经这样做了:

instance Eq Pixel where

但现在我不知道如何检查它们是否相同,我的意思是,我怎么说我有2个不同的像素,我想比较它们的Int?我不能做像

这样的事情
grey1 == grey2 = True

'因为我不知道grey1grey2来自哪里。

我该怎么做?

同样在为Show做一个实例时,我如何引用Floats和Int?

3 个答案:

答案 0 :(得分:4)

这样的东西?

data Pixel = Pixel Float Float Int

instance Eq Pixel where 
    Pixel _ _ g1 == Pixel _ _ g2 = g1 == g2

instance Show Pixel where
    show ( Pixel  x y g ) = "Pixel " ++ show g ++ " at ("  ++ show x ++ "," ++ show y ++ ")"

答案 1 :(得分:4)

改为使用记录语法

data Pixel = Pixel {   xPos :: Float
                     , yPos :: Float
                     , value :: Int  
                     }

xPosyPosvalue的类型Pixel -> FloatPixel -> Int会使某些操作比模式匹配更容易。

但是,要使它成为适当类的实例,它就足够了(例子):

instance Show Pixel where
    show (Pixel x y g) = "[" ++ show x ++ ", " ++ show y ++ "(" ++ show g ++ ")]"

instance Eq Pixel where
    (Pixel _ _ valA) == (Pixel _ _ valB) = valA == valB

与实际使用的记录语法相同:

instance Show Pixel where
    show pixel = "[" ++ show (xPos pixel) ++ ", " ++ show (yPos pixel) ++ "(" ++ show (value pixel) ++ ")]"

instance Eq Pixel where
    a == b = (value a) == (value b)

您可能需要修改示例;它们仅用于说明目的。

答案 2 :(得分:3)

您要做的是Pixel的构造函数上的模式匹配。这就是你编写“拉开”类型的函数的方法。使用case语句

进行模式匹配
case pixel of
  Pixel x y grey -> ...

其中,作为语法糖,也可直接在定义中使用

getX :: Pixel -> Double
getX (Pixel x y grey) = x

-- same as

getX :: Pixel -> Double
getX px = case px of
  Pixel x y grey -> x

所以我们这样做两次来创建一个相等函数

instance Eq Pixel where
  Pixel x1 y1 grey1 == Pixel x2 y2 grey2 = grey1 == grey2