How to parse a decimal fraction into Rational in Haskell?

我们两清 提交于 2019-12-10 02:42:02

问题


I've been participating in a programming contest and one of the problems' input data included a fractional number in a decimal format: 0.75 is one example.

Parsing that into Double is trivial (I can use read for that), but the loss of precision is painful. One needs to be very careful with Double comparisons (I wasn't), which seems redundant since one has Rational data type in Haskell.

When trying to use that, I've discovered that to read a Rational one has to provide a string in the following format: numerator % denominator, which I, obviously, do not have.

So, the question is:

What is the easiest way to parse a decimal representation of a fraction into Rational?

The number of external dependencies should be taken into consideration too, since I can't install additional libraries into the online judge.


回答1:


The function you want is Numeric.readFloat:

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



回答2:


How about the following (GHCi session):

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

Of course you have to pick your epsilon appropriately.




回答3:


Perhaps you'd get extra points in the contest for implementing it yourself:

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


来源:https://stackoverflow.com/questions/7056791/how-to-parse-a-decimal-fraction-into-rational-in-haskell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!