Пользовательское состояние в 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 этот документ, хотя и старый, должен быть релевантным.