【发布时间】:2016-08-22 02:12:41
【问题描述】:
我正在研究“在 48 小时内为自己编写一个方案”来学习 Haskell,但我遇到了一个我不太了解的问题。这是this section底部练习中的问题2。
任务是重写
import Text.ParserCombinators.Parsec
parseString :: Parser LispVal
parseString = do
char '"'
x <- many (noneOf "\"")
char '"'
return $ String x
这样正确转义的引号(例如,在“This sentence \” is nonsense”中)被解析器接受。
在命令式语言中,我可能会写出类似这样的东西(大致是 Python 的伪代码):
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 语句在命令式伪代码中所做的工作.
感谢您抽出宝贵时间阅读本文并给我建议。
【问题讨论】:
标签: parsing haskell functional-programming monads parsec