I have a custom data type which I would like to compare.
data Tile = Wall | Ground | Storage | Box | Blank
I would like to do instance-of-tile == Box
I've tried using == like so
tileToInteger :: Tile -> Integer
tileToInteger tile
| tile == Blank || tile == Wall = 1
| otherwise = 2
I've also tried
tileToInteger :: Eq => Tile -> Integer
The error message from stack build is
No instance for (Eq Tile) arising from a use of ‘==’
• In the first argument of ‘(||)’, namely ‘tile == Blank’
In the expression: tile == Blank || tile == Wall
In a stmt of a pattern guard for an equation for ‘tileToInteger’: tile == Blank || tile == Wall
Here's the full sample code
data Tile = Wall | Ground | Storage | Box | Blank
getTileAtXY :: Integer -> Integer -> Tile
getTileAtXY x y
| x == 0 && y == 0 = Box
| otherwise = Ground
tileToInteger :: Tile -> Integer
tileToInteger tile
| tile == Blank || tile == Wall = 1
| otherwise = 2
main :: IO ()
main = print (tileToInteger (getTileAtXY 1 0))
Background
The error
No instance for (Eq Tile) arising from a use of ‘==’
Says that you use (==) with two Tiles, but that the compiler did not found an instance of Eq Tile where you defined the (==) function for Tiles.
You can make it an instance of the Eq typeclass:
data Tile = Wall | Ground | Storage | Box | Blank deriving Eq
If you automatically derive Eq, then Haskell considers two objects of Tile equal given the data constructors (Wall, Ground, ...) are the same, and all their arguments are the same. Since the data constructors of your Tile data type have no arguments, this thus simply means that Wall is equal to Wall, Ground is equal to Ground, etc.
In your function tileToInteger however, you do not need to use (==) at all, you can use pattern matching [Haskell-wiki], like:
tileToInteger :: Tile -> Integer
tileToInteger Blank = 1
tileToInteger Wall = 1
tileToInteger _ = 2
You can implement the (==) function for Tiles with pattern matching, like:
instance Eq Tile where
Wall == Wall = True
Ground == Ground = True
Storage == Storage = True
Box == Box = True
Blank == Blank = True
_ == _ = False
The above is however equivalent to what deriving Eq will do, so usually one only implements Eq manually if two Tiles are considered equivalent in a different way.
You can derive the methods for comparison automatically:
data Tile = Wall | Ground | Storage | Box | Blank deriving (Eq)
And then you can use == and /= to compare Tiles for equality and inequality.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With