In this post we will briefly define
Parser to have an
Alternative is used in a similar way, but it has some better named functions when looked at in terms of parsing.
Making the Data Type an Alternative
Since we defined
Parser as a
MonadPlus, we can use
MonadPlus functions to implement
Parser as an
import Control.Applicative instance Alternative Parser where empty = mzero (<|>) = mplus
In my opinion,
empty is a little more explicit in terms of parsers, and
<|> gives the idea that the parser is doing something close to that of an
|| operation. For the calculator we made before, this does not change much, but you will see how much easier it will be to read the parser for Hisp.
import Control.Applicative data Expression = Expr Op Expression Expression | Number Int deriving Show data Op = Add | Sub | Div | Mul deriving Show -- keep these functions the same as they were before spaces = many $ char ' ' digit = oneof "0123456789" expression = expression' <|> integer -- change these ones to return something useful after parsing. operator = oneof "+*/-" >>= toOp toOp '+' = Add toOp '-' = Sub toOp '/' = Div toOp '*' = Mul integer = Number . \s -> (read s :: Int) <$> many1 digit expression' = Expr <$> (char '(' *> op <* spaces) <*> (expression <* spaces) <*> expression
There is also the nice addition of the
many function that is given in
Control.Applicative. This means we no longer need to define our own
many, as it is just a more specific version of the same function! The code for this last post on building a parser can be found here.