我正在尝试为替代版本编号方法定义 Eq 运算符。
type VersionCompound = Maybe Int -- x, 0, 1, 2, ...
type VersionNumber = [VersionCompound] -- x.x, x.0, x.1, x.2, ... , 1.0, 1.1, 1.2, ... 1.x.x, 2.x.x, 3.x.x, ...
instance Eq VersionNumber where
[] == [] = True
(x:[]) == (y:[]) = x == y
(Nothing:xs) == ys = (xs == ys)
xs == (Nothing:ys) = (xs == ys)
预计它会True
在以下情况下返回:x.x.x == x
、1.x.x == x.1.x.x
、x.1 == 1
等。但它会返回错误:
VersionNumber.hs:58:34:
Overlapping instances for Eq [VersionCompound]
arising from a use of ‘==’
Matching instances:
instance Eq a => Eq [a] -- Defined in ‘GHC.Classes’
instance Eq VersionNumber -- Defined at VersionNumber.hs:55:10
In the expression: (xs == ys)
In an equation for ‘==’: (Nothing : xs) == ys = (xs == ys)
In the instance declaration for ‘Eq VersionNumber’
任何想法如何解决它?
编辑:我通过列表上的模式匹配解决这个问题的方法被证明是不完整的。我想忽略给定版本左侧的任意x
's(或s)列表。Nothing
因此,例如,x.x.x.x.x
将等于x.x.x
和 to x
。同样,x.x.x.1
将等于x.x.1
和1
。如果x
中间有一个,它就不会被扔掉。因此,对于这种情况,x.x.1.x.0
将等于x.1.x.0
和1.x.0
。又一个例子:x.1.x.x.0.x
等于1.x.x.0.x
和x.1.x.0.x
等于1.x.0.x
(您只需删除x
左侧的 's)。
修复错误后我一直在努力解决的Overlapping instances for Eq [VersionCompound]
是如何获得x.x.x == x
->True
模式匹配。但是,正如@WillemVanOnsem 出色地指出的那样,它不应该通过模式匹配来实现,而应该通过函数组合来实现。
PS。我个人鼓励您投票赞成@WillemVanOnsem 的答案,因为他的解决方案非常优雅,需要一些努力才能提出并代表了 Haskell 力量的本质。