| Yes, but if it we're talking about parser monads, then usually you can't apply a function directly to a parser's result without either: 1. Being within the same monad. For example, you can `bind` a `Parser a` to a function only if it returns `Parser b`. 2. Performing an actual action and breaking it out of its monad. For example, if you're using the Parsec library, and you have a `Parser Int`, you can't get to that int without using a function like `parse`, performs the actual action of parsing input text. With a functor, you can compose a `Parser a` within an `a -> b` function, instead of having to return `Parser b` in your function. So if you have a `Parser Int`, and you want to turn it into a parser that multiplies its parsed input by 2, you can write `fmap (*2) myParser`, instead of having to write `myParser >>= \a -> return (a * 2)`. Parsers being functors means it's easier to compose them with other things, without having to actually perform the parse until you need to. |
> without having to actually perform the parse until you need to.
I'd rather parse my input before starting semantic analysis on it. Although if you really want to have a one-pass translator, literally being a composition three functions, `parse`, `analyze`, `emit`, with no visible intermediary structures then yeah, this allows for it.
But I'd argue that's more complicated than having three non-entwined passes with explicit, designed data structures serving as interfaces between them instead of invisibly unevaluated thunks; not to mention the sheer complexity of doing everything in one go (why do people even claim the single-pass compilers are simple?)