Пользовательское состояние в Parsec
Я разбираю выражение с использованием Parsec, и я хочу отслеживать переменные в этих выражениях с использованием состояния пользователя в Parsec. К сожалению, я действительно не понимаю, как это сделать.
С учетом следующего кода:
import Data.Set as Set
inp = "$x = $y + $z"
data Var = V String
var = do char '$'
n <- many1 letter
let v = Var n
-- I want to modify the set of variables here
return v
parseAssignment = ... -- parses the above assignment
run = case runIdentity $ runParserT parseAssignment Set.empty "" inp of
Left err -> ...
Right -> ...
Итак, u
в ParsecT s u m a
будет Set.Set
. Но как бы интегрировать обновление состояния в var
?
Я пробовал что-то вроде modify $ Set.insert v
, но это не работает, поскольку Set.Set
не является монадой состояния.
Ответы
Ответ 1
К сожалению, предложение Yuras updateParserState
не является оптимальным (вы использовали бы эту функцию, если хотите также изменить внутреннее состояние Parsec); вместо этого вы должны передать функцию, которая работает над вашим пользовательским состоянием (т.е. типа u -> u
) до modifyState
, например, в этом примере:
expr = do
x <- identifier
modifyState (+1)
-- ^ in this example, our type u is Int
return (Id x)
или использовать любую комбинацию функций getState
и putState
. Для вашего случая вы бы сделали что-то вроде:
modifyState (Set.insert v)
Подробнее см. эту ссылку.
Для более учебного введения в работу с пользовательским состоянием в Parsec этот документ, хотя и старый, должен быть релевантным.
Ответ 2
Вы можете использовать updateParserState