У меня есть эта функция compile
, которая должна взять строку, а затем дать выражение.Проблемы с рекурсией в Haskell
Это как Expression
было определено:
data Expression = Name Char | Lambda Char Expression | Apply Expression Expression
deriving Show
Допустим, что строка, что функция «компилировать» занимает:
"\\x.\\y.yx"
Так, в конце функция compile
предполагается это окончательное выражение:
Lambda 'x' (Lambda 'y' (Name 'y') (Name 'x'))
Это является compile
функция:
compile :: [Char] -> Expression
compile (x:xs) = if [x] == "\\" then Lambda (head xs) (compile (tail xs))
else if [x] == "." then compile xs
else if null xs then Name x
else Name x
В настоящее время эта функция устраняет последнюю часть выражения ((Name 'x')
). Я задал вопрос:
Как эта функция может продолжать двигаться дальше с более Name
s, если один раз я получу Name
Я не могу продолжать переходить к той же функции с остальной частью выражения? Так как Expression
был определен таким образом, если Expression
является Name
, он просто имеет Name
и не более, на нем не осталось никакого выражения.
Я имею в виду, как я могу взять каждый Name
что в Expression
, «говоря» Haskell, что я хочу, чтобы продолжать поиски Name
с и не только остановить, когда один Name
найден.
Я думал, что, возможно, создание другой функции было хорошей идеей, но я не могу понять, как вызвать эту функцию несколько раз. Правда в том, что я действительно не привык к рекурсии в Haskell, и мне действительно нужна помощь.
Как это сделать?
Собственно, написать парсер LL с прямой рекурсией совсем не сложно. Это просто утомительно (хорошо, что есть некоторые угловые случаи, которые сложны, но ничего, что могло бы возникнуть при анализе выражений лямбда-исчисления) – Cubic
@Cubic. Действительно легко программировать (даже на императивных языках!), Если вы понимаете, что такое грамматика LL , и немного теории, лежащей в основе.Тем не менее, это не то, что я ожидал бы от среднего программиста самостоятельно открыть без какого-либо предварительного воздействия на формальные языки. Нужно понять, что (для языка под рукой) вы можете написать грамматику так, чтобы один токен обзора был достаточно, чтобы разрешить недетерминированность в постановках для каждого нетерминала. – chi
Ну, вы можете _often_ уйти с одним токеном взглядом. LL (1) не охватывает все контекстно-свободные грамматики. – Cubic