@@ -29,7 +29,6 @@ import Prelude
2929
3030import Data.Array as Array
3131import Data.Char as Char
32- import Data.List (List (Cons, Nil), fromFoldable )
3332import Data.Maybe (Maybe (Just, Nothing))
3433import Data.String as String
3534import Data.String.Unsafe as Unsafe
@@ -106,7 +105,9 @@ foreign import _codePointAt
106105 -> Maybe CodePoint
107106
108107codePointAtFallback :: 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
110111
111112
112113-- | Returns the number of code points in the leading sequence of code points
@@ -129,7 +130,7 @@ foreign import _count
129130-- | empty string. Operates in space and time linear to the length of the given
130131-- | string.
131132drop :: 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
133134
134135
135136-- | Drops the leading sequence of code points which all match the given
@@ -227,7 +228,10 @@ take = _take takeFallback
227228foreign import _take :: (Int -> String -> String ) -> Int -> String -> String
228229
229230takeFallback :: 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
231235
232236
233237-- | Returns a string containing the leading sequence of code points which all
@@ -249,17 +253,22 @@ foreign import _toCodePointArray
249253 -> Array CodePoint
250254
251255toCodePointArrayFallback :: String -> Array CodePoint
252- toCodePointArrayFallback s = unfoldr decode (fromFoldable ( Char .toCharCode <$> String .toCharArray s))
256+ toCodePointArrayFallback s = unfoldr decode s
253257 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'
259260
260261
261262-- | Returns a record with the first code point and the remaining code points
262263-- | of the given string. Returns Nothing if the string is empty. Operates in
263264-- | space and time linear to the length of the string.
264265uncons :: 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