@@ -29,7 +29,6 @@ import Prelude
29
29
30
30
import Data.Array as Array
31
31
import Data.Char as Char
32
- import Data.List (List (Cons, Nil), fromFoldable )
33
32
import Data.Maybe (Maybe (Just, Nothing))
34
33
import Data.String as String
35
34
import Data.String.Unsafe as Unsafe
@@ -106,7 +105,9 @@ foreign import _codePointAt
106
105
-> Maybe CodePoint
107
106
108
107
codePointAtFallback :: Int -> String -> Maybe CodePoint
109
- codePointAtFallback n s = Array .index (toCodePointArray s) n
108
+ codePointAtFallback n s = case uncons s of
109
+ Just { head, tail } -> if n == 0 then Just head else codePointAtFallback (n - 1 ) tail
110
+ _ -> Nothing
110
111
111
112
112
113
-- | Returns the number of code points in the leading sequence of code points
@@ -129,7 +130,7 @@ foreign import _count
129
130
-- | empty string. Operates in space and time linear to the length of the given
130
131
-- | string.
131
132
drop :: Int -> String -> String
132
- drop n s = fromCodePointArray ( Array .drop n (toCodePointArray s))
133
+ drop n s = String .drop ( String .length (take n s)) s
133
134
134
135
135
136
-- | Drops the leading sequence of code points which all match the given
@@ -227,7 +228,10 @@ take = _take takeFallback
227
228
foreign import _take :: (Int -> String -> String ) -> Int -> String -> String
228
229
229
230
takeFallback :: Int -> String -> String
230
- takeFallback n s = fromCodePointArray (Array .take n (toCodePointArray s))
231
+ takeFallback n _ | n < 1 = " "
232
+ takeFallback n s = case uncons s of
233
+ Just { head, tail } -> singleton head <> takeFallback (n - 1 ) tail
234
+ _ -> s
231
235
232
236
233
237
-- | Returns a string containing the leading sequence of code points which all
@@ -249,17 +253,22 @@ foreign import _toCodePointArray
249
253
-> Array CodePoint
250
254
251
255
toCodePointArrayFallback :: String -> Array CodePoint
252
- toCodePointArrayFallback s = unfoldr decode (fromFoldable ( Char .toCharCode <$> String .toCharArray s))
256
+ toCodePointArrayFallback s = unfoldr decode s
253
257
where
254
- decode :: List Int -> Maybe (Tuple CodePoint (List Int ))
255
- decode (Cons cu0 (Cons cu1 rest)) | isLead cu0 && isTrail cu1
256
- = Just (Tuple (unsurrogate cu0 cu1) rest)
257
- decode (Cons cu rest) = Just (Tuple (CodePoint cu) rest)
258
- decode Nil = Nothing
258
+ decode :: String -> Maybe (Tuple CodePoint String )
259
+ decode s' = (\{ head, tail } -> Tuple head tail) <$> uncons s'
259
260
260
261
261
262
-- | Returns a record with the first code point and the remaining code points
262
263
-- | of the given string. Returns Nothing if the string is empty. Operates in
263
264
-- | space and time linear to the length of the string.
264
265
uncons :: String -> Maybe { head :: CodePoint , tail :: String }
265
- uncons s = { head: _, tail: drop 1 s } <$> codePointAt 0 s
266
+ uncons s = case String .length s of
267
+ 0 -> Nothing
268
+ 1 -> Just { head: CodePoint (Unsafe .charCodeAt 0 s), tail: " " }
269
+ _ ->
270
+ let cu0 = Unsafe .charCodeAt 0 s in
271
+ let cu1 = Unsafe .charCodeAt 1 s in
272
+ if isLead cu0 && isTrail cu1
273
+ then Just { head: unsurrogate cu0 cu1, tail: String .drop 2 s }
274
+ else Just { head: CodePoint cu0, tail: String .drop 1 s }
0 commit comments