diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+# 0.1.3
+
+* Add `mapAccumL'`.
+* Make `scanl'` stricter by forcing the initial element.
+  Cf. https://github.com/haskell/core-libraries-committee/issues/335
+
 # 0.1.2
 
 * Add `heteroZip` and `heteroZipWith`.
diff --git a/bench/Bench.hs b/bench/Bench.hs
deleted file mode 100644
--- a/bench/Bench.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-{-# LANGUAGE PostfixOperators #-}
-
-module Main where
-
--- import qualified Data.List.Infinite as Inf
-import Test.Tasty.Bench
-
-main :: IO ()
-main = defaultMain
-  [
-  ]
diff --git a/infinite-list.cabal b/infinite-list.cabal
--- a/infinite-list.cabal
+++ b/infinite-list.cabal
@@ -1,14 +1,14 @@
 cabal-version:   2.2
 name:            infinite-list
-version:         0.1.2
+version:         0.1.3
 license:         BSD-3-Clause
 license-file:    LICENSE
 maintainer:      andrew.lelechenko@gmail.com
 author:          Bodigrim
 tested-with:
     ghc ==8.2.2 ghc ==8.4.4 ghc ==8.6.5 ghc ==8.8.4
-    ghc ==8.10.7 ghc ==9.0.2 ghc ==9.2.8 ghc ==9.4.8 ghc ==9.6.5
-    ghc ==9.8.4 ghc ==9.10.1 ghc ==9.12.1
+    ghc ==8.10.7 ghc ==9.0.2 ghc ==9.2.8 ghc ==9.4.8 ghc ==9.6.7
+    ghc ==9.8.4 ghc ==9.10.3 ghc ==9.12.2 ghc ==9.14.1
 
 homepage:        https://github.com/Bodigrim/infinite-list
 synopsis:        Infinite lists
@@ -94,17 +94,3 @@
 
     if impl(ghc <9.2)
         buildable: False
-
-benchmark infinite-bench
-    type:             exitcode-stdio-1.0
-    main-is:          Bench.hs
-    hs-source-dirs:   bench
-    default-language: Haskell2010
-    ghc-options:      -Wall
-    build-depends:
-        base,
-        infinite-list,
-        tasty-bench
-
-    if impl(ghc >=8.6)
-        ghc-options: -fproc-alignment=64
diff --git a/src/Data/List/Infinite.hs b/src/Data/List/Infinite.hs
--- a/src/Data/List/Infinite.hs
+++ b/src/Data/List/Infinite.hs
@@ -45,6 +45,7 @@
   scanl',
   scanl1,
   mapAccumL,
+  mapAccumL',
   traverse_,
   for_,
 
@@ -178,7 +179,7 @@
 import GHC.Exts (oneShot)
 import qualified GHC.Exts
 import Numeric.Natural (Natural)
-import Prelude (Bool (..), Enum, Int, Integer, Integral, Maybe (..), Traversable, Word, const, enumFrom, enumFromThen, flip, fromIntegral, id, maxBound, minBound, not, otherwise, snd, uncurry, (&&), (+), (-), (.), (||))
+import Prelude (Bool (..), Enum, Int, Integer, Integral, Maybe (..), Traversable, Word, const, enumFrom, enumFromThen, flip, fromIntegral, id, maxBound, minBound, not, otherwise, seq, snd, uncurry, (&&), (+), (-), (.), (||))
 
 import Data.List.Infinite.Internal
 import qualified Data.List.Infinite.Set as Set
@@ -371,23 +372,24 @@
 -- | @since 0.1.2
 instance MonadFix Infinite where
   mfix f = map (\(!n) -> fix $ head . genericDrop n . f) ((...) (0 :: Natural))
-  -- To put it simply, mfix f !! n = fix ((!! n) . f)
-  --
-  -- How to derive it? As in Section 1.4 of Erkok's thesis,
-  -- we can start by putting mfix f = fix (>>= f).
-  --
-  -- mfix f !! n
-  -- = fix (>>= f) !! n
-  -- = [by definition of fix, fix g = g (fix g)]
-  -- = (fix (>>= f) >>= f) !! n
-  -- = [by the choice of >>= above, (xs >>= g) !! n = g (xs !! n) !! n]
-  -- = f (fix (>>= f) !! n) !! n
-  -- = ((!! n) . f) (fix (>>= f) !! n)
-  -- = [restoring mfix from fix]
-  -- = ((!! n) . f) (mfix f !! n)
-  --
-  -- Then mfix f !! n = fix ((!! n) . f).
 
+-- To put it simply, mfix f !! n = fix ((!! n) . f)
+--
+-- How to derive it? As in Section 1.4 of Erkok's thesis,
+-- we can start by putting mfix f = fix (>>= f).
+--
+-- mfix f !! n
+-- = fix (>>= f) !! n
+-- = [by definition of fix, fix g = g (fix g)]
+-- = (fix (>>= f) >>= f) !! n
+-- = [by the choice of >>= above, (xs >>= g) !! n = g (xs !! n) !! n]
+-- = f (fix (>>= f) !! n) !! n
+-- = ((!! n) . f) (fix (>>= f) !! n)
+-- = [restoring mfix from fix]
+-- = ((!! n) . f) (mfix f !! n)
+--
+-- Then mfix f !! n = fix ((!! n) . f).
+
 -- | Get the first elements of an infinite list.
 head :: Infinite a -> a
 head (x :< _) = x
@@ -567,7 +569,7 @@
 
 -- | Same as 'Data.List.Infinite.scanl', but strict in accumulator.
 scanl' :: (b -> a -> b) -> b -> Infinite a -> Infinite b
-scanl' f z0 = (z0 :<) . flip (foldr (\x acc z -> let !fzx = f z x in fzx :< acc fzx)) z0
+scanl' f !z0 = (z0 :<) . flip (foldr (\x acc z -> let !fzx = f z x in fzx :< acc fzx)) z0
 
 scanlFB' :: (elt' -> elt -> elt') -> (elt' -> lst -> lst) -> elt -> (elt' -> lst) -> elt' -> lst
 scanlFB' f cons = \elt g -> oneShot (\x -> let !elt' = f x elt in elt' `cons` g elt')
