@@ -90,6 +90,7 @@ unsafeCodePointAt0Fallback s =
9090-- | of code points from the beginning, if there is such a code point. Operates
9191-- | in constant space and in time linear to `n`.
9292codePointAt :: Int -> String -> Maybe CodePoint
93+ codePointAt n _ | n < 0 = Nothing
9394codePointAt 0 " " = Nothing
9495codePointAt 0 s = Just (unsafeCodePointAt0 s)
9596codePointAt n s = _codePointAt codePointAtFallback Just Nothing unsafeCodePointAt0 n s
@@ -113,16 +114,23 @@ codePointAtFallback n s = case uncons s of
113114-- | which all match the given predicate. Operates in constant space and in
114115-- | time linear to the length of the given string.
115116count :: (CodePoint -> Boolean ) -> String -> Int
116- count = _count isLead isTrail unsurrogate
117+ count = _count countFallback unsafeCodePointAt0
117118
118119foreign import _count
119- :: (Int -> Boolean )
120- -> (Int -> Boolean )
121- -> (Int -> Int -> CodePoint )
120+ :: ((CodePoint -> Boolean ) -> String -> Int )
121+ -> (String -> CodePoint )
122122 -> (CodePoint -> Boolean )
123123 -> String
124124 -> Int
125125
126+ countFallback :: (CodePoint -> Boolean ) -> String -> Int
127+ countFallback p s = countTail p s 0
128+ where
129+ countTail :: (CodePoint -> Boolean ) -> String -> Int -> Int
130+ countTail p' s' accum = case uncons s' of
131+ Just { head, tail } -> if p' head then countTail p' tail (accum + 1 ) else accum
132+ _ -> accum
133+
126134
127135-- | Drops the given number of code points from the beginning of the given
128136-- | string. If the string does not have that many code points, returns the
0 commit comments