如何在Haskell中比较自定义数据类型

3
我有一个自定义数据类型需要进行比较。
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
< p >来自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))

背景

  • 这是来自宾夕法尼亚大学工程学院课程的练习题。
  • 使用的堆栈版本为1.9.3.1。

1
附注:Stack 只是一个构建工具,因此它的版本并不能告诉我们你的代码实际使用了什么。在以后的问题中,你可以告诉我们 Stack 正在使用哪个解析器来构建你的代码,这样我们就可以找到相应的 GHC 和 Stackage 库的版本。解析器在你使用的 stack.yaml 文件中指定(如果你不确定它在哪里,可以使用 stack path --config-location 命令查看)。 - duplode
2个回答

7
错误
No instance for (Eq Tile) arising from a use of ‘==’
说你使用两个Tile并用(==),但编译器没有找到Eq Tile的实例,在你定义Tile(==)函数时。你可以将其作为Eq类型类的一个实例:
data Tile = Wall | Ground | Storage | Box | Blank <b>deriving Eq</b>

如果您自动推导 Eq,那么 Haskell 将考虑两个 Tile 对象相等,只要它们的数据构造函数(WallGround 等)相同,并且它们的所有参数都相同。由于您的 Tile 数据类型的数据构造函数没有参数,这意味着 Wall 等于 WallGround 等于 Ground 等等。
然而,在您的函数 tileToInteger 中,您完全不需要使用 (==),而可以使用模式匹配 模式匹配 [Haskell-wiki],如下所示:
tileToInteger :: Tile -> Integer
tileToInteger <b>Blank</b> = 1
tileToInteger <b>Wall</b> = 1
tileToInteger <b>_</b> = 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被认为是以不同的方式等价时才手动实现Eq。

3
你可以自动推导比较的方法:

您可以自动派生比较方法:

data Tile = Wall | Ground | Storage | Box | Blank deriving (Eq)

然后你可以使用==/=来比较Tile的相等和不相等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接