Haskell - 将一个解析器穿插在另一个解析器中

Haskell - intersperse a parser with another one

我有两个解析器 parser1 :: Parser aparser2 :: Parser a

我现在想解析 a 的列表,其中穿插着 parser2

想要的签名类似于

interspersedParser :: Parser b -> Parser a -> Parser [a]

例如,如果 Parser a 解析 'a' 字符,Parser b 解析 'b' 字符,那么 interspersedParser 应该解析

""
"a"
"aba"
"ababa"
...

我正在使用百万秒差距。是否已经有一些行为像这样的组合器,我目前找不到?

在 parsec 中有一个 sepBy 解析器可以做到这一点。 megaparsec 中似乎也有相同的解析器:https://hackage.haskell.org/package/megaparsec-4.4.0/docs/Text-Megaparsec-Combinator.html

当然,您可以使用 sepBy,但这不就是:

interspersedParser sepP thingP = (:) <$> thingP <*> many (sepP *> thingP)

编辑:哦,这至少需要一件事。您还想要空的,所以只需在末尾粘贴一个 <|> pure []

事实上,这基本上就是 sepBy1sepBy 的变体,至少需要一个)的实现方式:

-- | @sepBy p sep@ parses /zero/ or more occurrences of @p@, separated
-- by @sep@. Returns a list of values returned by @p@.
--
-- > commaSep p = p `sepBy` comma

sepBy :: Alternative m => m a -> m sep -> m [a]
sepBy p sep = sepBy1 p sep <|> pure []
{-# INLINE sepBy #-}

-- | @sepBy1 p sep@ parses /one/ or more occurrences of @p@, separated
-- by @sep@. Returns a list of values returned by @p@.

sepBy1 :: Alternative m => m a -> m sep -> m [a]
sepBy1 p sep = (:) <$> p <*> many (sep *> p)
{-# INLINE sepBy1 #-}