我正在閱讀Graham Hutton在Haskell編程。我陷在了帕爾斯的章節中。在它有定義爲兩個相互遞歸功能:許多產生空串的地方?
many p = many1 p +++ return []
many1 p = do v <- p
vs <- many p
return (v:vs)
凡many
實際上轉化成這種形式:
many1 p = p >>= (\ v -> many p >>= (\ vs -> return (v : vs)))
的>>=
操作者被定義爲:
p >>= f = P (\inp -> case parse p inp of
[] -> []
[(v,out)] -> parse (f v) out)
的+++
運營商定義爲:
p +++ q = P (\inp -> case parse p inp of
[] -> parse q inp
[(v,out)] -> [(v,out)])
個
有關這個問題的另一個功能是這些:
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
sat p = do x <- item
if p x then return x else failure
digit = sat isDigit
failure = P (\inp -> [])
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
return v = P (\inp -> [(v,inp)])
現在,企圖用many1
從字符串"a"
解析數字,就像當:
parse (many digit) "a"
結果是[("","a")]
。
在嘗試從使用many1
像字符串"a"
解析位數:
parse (many1 digit) "a"
結果是[]
。
我想我理解爲什麼第二個結果。 (many1 digit)
嘗試解析字符串"a"
,因此它調用digit "a"
,由於"a"
不是數字,因此失敗,因此空列表返回[]
。
但是,我不明白使用(many digit)
時的第一個結果。如果(many1 digit)
返回[]
那麼顯然它失敗了,所以在+++
運算符中,執行第二個case表達式。但是當我嘗試parse (return []) "a"
時,我得到的結果是[([], "a")]
。
我不明白爲什麼many
的結果是[("", "a")]
,結果many1
是[]
。 任何幫助表示讚賞。
P.S.我已經看過this question,但它沒有給我我正在尋找的答案。
當你談論「manny」和「manny1」時,那只是「許多」的錯誤拼寫,或者你的意思是不同的? –
請記住,「」== []因爲字符串只是字符列表的synactic糖。因此[([],「a」)] == [(「」,「a」)] –
這很簡單:'many'意味着解析零個或多個給定項目。字符串'「a」'從零開始,因此''「'開頭。 – Bakuriu