There are several important issues in your code.
First of all, as @scrwtp noted in the answer, your parser returns unit . Here's why: operator (>>.) Returns only the result returned by the correct internal parser. On the other hand, (.>>) will return the result of the left parser, and (.>>.) Will return the tuple of both the left and the right.
So parser1 >>. parser2 >>. eof parser1 >>. parser2 >>. eof parser1 >>. parser2 >>. eof essentially (parser1 >>. parser2) >>. eof (parser1 >>. parser2) >>. eof .
The code in parens completely ignores the result of parser1 , and the second (>>.) Then ignores the entire result of the analyzer in parens. Finally, eof returns unit , and this value is returned.
Instead, you may need some meaningful data returned , for example. parsed string. The easiest way:
let capitalized = (asciiUpper .>>. many asciiLower .>> eof)
Pay attention to the operators. The code for inverted can be executed in a similar way.
This parser will be of type Parser<(char * char list), unit> , tuple of the first character and all the rest, so you may need to combine them back . There are several ways to do this:
let mymerge (c1: char, cs: char list) = c1 :: cs
The beauty of this code is that your mymerge is a normal function , working with a regular char , it does not know anything about parsers or so. It just works with data, and the operator (>>=) does the rest.
Note. pCapitalized also a parser, but returns a single char list .
Nothing stops you from applying further transitions . As you mentioned, print the line back:
let pCapitalizedAndReversed = capitalized >>= mymerge >>= List.rev
I wrote the code this way for the purpose. On different lines, you see a gradual transition of your domain data, still within the Parser paradigm . This is important because any subsequent transition may "decide" that the data is bad for some reason and, for example, raises a parsing exception. Or, alternatively, it can be combined with another parser.
As soon as the data of your domain (the parsed word) is completed, you will get the result, as indicated in another answer.
A small note. choice is redundant for only two parsers. Use (<|>) instead. From experience, careful selection of parser combinators is important because making the wrong choice inside your parsing logic can easily cause your parsers to slow down dramatically.
See FParsec Primitives for more details.