Haskell 与Parsec中的attorParsecs`inClass`等效
我正在将一些代码从attoparsec翻译成Parsec,因为解析器需要生成更好的错误消息。ATOPASSEC代码广泛使用Haskell 与Parsec中的attorParsecs`inClass`等效,haskell,parsec,attoparsec,Haskell,Parsec,Attoparsec,我正在将一些代码从attoparsec翻译成Parsec,因为解析器需要生成更好的错误消息。ATOPASSEC代码广泛使用inClass(和notInClass)。Parsec是否有类似的功能,可以让我机械地翻译inClass-事件?Hayoo和Hoogle没有就此事提供任何见解 inClass :: String -> Char -> Bool inClass“a-c”-)0-3-”相当于\x->elem x“abc”()0123-“,但后者对于大范围编写效率低且繁琐 如果没有其
inClass
(和notInClass
)。Parsec是否有类似的功能,可以让我机械地翻译inClass
-事件?Hayoo和Hoogle没有就此事提供任何见解
inClass :: String -> Char -> Bool
inClass“a-c”-)0-3-”
相当于\x->elem x“abc”()0123-“
,但后者对于大范围编写效率低且繁琐
如果没有其他可用的函数,我将自己重新实现该函数。不,parsec中没有等效的函数。你必须自己写。我看到两个主要的选择
inClass
语法,从中创建一个字符串
,用于oneOf
满足的函数
(|||) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
p ||| q = \x -> p x || q x
(&&&) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
p &&& q = \x -> p x && q x
parseClass (l:'-':h:more) = ((>= l) &&& (<= h)) ||| parseClass more
parseClass (c:cs) = (== c) ||| parseClass cs
parseClass [] = const False
(a->Bool)->(a->Bool)->a->Bool
p | | | q=\x->p x | | q x
(&&&):(a->Bool)->(a->Bool)->a->Bool
p&&q=\x->p x&&q x
parseClass(l:'-':h:more)=((>=l)&&&&(没有任何这样的组合符;如果有,它将位于(这是所有涉及Char
的标准解析器组合符函数的定义位置)。您应该能够相当容易地定义它
不过,我不认为您能够获得attoparsec所具有的相同性能优势;它依赖于内部FastSet
类型,该类型仅适用于8位字符。当然,如果您不需要Unicode支持,这可能不是一个问题,但这意味着您将通过大于'\255'
,因此,如果您想重用基于FastSet
的解决方案,您至少必须读取正在解析的字符串。(您还必须将FastSet
的实现复制到您的程序中,因为它没有导出…)
如果您的范围字符串很短,那么像这样的简单解决方案可能会非常快:
type Range = (Char, Char)
inClass :: String -> Char -> Bool
inClass = inClass' . parseClass
parseClass :: String -> [Range]
parseClass "" = []
parseClass (a:'-':b:xs) = (a, b) : parseClass xs
parseClass (x:xs) = (x, x) : parseClass xs
inClass' :: [Range] -> Char -> Bool
inClass' cls c = any (\(a,b) -> c >= a && c <= b) cls
(注意将递归从lambda中移出;我不知道GHC是否能够/将自己做到这一点。)问题并不是真的需要解决,我可能会为此编写一个TH宏,但上面的代码很好地解决了这个问题。我想我会尽可能增加一些价值,因为“不,对不起”这对未来的访问者没有多大帮助:)
inClass :: String -> Char -> Bool
inClass "" = const False
inClass (a:'-':b:xs) = \c -> (c >= a && c <= b) || f c where f = inClass xs
inClass (x:xs) = \c -> c == x || f c where f = inClass xs