Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 这是Text.Parsec的惯用用法吗?_Haskell_Parsec - Fatal编程技术网

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='/'
,但运行较慢,因为它在任何
/
处都会被截断,然后重新组合。