Разбор int или float с FParsec

Я пытаюсь проанализировать файл, используя FParsec, который состоит из значений с плавающей запятой или int. Я сталкиваюсь с двумя проблемами, для которых я не могу найти хорошее решение.

1

И то и другоеpint32 а такжеpfloat успешно проанализирует одну и ту же строку, но даст разные ответы, напримерpint32 вернусь3 при разборе строки"3.0" а такжеpfloat вернусь3.0 при разборе той же строки. Можно ли попробовать разобрать значение с плавающей запятой, используяpint32 и потерпеть неудачу, если строка"3.0"?

Другими словами, есть ли способ заставить следующий код работать:

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

Этот фрагмент кода правильно поместит все значения с плавающей запятой вfloatvalues список, а потомуpfloat возвращается"3.0" при разборе строки"3"все целочисленные значения также будут помещены вfloatvalues список.

2

Приведенный выше пример кода кажется мне немного неуклюжим, поэтому я предполагаю, что должен быть лучший способ сделать это. Я подумал объединить их, используяchoiceОднако оба парсера должны возвращать один и тот же тип, чтобы это работало. Я думаю, что я мог бы сделать дискриминационный союз с одним параметром для float и один для int и преобразовать вывод изpint32 а такжеpfloat с использованием|>> оператор. Однако мне интересно, есть ли лучшее решение?

Ответы на вопрос(1)

Ваш ответ на вопрос