Haskell 这是Text.Parsec的惯用用法吗?
我对Haskell 这是Text.Parsec的惯用用法吗?,haskell,parsec,Haskell,Parsec,我对Text.Parsec的使用有点生疏。如果我只想返回匹配的字符串,这是惯用法吗 category :: Stream s m Char => ParsecT s u m [Char] category = concat <$> (many1 $ (:) <$> char '/' <*> (many1 $ noneOf "/\n")) category::Stream s m Char=>ParsecT
Text.Parsec
的使用有点生疏。如果我只想返回匹配的字符串,这是惯用法吗
category :: Stream s m Char => ParsecT s u m [Char]
category = concat <$> (many1 $ (:) <$> char '/' <*> (many1 $ noneOf "/\n"))
category::Stream s m Char=>ParsecT s u m[Char]
category=concat(many1$(:)char'/'(many1$noneOf/\n”))
我觉得
liftM-concat可能有一个现有的操作符。我忽略了很多,但我不确定。我想没关系。一点明智的命名会让它更漂亮:
category = concat <$> many1 segment
where
segment = (:) <$> char '/' <*> many1 (noneOf "/\n")
category=concat-many1段
哪里
段=(:)字符“/”many1(非字符“/\n”)
我认为使用Parsec返回更结构化的内容会更习惯一些,例如字符串列表:
catList :: Parser [String]
catList = char '/' *> many1 alphaNum `sepBy1` char '/'
我不认为有像你想知道的那样的组合器,但这是Haskell,滚动你自己的控制结构或组合器总是可用的:
concatMany1 :: Parser [a] -> Parser [a]
concatMany1 p = concat <$> many1 p
catConcat = concatMany1 $ (:) <$> char '/' <*> many1 alphaNum
concatMany1::解析器[a]->解析器[a]
concatMany1 p=concatMany1 p
catConcat=concatMany1$(:)char'/'many1 alphaNum
但下一个combinator甚至更好,至少是地道的Haskell:
infixr 5 <:>
(<:>) :: Applicative f => f a -> f [a] -> f [a]
hd <:> tl = (:) <$> hd <*> tl
infixr 5
()::Applicative f=>fa->f[a]->f[a]
hd tl=(:)hd tl
现在我们可以写了
catCons :: Parser String
catCons = concatMany1 (char '/' <:> many1 alphaNum)
catCons::解析器字符串
catCons=concatMany1(字符“/”many1字母数)
但顺便说一句
contrivedExample :: IO String
contrivedExample = getChar <:> getLine
moreContrived :: String -> Maybe String
moreContrived name = find isLetter name <:> lookup name symbolTable
contrivedExample::IO字符串
contrivedExample=getChar getLine
更多人为::字符串->可能是字符串
MORECONSTRIVED name=查找工具名称查找名称symbolTable
不属于
您会注意到我使用了alphaNum
,其中您使用了noneOf/\n“
。我认为noneOf
不是好的做法;解析器应该非常小心地接受正确的东西。您是否绝对确定希望解析器接受/qwerty/12345/!“£$%^&*()@:?>(1)我想要完整的字符串(不是字符串列表),b/c我只需要路径。我将使用它作为散列键,然后将其打印(作为路径),因此始终以正确的格式保存对我来说是有意义的。(2)alphaNum
能很好地处理非ascii码吗?我将处理大量来自非英语代码页的字符我使用noneOf
的另一个原因是,我不知道某些类别不包含空格或符号。我有超过一百万个空格或符号,我正在解析的这个文件包含了我的第一个完整的空格或符号列表,每个空格或符号都在一行中。因此noneOf”/\n“
似乎是安全的。alphaNum
似乎减少到了,所以我来检查一下。@rampion我的观点是,目前通过使用noneOf
,解析器相当于行检查okLine xs=not(null xs)和&head xs='/'
,但运行较慢,因为它在任何/
处都会被截断,然后重新组合。