繁体   English   中英

如何在Haskell中实现Ratio?

[英]How is Ratio implemented in Haskell?

这是我一段时间以来一直困惑的事情,我不知道如何能够更多地了解它。 假设我有以下程序:

main :: IO ()
main = do
    x <- liftM read getLine
    y <- liftM read getLine
    print (x % y)

如果我用输入62运行它,它将打印3 % 1

在什么时候简化发生(即由gcd划分)? 它是在show实施的吗? 如果是这样,那么理性的基本表示仍然是6 % 2 如果没有,那么(%)是否进行简化? 我的印象是(%)是一个数据构造函数,那么数据构造函数除了“构造”之外还会做什么呢? 更重要的是,我将如何实际使用自己的数据构造函数进行类似的操作?

我感谢任何关于这个主题的帮助。

Ratio实际上是在GHC.Real实现的(显然在GHC上),定义为

data Ratio a = !a :% !a deriving (Eq)

刘海只是严格要求。 如您所见,函数%不是数据构造函数,但是:%是。 由于您不应该直接构造Ratio ,因此使用%函数,它调用reduce。

reduce ::  (Integral a) => a -> a -> Ratio a
{-# SPECIALISE reduce :: Integer -> Integer -> Rational #-}
reduce _ 0              =  ratioZeroDenominatorError
reduce x y              =  (x `quot` d) :% (y `quot` d)
                           where d = gcd x y
(%) :: (Integral a) => a -> a -> Ratio a
x % y =  reduce (x * signum y) (abs y)

该规则是,如果运营商是冒号命令: ,那么它是一个构造函数,否则它只是一个普通的操作人员。 实际上,这是Haskell标准的一部分,所有类型的运算符都必须以冒号作为它们的第一个字符。

您可以查看源代码以便自己查看:

instance  (Integral a)  => Num (Ratio a)  where
    (x:%y) + (x':%y')   =  reduce (x*y' + x'*y) (y*y')
    (x:%y) - (x':%y')   =  reduce (x*y' - x'*y) (y*y')
    (x:%y) * (x':%y')   =  reduce (x * x') (y * y')
    negate (x:%y)       =  (-x) :% y
    abs (x:%y)          =  abs x :% y
    signum (x:%_)       =  signum x :% 1
    fromInteger x       =  fromInteger x :% 1 

reduce ::  (Integral a) => a -> a -> Ratio a
reduce _ 0              =  ratioZeroDenominatorError
reduce x y              =  (x `quot` d) :% (y `quot` d)
                           where d = gcd x y

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM