[英]Stack overflow with two functions calling each other in Applicative parser
[英]Applicative style parser for constructor with two arguments
我想在尖括號中為逗號分隔的值對編寫解析器。 我用它采用以下方法:
pair p1 p2 = do
x1 <- p1
comma
x2 <- p2
return (x1, x2)
data Foo = Foo (Bar, Bar)
foo :: Parser Foo
foo = Foo <$> (angles $ pair bar bar)
但是我更喜歡Foo構造函數采用兩個參數而不是元組:
data Foo = Foo Bar Bar
編寫這樣一個解析器的最佳方法是什么? 理想情況下,我想重用標准Parsec解析器這樣的angles
並盡可能使用applicative。
編寫這樣一個解析器的最佳方法是什么? 理想情況下,我想重用標准Parsec解析器這樣的角度,並盡可能使用applicative。
在應用程序風格中,您的解析器將是
foo = angles $ Foo <$> bar <* comma <*> bar
從里到外,解析一個bar
,然后解析一個comma
,然后另一個bar
,然后將構造函數Foo
應用於兩個解析的bar
。 最后,所有被包裹在angles
組合器中,以便形成一個字符串
< bar , bar >
被解析( bar
應該消耗尾隨空格)。
將解析器與*>
和<*
applicative組合器的結果組合在一起,消除了pair
組合子的需要,並且很容易推廣給構造函數采用任意數量的參數。
正如CA McCann在評論中提到的那樣, (<$)
組合子(它是GHC實現Functor
類的一部分,具有默認實現(<$) = fmap . const
;但它不是語言標准的一部分)是有用的如果你想忽略一個領先的標記。 使用它,你可以寫
Foo <$ ignoreMe <*> bar <* comma <*> baz
這比使用括號更好
Foo <$> (ignoreMe *> bar) <* comma <*> baz
或者pure
pure Foo <* ignoreMe <*> bar <* comma <*> baz
如果沒有它,將以某種形式要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.