Search code examples
parsinghaskellfunctional-programmingmonadsdo-notation

Parsing within case block


So I am writing my own parser which is almost done, however I keep on getting stuck with the return of my function. My return is a case, but within the case I have to do a parse, which I can't manage to make it work.

parseCompontntsTile :: Tile -> Parser Tile
parseCompontntsTile (Tile pos fix wiel) = 
    do  parseWhiteSpace
        patern <- match "pos:" `mplus`     match "fixed:" `mplus` match "wheel:"
        return (case patern of
                 "pos"   -> (Tile  parsePosition  fix  wiel)
                 "fixed" -> (Tile  pos     parseFixed  wiel)
                 "wheel" -> (Tile  pos     fix    parseWiel) )

The function parsePosition is from the type parsePosition :: Parser Coord; the constructor of tile is Coord Bool Bool.

This of course doesn't work because parsePosition returns Parser Coord and it expects a Coord (without the "parse"). Normally I would just 'unpack' it, however, how would I do this within a case ?

thx for the help


Solution

  • Normally I would just 'unpack' it, however, how would I do this within a case ?

    You need to "push" the final return inside the case branches first

    pattern <- match "pos:" `mplus`  ....
    case pattern of
       "pos"   -> return (Tile  parsePosition  fix  wiel)
       "fixed" -> return (Tile  pos     parseFixed  wiel)
       "wheel" -> return (Tile  pos     fix    parseWiel)
    

    Now, having the branches being run in the parser monad, you can unpack as usual:

    pattern <- match "pos:" `mplus`  ....
    case pattern of
       "pos"   -> do  -- alternative 1
          pp <- parsePosition
          return (Tile pp fix wiel)
       "fixed" -> -- alternative 2
          (\pf -> Tile pos pf wiel) <$> parseFixed
       "wheel" -> ...