Haskell自定义Rat类型如何实现Eq与Ord实例?
实现Rat类型的Eq和Ord实例
首先可以优化你的normaliseRat函数,确保归一化后的分母始终为正,让后续比较逻辑更简洁准确:
normaliseRat :: Rat -> Rat normaliseRat (Rat x y) = let g = gcd x y -- 将符号统一移到分子,保证分母为正 sign = if y < 0 then -1 else 1 simplifiedX = sign * (x `div` g) simplifiedY = sign * (y `div` g) in Rat simplifiedX simplifiedY
实现Eq实例
核心逻辑是先把两个有理数归一化,再比较分子和分母是否完全一致:
instance Eq Rat where r1 == r2 = let (Rat x1 y1) = normaliseRat r1 (Rat x2 y2) = normaliseRat r2 in x1 == x2 && y1 == y2
这样Rat 2 4 == Rat 1 2会返回True——两者归一化后都是Rat 1 2。
实现Ord实例
利用归一化后分母为正的特性,用交叉相乘的方式比较大小(避免浮点数转换带来的精度损失):
instance Ord Rat where compare r1 r2 = let (Rat x1 y1) = normaliseRat r1 (Rat x2 y2) = normaliseRat r2 -- 由于y1、y2都是正数,x1/y1 和 x2/y2的大小等价于x1*y2 和 x2*y1的大小 in compare (x1 * y2) (x2 * y1)
这样就能正确处理有理数的大小比较,比如Rat 1 2 < Rat 3 4会返回True,Rat (-1) 2 > Rat (-1) 1也能准确判定。
内容的提问来源于stack exchange,提问作者newcodder
相关产品推荐
相关产品推荐

