Skip to content

Commit fcce912

Browse files
authored
Add mapAccumL' (#22)
1 parent aa8b7d5 commit fcce912

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

src/Data/List/Infinite.hs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module Data.List.Infinite (
4545
scanl',
4646
scanl1,
4747
mapAccumL,
48+
mapAccumL',
4849
traverse_,
4950
for_,
5051

@@ -621,6 +622,26 @@ mapAccumLFB f = \x r -> oneShot (\s -> let (s', y) = f s x in y :< r s')
621622
mapAccumL f s xs
622623
#-}
623624

625+
-- | Same as 'mapAccumL', but strict in accumulator.
626+
mapAccumL' :: (acc -> x -> (acc, y)) -> acc -> Infinite x -> Infinite y
627+
mapAccumL' f = flip (foldr (\x acc !s -> let (s', y) = f s x in y :< acc s'))
628+
629+
mapAccumL'FB :: (acc -> x -> (acc, y)) -> x -> (acc -> Infinite y) -> acc -> Infinite y
630+
mapAccumL'FB f = \x r -> oneShot (\(!s) -> let (s', y) = f s x in y :< r s')
631+
632+
{-# NOINLINE [1] mapAccumL' #-}
633+
634+
{-# INLINE [0] mapAccumL'FB #-}
635+
636+
{-# RULES
637+
"mapAccumL'" [~1] forall f s xs.
638+
mapAccumL' f s xs = foldr (mapAccumL'FB f) xs s
639+
640+
"mapAccumL'List" [1] forall f s xs.
641+
foldr (mapAccumL'FB f) xs s = mapAccumL' f s xs
642+
#-}
643+
644+
624645
-- | Generate an infinite list of repeated applications.
625646
iterate :: (a -> a) -> a -> Infinite a
626647
iterate f = go

test/Fusion.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,13 @@ mapAccumLRepeat :: Int -> Infinite Int
8484
mapAccumLRepeat n =
8585
I.mapAccumL (\acc x -> (acc, fromIntegral x)) 'q' (I.repeat (fromIntegral n :: Word))
8686

87+
mapAccumLRepeat' :: Int -> Infinite Int
88+
mapAccumLRepeat' n =
89+
I.mapAccumL' (\acc x -> (acc, fromIntegral x)) 'q' (I.repeat (fromIntegral n :: Word))
8790

8891
takeFilterIterate :: [Int]
8992
takeFilterIterate = I.take 100 $ I.filter odd $ I.iterate (+ 1) 0
9093

91-
9294
sumTakeFilterIterate :: Int
9395
sumTakeFilterIterate = sum $ I.take 100 $ I.filter odd $ I.iterate (+ 1) 0
9496

@@ -259,6 +261,7 @@ main = defaultMain $ testGroup "All"
259261
, $(inspectTest $ 'foldrCycle `hasNoType` ''Infinite)
260262
, $(inspectTest $ 'foldrWordsCycle `hasNoType` ''NonEmpty)
261263
, $(inspectTest $ 'mapAccumLRepeat `hasNoType` ''Word)
264+
, $(inspectTest $ 'mapAccumLRepeat' `hasNoType` ''Word)
262265

263266
, $(inspectTest $ 'takeFilterIterate `hasNoType` ''Infinite)
264267
, $(inspectTest $ 'sumTakeFilterIterate `hasNoTypes` [''Infinite, ''[]])

test/Properties.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ main = defaultMain $ testGroup "All"
233233
, testProperty "mapAccumL laziness" $ once $
234234
I.head (I.mapAccumL (\_ x -> (undefined, x)) undefined ('q' :< undefined)) === 'q'
235235

236+
, testProperty "mapAccumL'" $
237+
\(curry . applyFun -> (f :: Bool -> Int -> (Bool, Word))) (Blind xs) ->
238+
trim (I.mapAccumL' f False xs) === snd (L.mapAccumL f False (trim xs))
239+
236240
, testProperty "iterate" $
237241
\(applyFun -> (f :: Int -> Int)) s ->
238242
trim (I.iterate f s) === L.take 10 (L.iterate f s)

0 commit comments

Comments
 (0)