@@ -90,6 +90,7 @@ unsafeCodePointAt0Fallback s =
90
90
-- | of code points from the beginning, if there is such a code point. Operates
91
91
-- | in constant space and in time linear to `n`.
92
92
codePointAt :: Int -> String -> Maybe CodePoint
93
+ codePointAt n _ | n < 0 = Nothing
93
94
codePointAt 0 " " = Nothing
94
95
codePointAt 0 s = Just (unsafeCodePointAt0 s)
95
96
codePointAt n s = _codePointAt codePointAtFallback Just Nothing unsafeCodePointAt0 n s
@@ -113,16 +114,23 @@ codePointAtFallback n s = case uncons s of
113
114
-- | which all match the given predicate. Operates in constant space and in
114
115
-- | time linear to the length of the given string.
115
116
count :: (CodePoint -> Boolean ) -> String -> Int
116
- count = _count isLead isTrail unsurrogate
117
+ count = _count countFallback unsafeCodePointAt0
117
118
118
119
foreign import _count
119
- :: (Int -> Boolean )
120
- -> (Int -> Boolean )
121
- -> (Int -> Int -> CodePoint )
120
+ :: ((CodePoint -> Boolean ) -> String -> Int )
121
+ -> (String -> CodePoint )
122
122
-> (CodePoint -> Boolean )
123
123
-> String
124
124
-> Int
125
125
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
+
126
134
127
135
-- | Drops the given number of code points from the beginning of the given
128
136
-- | string. If the string does not have that many code points, returns the
0 commit comments