如何在Haskell中将十进制小数解析为Rational



我一直在参加一个编程比赛,其中一个问题的输入数据包括一个十进制格式的小数:0.75就是一个例子。

将其解析为Double是微不足道的(我可以使用read),但精度的损失是痛苦的。需要非常小心Double比较(我没有),这似乎是多余的,因为在Haskell中有Rational数据类型。

当试图使用它时,我发现readRational必须提供以下格式的字符串:numerator % denominator,显然,我没有。

所以,问题是:

将分数的十进制表示形式解析为Rational的最简单方法是什么?

外部依赖的数量也应该考虑在内,因为我不能在在线判断中安装额外的库。

您想要的功能是Numeric.readFloat:

Numeric Data.Ratio> fst . head $ readFloat "0.75" :: Rational
3 % 4

下面的(GHCi会话)如何:

> :m + Data.Ratio
> approxRational (read "0.1" :: Double) 0.01
1 % 10

当然你得适当地选择

也许你自己实现它会在比赛中得到额外的分数:

import Data.Ratio ( (%) )
readRational :: String -> Rational
readRational input = read intPart % 1 + read fracPart % (10 ^ length fracPart)
  where (intPart, fromDot) = span (/='.') input
        fracPart           = if null fromDot then "0" else tail fromDot

最新更新