Haskell - 将一个解析器穿插在另一个解析器中
Haskell - intersperse a parser with another one
我有两个解析器 parser1 :: Parser a
和 parser2 :: 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 []
。
事实上,这基本上就是 sepBy1
(sepBy
的变体,至少需要一个)的实现方式:
-- | @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 #-}
我有两个解析器 parser1 :: Parser a
和 parser2 :: 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 []
。
事实上,这基本上就是 sepBy1
(sepBy
的变体,至少需要一个)的实现方式:
-- | @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 #-}