그러한 결합 자 (combinator)가 없습니다. 존재했다면, (이는 모든 표준 파서 결합 자 함수가 정의 된 Char
이 정의되어 있음)에 있습니다. 당신은 그것을 아주 쉽게 정의 할 수 있어야합니다.
비록 attoparsec이 its implementation과 동일한 성능 이점을 얻을 수 있다고 생각하지 않습니다. 8 비트 문자로만 작동하는 내부 FastSet
유형을 사용합니다. 물론 유니 코드 지원이 필요하지 않은 경우 문제가되지 않을 수도 있지만 code for FastSet
은 '\255'
보다 큰 Chars를 전달하면 예기치 않은 결과를 얻게되므로 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
(람다의 을으로 재전송하는 데주의하십시오. GHC가이 일을 할 수 있는지/모르겠다.)
이 질문은 실제로 해결책을 요구하지는 않았지만 아마도 TH 매크로를 작성하게 될 것이지만 위의 코드는 문제를 해결합니다. 아주 잘. – dflemstr
나는 "nope, sorry"가 미래의 방문자들에게는별로 도움이되지 않기 때문에 효율적인 구현이 간다면 가치를 추가 할 것이라고 생각했습니다. :) – ehird