我一直在参加一个编程比赛,其中一个问题的输入数据包括一个十进制格式的小数:0.75
就是一个例子。
将其解析为Double
是微不足道的(我可以使用read
),但精度的损失是痛苦的。需要非常小心Double
比较(我没有),这似乎是多余的,因为在Haskell中有Rational
数据类型。
当试图使用它时,我发现read
和Rational
必须提供以下格式的字符串: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