2013-11-24 33 views
3

我想解析一些文本,其中某些字段在大多數情況下都會有結構但偶爾會出現這種結構(由於特殊的外框,拼寫錯誤等)結構缺失。創建Parser a - > Parser b - > Parser的解析器組合器(或者ab)

E.g.正常情況下是Cost: 5,但偶爾會讀取Cost: 5mCost: 3 + 1 per ally或其他一些隨機的東西。

在普通解析器(p)無法正常工作的情況下,我想回退到只將整行作爲字符串的解析器。

爲此,我想創建一個類型爲Parser a -> Parser b -> Either a b的組合器。但是,我無法解決如何檢查第一個解析器是否成功的結果,而不需要執行諸如case parse p "" txt of ...之類的操作。

我看不到在組合子的生成,但我敢肯定,有一些簡單的方法來解決這個問題,我很想念

回答

6

我想你想是這樣的

eitherParse :: Parser a -> Parser b -> Parser (Either a b) 
eitherParse a b = fmap Left (try a) <|> fmap Right b 

ŧ他try只是爲了確保如果a消耗一些輸入,然後失敗,你會正確回溯。然後,你可以使用正常的方法來運行一個分析器,以產生Either ParseError (Either a b)

這是很容易轉換成你的Either a b

case parse p "" str of 
    Right (Left a) -> useA a 
    Right (Right b) -> useB b 
    Left err  -> handleParserError err 
+0

忽略此評論 - 發佈之後我想到了這件事,但是GHC不能簡單地將a和b統一爲(fmap Left foo)::或者ab,(fmap右欄)::任一ab – Squidly

+0

@MrBones你能澄清你的意思?這對我來說編譯得很好 – jozefg

+0

我錯了,當我交換參數a和b時,我沒有更正類型簽名。 – Squidly