Применимый анализатор стиля для конструктора с двумя аргументами

Я хочу написать, что анализатор для запятой отделил пару ценностей в угловых скобках. Я заставил его работать со следующим подходом:

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)

Однако, я предпочел бы, чтобы конструктор Фу взял два параметра, а не кортеж:

data Foo = Foo Bar Bar

Что лучший способ состоит в том, чтобы написать такому анализатору? Идеально я хотел бы снова использовать стандартные анализаторы Парсека такой углы и использование, применимое как можно больше.

2
nl ja de

2 ответы

Что лучший способ состоит в том, чтобы написать такому анализатору? Идеально я хотел бы снова использовать стандартные анализаторы Парсека такие углы и использование, применимое как можно больше.

В применимом стиле ваш анализатор был бы

foo = angles $ Foo <$> bar <* comma <*> bar

Входя, , бар разобран, затем запятая , от которого отказываются, и другой бар , тогда конструктор , Фу применяется к двум, разобранным бар s. Наконец, все обернуто в углы combinator, так, чтобы последовательность формы

< bar , bar >

разобран (, бар должен, вероятно, потреблять перемещение пробела).

Combining parsers ignoring the result of one with the *> and <* applicative combinators eliminates the need for the pair combinator and easily generalises to constructors taking an arbitrary number of arguments.

As C.A. McCann mentioned in a comment, the (<$) combinator (which is part of GHC's implementation of the Functor class, with the default implementation (<$) = fmap . const; but it's not part of the language standard) is useful too, if you want to ignore a leading token. Using that, you can write

Foo <$ ignoreMe <*> bar <* comma <*> baz

который более хорош, чем использование круглых скобок

Foo <$> (ignoreMe *> bar) <* comma <*> baz

или , чистый ,

pure Foo <* ignoreMe <*> bar <* comma <*> baz

как требовался бы в некоторой форме без него.

8
добавлено
класс Функтор f, где... (<$)::-> f b-> f - Определенный в 'GHC.Base' infixl 4 <$ Положительная сторона, которая полезна также.
добавлено автор Daniel Fischer, источник
Кроме того, для случая, где у вас есть ведущий символ, чтобы проигнорировать, можно использовать что-то, любят Фу <$ keywordFoo <*> бар <* запятая <*> baz . Я забываю, где (<$) определяется и что экспортирует его, все же.
добавлено автор C. A. McCann, источник

Что лучший способ состоит в том, чтобы написать такому анализатору? Идеально я хотел бы снова использовать стандартные анализаторы Парсека такие углы и использование, применимое как можно больше.

В применимом стиле ваш анализатор был бы

foo = angles $ Foo <$> bar <* comma <*> bar

Входя, , бар разобран, затем запятая , от которого отказываются, и другой бар , тогда конструктор , Фу применяется к двум, разобранным бар s. Наконец, все обернуто в углы combinator, так, чтобы последовательность формы

< bar , bar >

разобран (, бар должен, вероятно, потреблять перемещение пробела).

Combining parsers ignoring the result of one with the *> and <* applicative combinators eliminates the need for the pair combinator and easily generalises to constructors taking an arbitrary number of arguments.

As C.A. McCann mentioned in a comment, the (<$) combinator (which is part of GHC's implementation of the Functor class, with the default implementation (<$) = fmap . const; but it's not part of the language standard) is useful too, if you want to ignore a leading token. Using that, you can write

Foo <$ ignoreMe <*> bar <* comma <*> baz

который более хорош, чем использование круглых скобок

Foo <$> (ignoreMe *> bar) <* comma <*> baz

или , чистый ,

pure Foo <* ignoreMe <*> bar <* comma <*> baz

как требовался бы в некоторой форме без него.

8
добавлено
класс Функтор f, где... (<$)::-> f b-> f - Определенный в 'GHC.Base' infixl 4 <$ Положительная сторона, которая полезна также.
добавлено автор Daniel Fischer, источник
Кроме того, для случая, где у вас есть ведущий символ, чтобы проигнорировать, можно использовать что-то, любят Фу <$ keywordFoo <*> бар <* запятая <*> baz . Я забываю, где (<$) определяется и что экспортирует его, все же.
добавлено автор C. A. McCann, источник
Haskell
Haskell
910 участник(ов)

https://combot.org/chat/-1001043143583 Ссылки на полезные ресурсы: https://ruhaskell.org/links.html ;