I cannot store global data anywhere using Haskell
This is not true; in most cases, something like State monad is enough , but there is also ST monad .
You do not need a global state for this task. Writing a parser consists of two parts; lexical analysis and parsing. Lexical analysis simply turns a stream of characters into a stream of meaningful tokens. Syntax analysis turns tokens into AST; here you have to deal with indentation.
When you interpret indentation, you call the handler function when the indentation level changes - when it increases (nesting), you call the handler function (possibly with one arg increment) if you want to track the indentation level); when the level decreases, you simply return the corresponding part of the AST from the function.
(As an aside, using a global variable for this is something that would not be imperative for me - if you like, it is an instance variable. The state monad is very similar to the concept of this.)
Finally, I think that the phrase "I can’t put all my vocabulary rules inside any monad" means some kind of misunderstanding of the monads. If I needed to parse and save the global state, my code would look like this:
data AST = ... type Step = State Int AST parseFunction :: Stream -> Step parseFunction s = do level <- get ... if anotherFunction then put (level + 1) >> parseFunction ... else parseWhatever ... return node parse :: Stream -> Step parse s = do if looksLikeFunction then parseFunction ... main = runState parse 0 -- initial nesting of 0
Instead of combining functional applications with (.) Or ($) you combine them with (>>=) or (>>) . In addition, the algorithm is the same. (There is no "monad" to be "inside.")
Finally, you may need applicative functors:
eval :: Environment -> Node -> Evaluated eval e (Constant x) = Evaluated x eval e (Variable x) = Evaluated (lookup ex) eval e (Function fxy) = (f <$> (`eval` x) <*> (`eval` y)) e
(or
eval e (Function fxy) = ((`eval` f) <*> (`eval` x) <*> (`eval` y)) e
If you have something like "funcall" ... but I'm distracted.)
There is a wealth of parsing literature with applicative functors, monads, and arrows; all of which have the potential to solve your problem. Read them and see what you get.