You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为自定义Rat类型创建Eq与Ord类型实例

为自定义Rat有理数类型实现Eq和Ord实例

你已经完成了有理数类型的规范化和显示逻辑,现在要让Rat成为Eq和Ord的实例,确保等价有理数(比如Rat 2 4和Rat 1 2)能正确判断相等,同时支持大小比较。

完整实现代码

gcd' :: Integer -> Integer -> Integer
gcd' a b = if b == 0 then a else gcd' b (a `mod` b)

data Rat = Rat Integer Integer

normaliseRat :: Rat -> Rat
normaliseRat (Rat num den) =
    let commonDivisor = gcd' (abs num) (abs den)
        num' = num `div` commonDivisor
        den' = den `div` commonDivisor
    in Rat (if den < 0 then (-num') else num') (abs den')

createRat :: Integer -> Integer -> Rat
createRat num den = normaliseRat (Rat num den)

-- Show实例:格式化显示有理数
instance Show Rat where
    show (Rat num den) = show num ++ "/" ++ show den

-- Eq实例:判断两个有理数是否相等
instance Eq Rat where
    r1 == r2 =
        let (Rat n1 d1) = normaliseRat r1
            (Rat n2 d2) = normaliseRat r2
        in n1 == n2 && d1 == d2

-- Ord实例:实现有理数的大小比较
instance Ord Rat where
    compare r1 r2 =
        let (Rat n1 d1) = normaliseRat r1
            (Rat n2 d2) = normaliseRat r2
            -- 交叉相乘比较,避免浮点数精度问题(分母均为正,不影响符号)
            left = n1 * d2
            right = n2 * d1
        in compare left right

关键说明

  • Eq实例:不管输入的Rat是否经过规范化,先通过normaliseRat统一转成标准形式,再直接比较分子和分母是否完全相等,这样就能保证Rat 2 4 == Rat 1 2返回True。
  • Ord实例:利用有理数交叉相乘的性质(对于正数分母的有理数a/b和c/d,a/b > c/d等价于a*d > c*b),避免使用浮点数转换带来的精度损失,同时确保比较逻辑的准确性。

测试示例

在GHCi中测试:

ghci> createRat 2 4 == createRat 1 2
True
ghci> createRat 3 4 > createRat 1 2
True
ghci> createRat (-1) 2 < createRat 1 3
True
ghci> max (createRat 5 6) (createRat 3 4)
5/6

内容的提问来源于stack exchange,提问作者Anik kanti sikder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:43:25