在 case 块内解析

Parsing within case block

所以我正在编写自己的解析器,这几乎完成了,但是我一直卡在函数的 return 中。我的 return 是 case,但在 case 中我必须进行解析,但我无法让它工作。

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) )

函数parsePosition来自类型parsePosition :: Parser Coord; tile 的构造函数是 Coord Bool Bool.

这当然行不通,因为 parsePosition returns Parser Coord 并且它期望 Coord (没有 "parse")。通常我只会 'unpack' 它,但是,我将如何在一个案例中做到这一点?

感谢帮助

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

您需要先 "push" 最后 return 案例分支

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)

现在,解析器 monad 中的分支是 运行,您可以像往常一样解压:

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" -> ...

类似

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

假设那些 parseXXXX 项是解析器。

或者通过使用 shadowing"update" 相应的变量来重组它以减少代码重复,如

parseCompontntsTile :: Tile -> Parser Tile
parseCompontntsTile (Tile pos fix wiel) = 
    do  parseWhiteSpace
        pattern <- match "pos:" `mplus` match "fixed:" `mplus` match "wheel:"
        (pos,fix,wiel) <- case pattern of
                 "pos"   -> do { pos <- parsePosition ; return (pos,fix,wiel) }
                 "fixed" -> do { fix <- parseFixed    ; return (pos,fix,wiel) }
                 "wheel" -> do { wiel <- parseWiel    ; return (pos,fix,wiel) } 
        -- .....
        return $ Tile pos fix wiel

如果,实际的 post 处理步骤更复杂(即在 case 之后,最终 [=14= 之前还有更多步骤]).