Haskell中未实现Eq实例的自定义类型如何进行等值比较
报错原因
Haskell 中自定义的数据类型默认不自带相等比较能力,要使用==运算符做相等判断,对应类型必须实现Eq类型类。当前定义的Planet枚举类型没有实现Eq,因此无法直接用==对比两个行星值。
解决方案
常用的解决方式有两种:
方案1:为Planet派生Eq实例
在Planet类型的声明末尾加上自动派生标记,编译器会自动生成对应Eq实例的相等判断逻辑,修改后的类型定义为:
data Planet = Mercury | Venus | Earth | Mars | Jupiter | Saturn | Uranus | Neptune deriving (Eq)
如果需要在控制台打印Planet值做调试,还可以顺带派生Show实例,也就是将派生行改为deriving (Eq, Show)。修改完成后,原有代码中基于==的守卫判断逻辑即可正常编译运行。
方案2:用模式匹配替代相等判断(Haskell惯用写法)
这种方式不需要为Planet实现Eq,是Haskell处理枚举类型的标准写法,运行效率也比运行时的相等判断更高。可以去掉之前的守卫判断,直接针对Planet的不同构造子编写独立的函数分支:
ageOn :: Planet -> Float -> Float ageOn Mercury seconds = seconds * mercury ageOn Venus seconds = seconds * venus ageOn Earth seconds = seconds * earth ageOn Mars seconds = seconds * mars ageOn Jupiter seconds = seconds * jupiter ageOn Saturn seconds = seconds * saturn ageOn Uranus seconds = seconds * uranus ageOn Neptune seconds = seconds * neptune
如果没有其他场景需要对比行星是否相等,这种方案比派生Eq更轻量化,代码逻辑也更直白。
内容的提问来源于stack exchange,提问作者timtam
相关产品推荐
相关产品推荐

