Commits

Bryan O'Sullivan committed af2e77d

Implement lazy splitAt

Comments (0)

Files changed (1)

     -- , drop
     -- , takeWhile
     -- , dropWhile
-    -- , splitAt
+    , splitAt
     -- , span
     -- , break
     -- , group
     -- , sort
     ) where
 
+import Prelude (Char, Bool(..), Functor(..), Int, Maybe(..), String,
+                Eq(..), Ord(..), (++),
+                Read(..), Show(..),
+                (&&), (||), (+), (-), (.), ($),
+                not, return, otherwise)
 import Data.String (IsString(..))
 import qualified Data.Text as T
 import qualified Data.Text.Fusion as S
 "TEXT append -> unfused" [1] forall t1 t2.
     unstream (S.append (stream t1) (stream t2)) = append t1 t2
  #-}
+
+-- | /O(n)/ 'splitAt' @n t@ returns a pair whose first element is a
+-- prefix of @t@ of length @n@, and whose second is the remainder of
+-- the string. It is equivalent to @('take' n t, 'drop' n t)@.
+splitAt :: Int -> Text -> (Text, Text)
+splitAt = loop
+  where loop _ Empty      = (empty, empty)
+        loop n t | n <= 0 = (empty, t)
+        loop n (Chunk t ts)
+             | n < len   = let (ts',ts'') = T.splitAt n t
+                           in (Chunk ts' Empty, Chunk ts'' Empty)
+             | otherwise = let (ts',ts'') = loop (n - len) ts
+                           in (Chunk t ts', ts'')
+             where len = T.length t