I am trying to parse a file using FParsec, which consists of float or int values. I ran into two problems for which I cannot find a good solution.
1
Both pint32 and pfloat will successfully parse the same string, but give different answers, for example pint32 will return 3 when parsing the string "3.0" and pfloat will return 3.0 when parsing the same string. Is it possible to try to parse a floating point value using pint32 , and will it fail if the string is "3.0" ?
In other words, is there a way to do the following code:
let parseFloatOrInt lines = let rec loop intvalues floatvalues lines = match lines with | [] -> floatvalues, intvalues | line::rest -> match run floatWs line with | Success (r, _, _) -> loop intvalues (r::floatvalues) rest | Failure _ -> match run intWs line with | Success (r, _, _) -> loop (r::intvalues) floatvalues rest | Failure _ -> loop intvalues floatvalues rest loop [] [] lines
This piece of code will correctly place all floating point values ββin the floatvalues list, but since pfloat returns "3.0" when parsing the string "3" , all integer values ββwill also be placed in the floatvalues list.
2
The above code example seems a bit awkward to me, so I guess there should be a better way to do this. I considered combining them with choice , however, both parsers must return the same type to work. I think I could make a discriminated union with one parameter for float and one for int and convert the output from pint32 and pfloat using the |>> operator. However, I wonder if there is a better solution?
Chepe source share