Сохранение состояния в мире без состояния

Я конвертирую контекстно-свободную грамматику в нормальную форму Грейбаха (GNF). Основное преобразование (от Hopcroft & Ullman) - это последовательность итераций по индексированным переменным грамматики. По сути, это "апатрид". Я реализовал его как последовательность сверток по соответствующим индексам (реализация довольно проста):

gnf :: Ord a => Set (Rule a) -> Set (Rule a)
gnf rl = foldl step1 rl [1..maxIndex rl]
 where step1 rl' k = foldl step2 rl' [1..k - 1]
        where step2 rl'' j = noLR k (subst rl'' k j)

maxIndex rl возвращает максимальный индекс переменной в наборе правил; subst rl kj выполняет подстановку в k -индексированных правилах на правила, правая часть которых начинается с j -индексированной переменной. После выполнения gnf мне нужно выполнить последний проход по грамматике в обратном порядке.

Проблема в noLR , который преобразует грамматику с леворекурсивным k -индексированные правила. Это функция с отслеживанием состояния, поскольку для каждого правила (или правила с индексом k ), к которому применяется noLR , должна быть создана уникальная переменная. Итак, я написал функцию с отслеживанием состояния

noLR :: Ord a => Int -> Set (Rule a) -> State [Sym a] (Set (Rule a))
noLR rl = do (n:ns) <- get; put ns;
             let rl' = ... remove left recursion rl n ...
              in return rl'

. Я могу упорядочить вместе noLR , чтобы обновить n , который noLR принимает в качестве параметра. Я не уверен, как выполнить noLR внутри шага 2 в приведенной выше функции. Кажется, я не могу использовать let ... в схеме , потому что вычисление с сохранением состояния встроено в несколько рекурсивных функций.

Я хочу иметь n - это глобальная переменная некоторого типа, аналогичная явной потоковой передаче n , которую я могу вызывать и обновлять внутри step2 , именно поэтому я изначально написал функцию как свертку с eta -расширением (для n ). Кто-нибудь знает, как я мог структурировать gnf внутри монады состояний для достижения такого эффекта? За исключением последнего вычисления в свертке, ничто другое не является «отслеживающим состояние», и мне удобно использовать монаду состояния только с «тривиальными» примерами. Я довольно потерян.

7
задан danportin 23 November 2010 в 19:40
поделиться