我有一个自定义数据类型,我想比较一下。
data Tile = Wall | Ground | Storage | Box | Blank
Run Code Online (Sandbox Code Playgroud)
我想要做 instance-of-tile == Box
我试过==像这样
tileToInteger :: Tile -> Integer
tileToInteger tile
| tile == Blank || tile == Wall = 1
| otherwise = 2
Run Code Online (Sandbox Code Playgroud)
我也尝试过
tileToInteger :: Eq => Tile -> Integer
Run Code Online (Sandbox Code Playgroud)
来自的错误消息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
Run Code Online (Sandbox Code Playgroud)
这是完整的示例代码
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))
Run Code Online (Sandbox Code Playgroud)
背景
错误
Run Code Online (Sandbox Code Playgroud)No instance for (Eq Tile) arising from a use of ‘==’
说您(==)与两个Tiles 一起使用,但是编译器未找到Eq Tile您(==)为Tiles 定义函数的实例。
您可以使其成为Eqtypeclass的实例:
data Tile = Wall | Ground | Storage | Box | Blank deriving EqRun Code Online (Sandbox Code Playgroud)
如果您自动获得Eq,然后哈斯克尔考虑的两个对象Tile相等给出的数据构造(Wall,Ground,...)是相同的,并且其所有参数都是相同的。由于您Tile数据类型的数据构造函数没有参数,因此这仅意味着Wall等于Wall,Ground等于Ground等。
tileToInteger但是,在您的函数中,您根本不需要使用(==),可以使用模式匹配 [Haskell-wiki],例如:
tileToInteger :: Tile -> Integer
tileToInteger Blank = 1
tileToInteger Wall = 1
tileToInteger _ = 2Run Code Online (Sandbox Code Playgroud)
您可以使用模式匹配(==)为实现的功能Tile,例如:
instance Eq Tile where
Wall == Wall = True
Ground == Ground = True
Storage == Storage = True
Box == Box = True
Blank == Blank = True
_ == _ = FalseRun Code Online (Sandbox Code Playgroud)
然而,以上内容等同于deriving Eq将要执行的操作,因此通常,Eq如果Tile以不同的方式将两个s视为等效,则通常只能手动执行。