Я работал над «Напишите себе схему через 48 часов», чтобы узнать Haskell, и я столкнулся с проблемой, которую я действительно не понимаю. Это вопрос 2 из упражнений внизу this section.Как выразить логику разбора в Parsec ParserT monad
Задача состоит в том, чтобы переписать
import Text.ParserCombinators.Parsec
parseString :: Parser LispVal
parseString = do
char '"'
x <- many (noneOf "\"")
char '"'
return $ String x
таким образом, что кавычки, которые должным образом экранированы (например, в «Эта фраза \» нонсенс ") быть принятым анализатором.
В императивном языке Я мог бы написать что-то вроде этого (примерно вещий псевдокоде):
def parseString(input):
if input[0] != "\"" or input[len(input)-1] != "\"":
return error
input = input[1:len(input) - 1] # slice off quotation marks
output = "" # This is the 'zero' that accumulates over the following loop
# If there is a '"' in our string we want to make sure the previous char
# was '\'
for n in range(len(input)):
if input[n] == "\"":
try:
if input[n - 1] != "\\":
return error
catch IndexOutOfBoundsError:
return error
output += input[n]
return output
Я смотрел на docs for Parsec, и я просто не могу понять, как решить эту проблему как монадическое выражение.
Я получил это:
parseString :: Parser LispVal
parseString = do
char '"'
regular <- try $ many (noneOf "\"\\")
quote <- string "\\\""
char '"'
return $ String $ regular ++ quote
Но это работает только для одной кавычки, и он должен быть в самом конце строки - я не могу думать о функциональной экспрессии, которая делает работайте с моими петлями и if-statements в императивном псевдокоде.
Я ценю, что вы не торопитесь, чтобы прочитать это и дать мне совет.
В сторону: 'х >> вернуться a' является' а <$ x'. – user2407038
О, спасибо. Я обновлю пример! –
Спасибо! Я работал над сигнатурами типов и документацией, чтобы понять, почему 'x >> return a' является' a <$ x'. Есть ли причина, почему последнее выражение предпочтительнее первого здесь? И есть ли причина, по которой '_ <- char dq' предпочитается над' char dq'? (отредактировано) – lachrimae