Я пытаюсь разобрать что-то, что может быть списком элементов или может быть только одним элементом.Я хочу поместить результаты в DU (Thing
ниже).
Способ, которым я подхожу к этому, описан ниже, но он дает мне список вещей, даже если вlist.
let test p str =
match run p str with
| Success(result, _, _) -> printfn "Success: %A" result
| Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg
type Thing =
| OneThing of int
| LotsOfThings of Thing list
let str s = pstringCI s .>> spaces
let one = str "one" |>> fun x -> OneThing 1
let two = str "two" |>> fun x -> OneThing 2
let three = str "three" |>> fun x -> OneThing 3
let oneThing = (one <|> two <|> three)
let lotsOfThings = sepBy1 oneThing (str "or") |>> LotsOfThings
let lotsFirst = (lotsOfThings <|> oneThing)
test lotsFirst "one or two" // Success: LotsOfThings [OneThing 1; OneThing 2]
test lotsFirst "one" // Success: LotsOfThings [OneThing 1]
Как правильно вернуть OneThing
, если в списке есть только один элемент?
Я могу это сделать, если проверю список перед возвратом, например:нижеприведенное.Но это на самом деле не «чувствует» правильно.
let lotsOfThings = sepBy1 oneThing (str "or") |>> fun l -> if l.Length = 1 then l.[0] else l |> LotsOfThings
LinqPad из вышеперечисленного здесь: http://share.linqpad.net/sd8tpj.linq