[英]How to compare a custom data type in haskell
我有一个自定义数据类型,我想比较。
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))
背景
错误
No instance for (Eq Tile) arising from a use of '=='
说你使用(==)
两个Tile
,但编译器没有找到Eq Tile
的实例,你为Tile
s定义了(==)
函数。
你可以使它成为Eq
类型类的一个实例:
data Tile = Wall | Ground | Storage | Box | Blank deriving Eq
如果你自动派生Eq
,那么Haskell认为两个Tile
对象相等,因为数据构造函数( Wall
, Ground
,...)是相同的,并且它们的所有参数都是相同的。 由于Tile
数据类型的数据构造函数没有参数,因此这仅仅意味着Wall
等于Wall
, Ground
等于Ground
等。
在你的函数tileToInteger
中,你根本不需要使用(==)
,你可以使用模式匹配 [Haskell-wiki] ,如:
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
然而,上述内容等同于deriving Eq
将要执行的操作,因此,如果两个Tile
s以不同的方式被视为等效,则通常仅手动实现Eq
。
您可以自动派生比较方法:
data Tile = Wall | Ground | Storage | Box | Blank deriving (Eq)
然后你可以使用==
和/=
比较Tile
s的相等性和不等式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.