我最近開始學習Haskell,並一直在Parsec上嘗試我的手。但是,在過去的幾天裏,我一直在困擾着我一直無法找到解決方案的問題。所以,我試圖做的是寫一個解析器,可以解析這樣的字符串:如何使用只接受唯一元素的Parsec編寫解析器?
<"apple", "pear", "pineapple", "orange">
我寫這樣做的代碼是:
collection :: Parser [String]
collection = (char '<') *> (string `sepBy` char ',')) <* (char '>')
string :: Parser String
string = char '"' *> (many (noneOf ['\"', '\r', '\n', '"'])) <* char '"'
這對我工作得很好,因爲它能夠解析上面定義的字符串。儘管如此,我現在想強制執行這樣一條規則:此集合中的每個元素都必須是唯一的,這就是我遇到問題的地方。我在互聯網上搜索時發現的第一個結果是this之一,這表明使用nub
函數。雖然在這個問題上所陳述的問題並不相同,但它理論上可以解決我的問題。但是我不明白的是我如何在Parser中應用這個函數。我曾嘗試將nub函數添加到上面的代碼的幾個部分中,但沒有取得任何成功。後來我也試着做以下方式:
collection :: Parser [String]
collection = do
char '<'
value <- (string `sepBy` char ','))
char '>'
return nub value
但是,這並不工作,因爲類型不匹配nub
期待,我相信是的,我掙扎的問題之一。我也不完全確定nub
是否是正確的選擇。我的恐懼是我走錯了方向,我不能像這樣解決我的問題。有可能是我失蹤的東西嗎?任何建議或幫助任何人可以提供將不勝感激。
'return $ nub value' - 這是一個簡單的印刷錯誤。現在你試圖將'return'應用於'nub',而不是'nub value'。請注意,這不會使解析器只解析唯一的項目列表,它只會過濾列表中存在的重複項。 – Cubic
@Cubic感謝您指出這一點,這確實有效,你是正確的,這不會讓我的解析器解析一個獨特的項目列表,但它已經非常接近我想要實現的。我想知道的是,我想使用解析器實現我想實現的目標,還是應該嘗試以另一種方式實現這一點。 – Dexter
劇透:是的,這是可能的 - 但是如果你不限制那個列表中可能的字符串,你就進入了上下文敏感的領域。你必須以更手動的方式解析列表,因爲你需要記住你已經看過的列表項。 – Cubic