Я пытаюсь преобразовать следующую грамматическую продукцию
callExpr:
primaryExpr
| callExpr primaryExpr
к выражению Parsec в Haskell.
Очевидно, проблема в том, что он леворекурсивный, поэтому я пытаюсь разобрать его в стиле рекурсивного восхождения. Псевдокод, который я пытаюсь реализовать:
e = primaryExp
while(true) {
e2 = primaryExp
if(e2 failed) break;
e = CallExpr(e, e2)
}
и моя попытка перевести это на Haskell:
callExpr :: IParser Expr
callExpr = do
e <- primaryExpr
return $ callExpr' e
where
callExpr' e = do
e2m <- optionMaybe primaryExpr
e' <- maybe e (\e2 -> callExpr' (CallExpr e e2)) e2m
return e'
где primaryExpr
имеет тип IParser Expr
, а IParser определяется как
type IParser a = ParsecT String () (State SourcePos) a
Однако это дает мне следующую ошибку типа:
Couldn't match type `ParsecT String () (State SourcePos) t0'
with `Expr'
Expected type: ParsecT String () (State SourcePos) Expr
Actual type: ParsecT
String
()
(State SourcePos)
(ParsecT String () (State SourcePos) t0)
In a stmt of a 'do' block: return $ callExpr' e
In the expression:
do { e <- primaryExpr;
return $ callExpr' e }
In an equation for `callExpr':
callExpr
= do { e <- primaryExpr;
return $ callExpr' e }
where
callExpr' e
= do { e2m <- optionMaybe primaryExpr;
.... }
Как исправить ошибку этого типа?