I am a very new student of Haskell. I have a working expression:
do x <- try parseA <|> parseB return x
which works fine (I use the Parsec package, but I hope this question has nothing to do with its functionality, as far as I know, <|> is an infix operator defined by Parsec). parseA and parseB both have the Parser Foo monad type, like the whole expression.
Based on what I have read so far, it seems like this should be equivalent
do return (try parseA <|> parseB)
and
do return $ try parseA <|> parseB
but none of the latter compiles, they complain about inappropriate types (errors below).
My other attempt to rewrite this as
(try parseA <|> parse B) >>= return
seems to work. But if I also misunderstood this, please tell me.
So my question is, can someone explain why the first three are different. I am confused why they are not equivalent. What am I missing?
Errors (in case this matters, although fwiw I don’t want to “fix” my code - I have a working version, I want to understand how the versions differ):
do return (try parseA <|> parseB)
gives
parse.hs:76:11: Couldn't match expected type 'Foo' with actual type 'Text.Parsec.Prim.ParsecT [Char] () Data.Functor.Identity.Identity Foo'
and
do return $ try parseA <|> parseB
gives
parse.hs:76:3: Couldn't match type 'Text.Parsec.Prim.ParsecT [Char] () Data.Functor.Identity.Identity Foo' with 'Foo' Expected type: Parser Foo Actual type: Text.Parsec.Prim.ParsecT String () Data.Functor.Identity.Identity (Text.Parsec.Prim.ParsecT [Char] () Data.Functor.Identity.Identity Foo)