我有一个要比较的自定义数据类型。
data Tile = Wall | Ground | Storage | Box | Blank
我想做instance-of-tile == Box
我尝试像这样使用==
tileToInteger :: Tile -> Integer
tileToInteger tile
| tile == Blank || tile == Wall = 1
| otherwise = 2
我也尝试过
tileToInteger :: Eq => Tile -> Integer
来自stack build
的错误消息是
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
这是完整的示例代码
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))
背景
答案 0 :(得分:7)
错误
No instance for (Eq Tile) arising from a use of ‘==’
假设您将(==)
与两个Tile
一起使用,但是编译器没有找到Eq Tile
的实例,而您在其中为{{1 }}。
您可以将其设为Eq
typeclass的实例:
(==)
如果您自动派生Tile
,则在数据构造函数(data Tile = Wall | Ground | Storage | Box | Blank deriving Eq
,Eq
等相同的情况下,Haskell认为Tile
的两个对象相等,他们所有的论点都是一样的。由于Wall
数据类型的数据构造函数没有参数,因此,这仅意味着Ground
等于Tile
,Wall
等于Wall
,等
但是在功能Ground
中,根本不需要使用Ground
,可以使用pattern matching [Haskell-wiki],例如:
tileToInteger
您可以为(==)
的{{1}}函数实施模式匹配,例如:
tileToInteger :: Tile -> Integer
tileToInteger Blank = 1
tileToInteger Wall = 1
tileToInteger _ = 2
然而,上述内容等同于(==)
的作用,因此通常只有在两个Tile
被认为是等效的情况下才手动实现instance Eq Tile where
Wall == Wall = True
Ground == Ground = True
Storage == Storage = True
Box == Box = True
Blank == Blank = True
_ == _ = False
。
答案 1 :(得分:3)
您可以推导自动进行比较的方法:
data Tile = Wall | Ground | Storage | Box | Blank deriving (Eq)
然后您可以使用==
和/=
比较Tile
的相等性和不平等性。