У меня есть следующий ADT:Проблем с Applicative стилем Parsec
type Program = [Expr]
data Expr =
Num Int
| Bool Bool
| Binding String Expr
deriving (Show)
Вот анализатор для переменных связывания выражений вида lhs is rhs
.
binding :: Parser Expr
binding = do
lhs <- word
spaces
string "is"
spaces
rhs <- expr
return $ Binding lhs rhs
Это прекрасно работает, но когда я пытаюсь преобразовать его в аппликативный стиль, это дает неверный результат.
binding :: Parser Expr
binding = Binding <$> word <* (spaces *> string "is" *> spaces) *> expr
*>
Замена с >>
в скобках, часть не работает. В чем разница между этими двумя реализациями? Есть ли комбинатор для составления двух парсеров и игнорирования результата обоих?
Попытка отладки с Debug.trace
тоже не работала ... Ничего не было напечатано.
binding :: Parser Expr
binding = (\x y -> trace (show (x, y)) (Binding x y)) <$> word <* (spaces *> string "is" *> spaces) *> expr
Остальная часть синтаксического анализа, для контекста:
word :: Parser String
word = many1 letter
expr :: Parser Expr
expr = binding <|> atom
program :: Parser Program
program = do
spaces
result <- many (expr <* spaces)
return result
Быстро догадаться, но разве вы не должны использовать '(<*>)' после 'word' в вашем определении' binding'? I.e: 'binding = Binding <$> Слово <*> (пробелы *> строка" есть "*> пробелы) *> expr' – danem
Это работает? Возможно, вы должны предоставить больше своего кода. http://lpaste.net/121008 – danem
Вы заметили это быстро.:) Спасибо за помощь! – user1953221