FParsec has no built-in sequence combinator that does exactly what you're looking for, but you could implement one yourself like in the following example:
let mySeq (parsers: seq<Parser<'t,'u>>) : Parser<'t[],'u> =
let ps = Array.ofSeq parsers
if ps.Length = 0 then preturn [||]
else
fun stream ->
let mutable stateTag = stream.StateTag
let mutable reply = ps.[0] stream
let mutable error = reply.Error
let mutable myReply = Reply()
if reply.Status <> Ok then myReply.Result <- [||]
else
// create array to hold results
let mutable xs = Array.zeroCreate ps.Length
xs.[0] <- reply.Result
let mutable i = 1
while i < ps.Length do
stateTag <- stream.StateTag
reply <- ps.[i] stream
error <- if stateTag <> stream.StateTag then reply.Error
else mergeErrors error reply.Error
if reply.Status = Ok then
xs.[i] <- reply.Result
i <- i + 1
else // truncate array and break loop
xs <- Array.sub xs 0 i
i <- ps.Length
myReply.Result <- xs
myReply.Status <- if reply.Status = Error && stateTag = stream.StateTag
then Ok
else reply.Status
myReply.Error <- error
myReply
With the mySeq
combinator, you can express your fooSeq
parser as
let fooSeq = mySeq [foo; bar; baz]