@@ -579,7 +581,7 @@
 {-# RULES
 "scanl'" [~1] forall f a bs.
   scanl' f a bs =
-    build (\cons -> a `cons` foldr (scanlFB' f cons) bs a)
+    build (\cons -> a `seq` a `cons` foldr (scanlFB' f cons) bs a)
 "scanlList'" [1] forall f (a :: a) bs.
   foldr (scanlFB' f (:<)) bs a =
     tail (scanl' f a bs)
@@ -619,6 +621,26 @@
 "mapAccumLList" [1] forall f s xs.
   foldr (mapAccumLFB f) xs s =
     mapAccumL f s xs
+  #-}
+
+-- | Same as 'mapAccumL', but strict in accumulator.
+mapAccumL' :: (acc -> x -> (acc, y)) -> acc -> Infinite x -> Infinite y
+mapAccumL' f = flip (foldr (\x acc !s -> let (s', y) = f s x in y :< acc s'))
+
+mapAccumL'FB :: (acc -> x -> (acc, y)) -> x -> (acc -> Infinite y) -> acc -> Infinite y
+mapAccumL'FB f = \x r -> oneShot (\(!s) -> let (s', y) = f s x in y :< r s')
+
+{-# NOINLINE [1] mapAccumL' #-}
+
+{-# INLINE [0] mapAccumL'FB #-}
+
+{-# RULES
+"mapAccumL'" [~1] forall f s xs.
+  mapAccumL' f s xs =
+    foldr (mapAccumL'FB f) xs s
+"mapAccumL'List" [1] forall f s xs.
+  foldr (mapAccumL'FB f) xs s =
+    mapAccumL' f s xs
   #-}
 
 -- | Generate an infinite list of repeated applications.
diff --git a/src/Data/List/Infinite/Set.hs b/src/Data/List/Infinite/Set.hs
--- a/src/Data/List/Infinite/Set.hs
+++ b/src/Data/List/Infinite/Set.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE LambdaCase #-}
 
 -- |
@@ -10,12 +11,11 @@
   insert,
 ) where
 
-data Color = Red | Black
-  deriving (Show)
-
 -- | Okasaki red-black tree.
-data Set a = Empty | Node !Color !(Set a) !a !(Set a)
-  deriving (Show)
+data Set a
+  = Empty
+  | Red !(Set a) !a !(Set a)
+  | Black !(Set a) !a !(Set a)
 
 empty :: Set a
 empty = Empty
@@ -23,39 +23,55 @@
 member :: (a -> a -> Ordering) -> a -> Set a -> Bool
 member cmp = member'
   where
-    member' x = go
+    member' !x = go
       where
         go = \case
           Empty -> False
-          Node _ left center right -> case cmp x center of
-            LT -> go left
-            EQ -> True
-            GT -> go right
+          Red left center right -> whereToGo left center right
+          Black left center right -> whereToGo left center right
 
+        whereToGo left center right = case x `cmp` center of
+          LT -> go left
+          EQ -> True
+          GT -> go right
+{-# INLINE member #-}
+
 insert :: (a -> a -> Ordering) -> a -> Set a -> Set a
 insert cmp = insert'
   where
-    insert' x = blacken . go
+    insert' !x = blacken . go
       where
-        go = \case
-          Empty -> Node Red Empty x Empty
-          Node color left center right -> case cmp x center of
-            LT -> balance color (go left) center right
-            EQ -> Node color left center right
-            GT -> balance color left center (go right)
+        go node = case node of
+          Empty -> Red Empty x Empty
+          Red left center right -> case x `cmp` center of
+            LT -> Red (go left) center right
+            EQ -> node
+            GT -> Red left center (go right)
+          Black left center right -> case x `cmp` center of
+            LT -> balanceLeft (go left) center right
+            EQ -> node
+            GT -> balanceRight left center (go right)
 
-    blacken = \case
+    blacken node = case node of
       Empty -> Empty
-      Node _ left center right -> Node Black left center right
+      Red left center right -> Black left center right
+      Black {} -> node
+{-# INLINE insert #-}
 
-balance :: Color -> Set a -> a -> Set a -> Set a
-balance Black (Node Red (Node Red a b c) d e) f g =
-  Node Red (Node Black a b c) d (Node Black e f g)
-balance Black (Node Red a b (Node Red c d e)) f g =
-  Node Red (Node Black a b c) d (Node Black e f g)
-balance Black a b (Node Red (Node Red c d e) f g) =
-  Node Red (Node Black a b c) d (Node Black e f g)
-balance Black a b (Node Red c d (Node Red e f g)) =
-  Node Red (Node Black a b c) d (Node Black e f g)
-balance color left center right =
-  Node color left center right
+balanceLeft :: Set a -> a -> Set a -> Set a
+balanceLeft (Red (Red a b c) d e) f g =
+  Red (Black a b c) d (Black e f g)
+balanceLeft (Red a b (Red c d e)) f g =
+  Red (Black a b c) d (Black e f g)
+balanceLeft left center right =
+  Black left center right
+{-# INLINE balanceLeft #-}
+
+balanceRight :: Set a -> a -> Set a -> Set a
+balanceRight a b (Red (Red c d e) f g) =
+  Red (Black a b c) d (Black e f g)
+balanceRight a b (Red c d (Red e f g)) =
+  Red (Black a b c) d (Black e f g)
+balanceRight left center right =
+  Black left center right
+{-# INLINE balanceRight #-}
diff --git a/test/Fusion.hs b/test/Fusion.hs
--- a/test/Fusion.hs
+++ b/test/Fusion.hs
@@ -84,11 +84,13 @@
 mapAccumLRepeat n =
   I.mapAccumL (\acc x -> (acc, fromIntegral x)) 'q' (I.repeat (fromIntegral n :: Word))
 
+mapAccumLRepeat' :: Int -> Infinite Int
+mapAccumLRepeat' n =
+  I.mapAccumL' (\acc x -> (acc, fromIntegral x)) 'q' (I.repeat (fromIntegral n :: Word))
 
 takeFilterIterate :: [Int]
 takeFilterIterate = I.take 100 $ I.filter odd $ I.iterate (+ 1) 0
 
-
 sumTakeFilterIterate :: Int
 sumTakeFilterIterate = sum $ I.take 100 $ I.filter odd $ I.iterate (+ 1) 0
 
@@ -259,6 +261,7 @@
   , $(inspectTest $ 'foldrCycle `hasNoType` ''Infinite)
   , $(inspectTest $ 'foldrWordsCycle `hasNoType` ''NonEmpty)
   , $(inspectTest $ 'mapAccumLRepeat `hasNoType` ''Word)
+  , $(inspectTest $ 'mapAccumLRepeat' `hasNoType` ''Word)
 
   , $(inspectTest $ 'takeFilterIterate `hasNoType` ''Infinite)
   , $(inspectTest $ 'sumTakeFilterIterate `hasNoTypes` [''Infinite, ''[]])
diff --git a/test/Properties.hs b/test/Properties.hs
--- a/test/Properties.hs
+++ b/test/Properties.hs
@@ -2,6 +2,7 @@
 -- Copyright:   (c) 2022 Bodigrim
 -- Licence:     BSD3
 
+{-# LANGUAGE CPP                 #-}
 {-# LANGUAGE PostfixOperators    #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TupleSections       #-}
@@ -23,6 +24,7 @@
 import Test.Tasty.QuickCheck as QC
 
 import Control.Applicative
+import Control.Exception
 import Control.Monad
 import Control.Monad.Fix (mfix)
 import Data.Bifunctor
@@ -44,8 +46,10 @@
   arbitrary = (:<) <$> arbitrary <*> arbitrary
   shrink = const []
 
+#if !MIN_VERSION_QuickCheck(2,17,0)
 instance Arbitrary a => Arbitrary (NonEmpty a) where
   arbitrary = (:|) <$> arbitrary <*> arbitrary
+#endif
 
 trim :: Infinite a -> [a]
 trim = I.take 10
@@ -214,18 +218,29 @@
   , testProperty "scanl" $
     \(curry . applyFun -> (f :: Word -> Int -> Word)) s (Blind xs) ->
       trim1 (I.scanl f s xs) === L.scanl f s (trim xs)
-  , testProperty "scanl laziness" $ once $
+  , testProperty "scanl laziness 1" $ once $
     I.head (I.scanl undefined 'q' undefined) === 'q'
+  , testProperty "scanl laziness 2" $ once $
+    I.head (I.tail (I.scanl (const (const 'q')) undefined (I.repeat 'z'))) === 'q'
+
   , testProperty "scanl'" $
     \(curry . applyFun -> (f :: Word -> Int -> Word)) s (Blind xs) ->
       trim1 (I.scanl' f s xs) === L.scanl' f s (trim xs)
-  , testProperty "scanl' laziness" $ once $
+  , testProperty "scanl' laziness 1" $ once $
     I.head (I.scanl' undefined 'q' undefined) === 'q'
+  , testProperty "scanl' laziness 2" $ once $ ioProperty $ do
+    x <- try $ evaluate $ I.scanl' (const (const 'q')) undefined (I.repeat 'z')
+    pure $ case x of
+      Left (_ :: SomeException) -> True
+      _ -> False
+
   , testProperty "scanl1" $
     \(curry . applyFun -> (f :: Int -> Int -> Int)) (Blind xs) ->
       trim (I.scanl1 f xs) === L.scanl1 f (trim xs)
-  , testProperty "scanl1 laziness" $ once $
+  , testProperty "scanl1 laziness 1" $ once $
     I.head (I.scanl1 undefined ('q' :< undefined)) === 'q'
+  , testProperty "scanl1 laziness 2" $ once $
+    I.head (I.tail (I.scanl1 (const (const 'q')) (undefined :< I.repeat 'z'))) === 'q'
 
   , testProperty "mapAccumL" $
     \(curry . applyFun -> (f :: Bool -> Int -> (Bool, Word))) (Blind xs) ->
@@ -233,16 +248,32 @@
   , testProperty "mapAccumL laziness" $ once $
     I.head (I.mapAccumL (\_ x -> (undefined, x)) undefined ('q' :< undefined)) === 'q'
 
+  , testProperty "mapAccumL'" $
+    \(curry . applyFun -> (f :: Bool -> Int -> (Bool, Word))) (Blind xs) ->
+      trim (I.mapAccumL' f False xs) === snd (L.mapAccumL f False (trim xs))
+
   , testProperty "iterate" $
     \(applyFun -> (f :: Int -> Int)) s ->
       trim (I.iterate f s) === L.take 10 (L.iterate f s)
-  , testProperty "iterate laziness" $ once $
+  , testProperty "iterate laziness 1" $ once $
       I.head (I.iterate undefined 'q') === 'q'
+  , testProperty "iterate laziness 2" $ once $
+      I.head  (I.tail (I.iterate (\c -> if c == 'r' then undefined else 'r') 'q')) === 'r'
+  , testProperty "iterate laziness 3" $ once $
+    I.iterate (const 'q') undefined `seq` () === ()
+
   , testProperty "iterate'" $
     \(applyFun -> (f :: Int -> Int)) s ->
       trim (I.iterate' f s) === L.take 10 (L.iterate f s)
-  , testProperty "iterate' laziness" $ once $
+  , testProperty "iterate' laziness 1" $ once $
       I.head (I.iterate' undefined 'q') === 'q'
+  , testProperty "iterate' laziness 2" $ once $
+      I.head  (I.tail (I.iterate' (\c -> if c == 'r' then undefined else 'r') 'q')) === 'r'
+  , testProperty "iterate' laziness 3" $ once $ ioProperty $ do
+    xs <- try $ evaluate $ I.iterate' (const 'q') undefined
+    pure $ case xs of
+      Left (_ :: SomeException) -> True
+      _ -> False
 
   , testProperty "repeat" $
     \(s :: Int) ->
