[英]Infinite loop when implementing “zero or more” in Haskell Arrow parser
[英]Implementing (<++) within a Haskell Parser
目的是使用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
從這個基礎上,我如何實現<++,以便它鏡像Text.ParserCombinators.ReadP中的定義。
本地,排他,左偏選項:如果左解析器在本地根本不產生任何結果,則不使用右解析器。
您的解析器是函數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,"")]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.