提问人:newcodder 提问时间:11/15/2022 最后编辑:M. Justinnewcodder 更新时间:11/7/2023 访问量:130
为什么我不能有一个“相等”的有理函数
Why cant i have a "equal" rational function
问:
我对 Haskell 很陌生,对 Eq 有疑问。
data Rat = Rat Integer Integer
normaliseRat :: Rat -> Rat
normaliseRat (Rat x y)
|x < 0 && y < 0 = Rat (-x) (-y)
|otherwise = Rat (x `div`(gcd x y)) (y `div` (gcd x y))
所以我有一个func normaliseRat。我需要的是 Eq 和 Ord 的实例。当然,老鼠 2 4 == 老鼠 1 2 应该是有效的。
感谢您的帮助
答:
2赞
chepner
11/15/2022
#1
Haskell 不支持函数重载。但不是函数;它被声明为 TypeClass 方法,因此必须在声明中定义该方法的任何特定于类型的实现,如下所示:(==)
instance
instance Eq Rat where
(Rat x y) == (Rat n m) = x * m == y * n
(x/y == n/m
等价于,在交叉乘法后,为 ;乘法效率更高,并且没有除法会引入的准确性问题。x * m == y * n
这同样适用于 ,除非您可以选择实现 或 。(给定其中任何一个,其他比较方法的默认定义将起作用。Ord
(<=)
compare
instance Ord Rat where
-- I leave fixing this to accommodate negative numbers
-- correctly as an exercise.
(Rat x y) <= (Rat n m) = (x * m) <= (y * n)
作为类型类方法,实际上是一整套函数,按其使用的类型进行索引。声明的目的不是重新定义方法,而是向该系列添加一个新函数。(==)
instance
如果启用扩展,则可以查看从类型到函数的映射。TypeApplications
(==)
> :t (==)
(==) :: Eq a => a -> a -> Bool
> :t (==) @Int
(==) @Int :: Int -> Int -> Bool
如果没有类型应用程序,Haskell 的类型检查器会自动确定要使用哪个函数:
> (==) 'c' 'd'
False
> (==) 3 5
False
但你可以明确:
> (==) @Char 'c 'd'
False
> (==) @Char 3 5
<interactive>:9:12: error:
• No instance for (Num Char) arising from the literal ‘3’
• In the second argument of ‘(==)’, namely ‘3’
In the expression: (==) @Char 3 5
In an equation for ‘it’: it = (==) @Char 3 5
评论
0赞
newcodder
11/15/2022
当我写你在那里写的东西时,我得到了一个错误。x * m == y *n 我得到“==”一个错误,说这是一个模棱两可的情况
0赞
newcodder
11/15/2022
啊,好吧。因此,当我编写代码时,它应该看起来像这样: (==) (Rat x y) (Rat m n) = xm == yn ??
1赞
chepner
11/15/2022
你不应该需要。我无法重现您声称看到的错误。
1赞
chepner
11/15/2022
您确定您完全按照所示键入了它吗?确切的错误消息是什么?
1赞
Daniel Wagner
11/16/2022
您的定义需要谨慎。如果有理数没有被归一化,也许其中一个分母是负数(而不是另一个分母)——那么 必须变成 !Ord
<=
>=
评论
instance Eq Rat where (Rat x1 y1) == (Rat x2 y2) = ...
instance Ord Rat where compare (Rat x1 y1) (Rat x2 y2) = ...
normalizeRat (Rat (-4) (-2))
似乎它可能给出了错误的答案,具有明显的规格。normalizeRat