Skip to content

Commit b38eb80

Browse files
refactor to avoid lists dep; better complexity adherence in fallbacks
1 parent cef521a commit b38eb80

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

bower.json

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
"purescript-maybe": "^3.0.0",
2323
"purescript-partial": "^1.2.0",
2424
"purescript-unfoldable": "^3.0.0",
25-
"purescript-lists": "^4.1.1",
2625
"purescript-arrays": "^4.0.1"
2726
},
2827
"devDependencies": {

src/Data/String/CodePoints.purs

+20-11
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import Prelude
2929

3030
import Data.Array as Array
3131
import Data.Char as Char
32-
import Data.List (List(Cons, Nil), fromFoldable)
3332
import Data.Maybe (Maybe(Just, Nothing))
3433
import Data.String as String
3534
import Data.String.Unsafe as Unsafe
@@ -106,7 +105,9 @@ foreign import _codePointAt
106105
-> Maybe CodePoint
107106

108107
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
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.
131132
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
133134

134135

135136
-- | Drops the leading sequence of code points which all match the given
@@ -227,7 +228,10 @@ take = _take takeFallback
227228
foreign import _take :: (Int -> String -> String) -> Int -> String -> String
228229

229230
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
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

251255
toCodePointArrayFallback :: 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.
264265
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

Comments
 (0)