繁体   English   中英

如何比较haskell中的自定义数据类型

[英]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对象相等,因为数据构造函数( WallGround ,...)是相同的,并且它们的所有参数都是相同的。 由于Tile数据类型的数据构造函数没有参数,因此这仅仅意味着Wall等于WallGround等于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.

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