没有任何这样的组合器;如果有的话,它将在Text.Parsec.Char(这是定义涉及Char
的所有标准解析器组合函数的地方)。你应该可以很容易地定义它。
虽然我不认为你可以在toptopc上获得相同的性能优势,它依赖于内部FastSet
类型,它仅适用于8位字符。当然,如果你不需要Unicode支持,这可能不是问题,但code for FastSet
意味着你会得到不可预知的结果,传递的字符数大于'\255'
,所以如果你想重新使用基于FastSet
的解决方案,你会至少必须读取您在binary mode中解析的字符串。 (您还可以到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
你甚至可以尝试这样的事情,这应该至少与上述版本(包括当为单个inClass s
许多呼叫制造)作为高效,并且还避免了列表遍历开销:
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
(注意将递归移出的lambda;我不知道GHC是否可以自己做这件事。)
这个问题并不是真的要求解决方案,我可能最终会为此写一个TH宏,但上面的代码解决了这个问题很好。 – dflemstr 2011-12-28 02:55:40
我认为只要有效实施,我会增加一些价值,因为“对不起,对不起”对未来的访问者不是很有帮助:) – ehird 2011-12-28 03:11:47