简体   繁体   中英

Creating an instance for a new type

I created a type in Haskell which represents a pixel, like so:

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

Here, the first float corresponds to the pixel's location on the x axis, the second float represents the location in the y axis (so basically I have 2 coordinates for it on the "screen") and the Int it's its grey value.

I wanted to create and instance of Eq for Pixel in which a pixel is equal to each other if their grey value is the same, regardless of its position.

So far I've done this:

instance Eq Pixel where

but now I don't know how to check if they're the same, I mean, how do I say I have 2 diferent Pixels here and I want to compare their Int ? I can't do something like

grey1 == grey2 = True

'cause I don't know where grey1 and grey2 came from.

How can I do it?

Also when doing a instance for Show , how do I refer to the Floats and the Int?

Something like this?

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 ++ ")"

Use record syntax instead!

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

xPos , yPos and value have types Pixel -> Float and Pixel -> Int which will make some operations easier than pattern matching.

However, to make it an instance of appropriate classes it's sufficient (examples):

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

The same with record syntax actually used:

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)

You might need to modify the examples; they are just for illustrative purposes.

What you'd like to do is pattern match on the constructor of Pixel . This is how you write functions which "pull apart" a type. Pattern matching happens using the case statement

case pixel of
  Pixel x y grey -> ...

Which, as syntax sugar, is also available directly in definitions

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

-- same as

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

So we do this twice to create an equality function

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM