on master help sign in
Sort of implement mapAccumL

--HG-- extra : convert_revision : da452ce31a7806923eb2c2a022de60f767688a13

commit220f2b9aebbd5978270b8fc35149a21b8c160d53 authorBryan O'Sullivan <bos@serpentine.com> dateWed 4 Feb 2009, 07:59 (18 years ago) parent7541131
3 files changed+33−1
Data/Text.hs+11−1 Data/Text/Fusion.hs+17 tests/Properties.hs+5
Data/Text.hs+11−1
@@ -80,7 +80,7 @@ module Data.Text
8080 -- , scanr1
8181
8282 -- ** Accumulating maps
83− -- , mapAccumL
83+ , mapAccumL
8484 -- , mapAccumR
8585
8686 -- ** Generation and unfolding
@@ -504,6 +504,16 @@ scanl1 f t | null t = empty
504504 | otherwise = scanl f (head t) (tail t)
505505{-# INLINE scanl1 #-}
506506
507+-- | /O(n)/ Like a combination of 'map' and 'foldl'. Applies a
508+-- function to each element of a 'Text', passing an accumulating
509+-- parameter from left to right, and returns a final 'Text'.
510+--
511+-- /Note/: Unlike the version over lists, this function does not return a
512+-- final value for the accumulator.
513+mapAccumL :: (a -> Char -> (a,Char)) -> a -> Text -> Text
514+mapAccumL f z t = unstream (S.mapAccumL f z (stream t))
515+{-# INLINE mapAccumL #-}
516+
507517-- -----------------------------------------------------------------------------
508518-- ** Generating and unfolding 'Text's
509519
Data/Text/Fusion.hs+17
@@ -64,6 +64,9 @@ module Data.Text.Fusion
6464 -- ** Scans
6565 , scanl
6666
67+ -- ** Accumulating maps
68+ , mapAccumL
69+
6770 -- ** Generation and unfolding
6871 , replicate
6972 , unfoldr
@@ -559,6 +562,20 @@ scanl f z0 (Stream next0 s0 len) = Stream next (S1 :!: z0 :!: s0) (len+1)
559562 Done -> Done
560563{-# INLINE [0] scanl #-}
561564
565+-- -----------------------------------------------------------------------------
566+-- ** Accumulating maps
567+
568+mapAccumL :: (a -> Char -> (a,Char)) -> a -> Stream Char -> Stream Char
569+mapAccumL f z0 (Stream next0 s0 len) = Stream next (s0 :!: z0) len
570+ where
571+ {-# INLINE next #-}
572+ next (s :!: z) = case next0 s of
573+ Yield x s' -> let (z',y) = f z x
574+ in Yield y (s' :!: z')
575+ Skip s' -> Skip (s' :!: z)
576+ Done -> Done
577+{-# INLINE [0] mapAccumL #-}
578+
562579-- -----------------------------------------------------------------------------
563580-- ** Generating and unfolding streams
564581
tests/Properties.hs+5
@@ -74,6 +74,9 @@ prop_minimum = L.minimum `eqEP` T.minimum
7474prop_scanl f z = L.scanl f z `eqP` (unpack . T.scanl f z)
7575prop_scanl1 f = L.scanl1 f `eqP` (unpack . T.scanl1 f)
7676
77+prop_mapAccumL f z = (snd . L.mapAccumL f z)`eqP` (unpack . T.mapAccumL f z)
78+ where types = f :: Int -> Char -> (Int,Char)
79+
7780prop_replicate n = L.replicate n `eq` (unpack . T.replicate n)
7881prop_unfoldr n = L.unfoldr f `eq` (unpack . T.unfoldr f)
7982 where f c | fromEnum c * 100 > n = Nothing
@@ -162,6 +165,8 @@ tests = [
162165 ("prop_scanl", mytest prop_scanl),
163166 ("prop_scanl1", mytest prop_scanl1),
164167
168+ ("prop_mapAccumL", mytest prop_mapAccumL),
169+
165170 ("prop_replicate", mytest prop_replicate),
166171 ("prop_unfoldr", mytest prop_unfoldr),
167172 ("prop_unfoldrN", mytest prop_unfoldrN),