在Haskell Parser中实现(< ++)

时间:2016-11-16 05:21:03

标签: parsing haskell

这样做的目的是使用StateT在Haskell中实现< ++以充当解析器

    import Control.Monad.State

    type Parser = StateT String []

    runParser :: Parser a -> String -> [(a,String)]
    runParser = runStateT

    parser :: (String -> [(a,String)]) -> Parser a
    parser = StateT

    (<++) :: Parser a -> Parser a -> Parser a

从这个基础开始,我如何实现&lt; ++以便它反映Text.ParserCombinators.ReadP中的定义

本地,独占,左偏选择:如果左解析器本地产生任何结果,则不使用右解析器。

1 个答案:

答案 0 :(得分:3)

您的解析器是函数String -> [(a,String)],其中参数是初始状态。因此,让我们构造一个尝试第一个解析器的函数,如果失败则尝试第二个解析器:

(<++) :: Parser a -> Parser a -> Parser a
p1 <++ p2 =
  parser $ \s0 ->            -- 1. captures initial state
    case runParser p1 s0 of  -- 2. run first parser
      (x:xs) -> x : xs       -- 3. success
      [] -> runParser p2 s0  -- 4. otherwise run second parser

一些解析器尝试这个

-- | Always fails
failP :: Parser a
failP = parser (const [])

-- | Parses an Int
intP :: Parser Int
intP = parser reads

按预期输出? (也许还有更具启发性的测试用例......)

λ> runParser (failP <++ intP) "2014"
[(2014,"")]
λ> runParser (intP <++ failP) "2014"
[(2014,"")]
λ> runParser (intP <++ intP) "2014"
[(2014,"")]