我当前的实现与
Text.ParserCombinators.ReadP
:
trim :: ReadP String
trim = do skipSpaces
content <- some get
skipSpaces
eof
return content
问题是,运行时经常弹出不明确的结果:
ghci> readP_to_S trim " hello world "
[("hello world",""),("hello world ","")]
我相信我需要指定修剪后的内容不会以空格字符结尾,但除了这种极其低效的设计之外,我不知道如何表达这一点:
trim :: ReadP String
trim = do skipSpaces
content <- many get
lastOne <- satisfy (not . isSpace)
skipSpaces
eof
return (content ++ [lastOne])
我们可以拥有更好的东西,对吧?
与其尝试通过解析器组合来做到这一点,为什么不直接解析内容然后修剪,例如:
import Data.Char(isSpace)
import Data.List(dropWhileEnd)
trim :: ReadP String
trim = do skipSpaces
content <- many get
skipSpaces
eof
return (trimData content)
trimStr :: String -> String
trimStr = dropWhileEnd isSpace . dropWhile isSpace
解析器可以缩短为:
trim :: ReadP String
trim = trimStr <$> (many get <* eof)
因此,我们首先检索所有字符,然后返回修剪后的字符串,尽管这里可能不需要
eof
。