diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 1.0.5
+
+* Add `Functor` instance for `Border`
+* Improve performance and reduce allocations during computation of higher dimension `DW` arrays [#142](https://github.com/lehins/massiv/issues/142)
+
 # 1.0.4
 
 * Improve performance of sorting algorithm and its parallelization. Fix huge slow down on
diff --git a/massiv.cabal b/massiv.cabal
--- a/massiv.cabal
+++ b/massiv.cabal
@@ -1,5 +1,5 @@
 name:                massiv
-version:             1.0.4.1
+version:             1.0.5.0
 synopsis:            Massiv (Массив) is an Array Library.
 description:         Multi-dimensional Arrays with fusion, stencils and parallel computation.
 homepage:            https://github.com/lehins/massiv
diff --git a/src/Data/Massiv/Array/Delayed/Push.hs b/src/Data/Massiv/Array/Delayed/Push.hs
--- a/src/Data/Massiv/Array/Delayed/Push.hs
+++ b/src/Data/Massiv/Array/Delayed/Push.hs
@@ -9,6 +9,7 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}
+
 -- |
 -- Module      : Data.Massiv.Array.Delayed.Push
 -- Copyright   : (c) Alexey Kuleshevich 2019-2022
@@ -16,20 +17,19 @@
 -- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
 -- Stability   : experimental
 -- Portability : non-portable
---
-module Data.Massiv.Array.Delayed.Push
-  ( DL(..)
-  , Array(..)
-  , Loader
-  , toLoadArray
-  , makeLoadArrayS
-  , makeLoadArray
-  , unsafeMakeLoadArray
-  , unsafeMakeLoadArrayAdjusted
-  , fromStrideLoad
-  , appendOuterM
-  , concatOuterM
-  ) where
+module Data.Massiv.Array.Delayed.Push (
+  DL (..),
+  Array (..),
+  Loader,
+  toLoadArray,
+  makeLoadArrayS,
+  makeLoadArray,
+  unsafeMakeLoadArray,
+  unsafeMakeLoadArrayAdjusted,
+  fromStrideLoad,
+  appendOuterM,
+  concatOuterM,
+) where
 
 import Control.Monad
 import Control.Scheduler as S (traverse_)
@@ -40,45 +40,48 @@
 #include "massiv.h"
 
 -- | Delayed load representation. Also known as Push array.
-data DL = DL deriving Show
+data DL = DL deriving (Show)
 
 type Loader e =
-  forall s. Scheduler s () -- ^ Scheduler that will be used for loading
-         -> Ix1 -- ^ Start loading at this linear index
-         -> (Ix1 -> e -> ST s ()) -- ^ Linear element writing action
-         -> (Ix1 -> Sz1 -> e -> ST s ()) -- ^ Linear region setting action
-         -> ST s ()
-
+  forall s
+   . Scheduler s ()
+  -- ^ Scheduler that will be used for loading
+  -> Ix1
+  -- ^ Start loading at this linear index
+  -> (Ix1 -> e -> ST s ())
+  -- ^ Linear element writing action
+  -> (Ix1 -> Sz1 -> e -> ST s ())
+  -- ^ Linear region setting action
+  -> ST s ()
 
 data instance Array DL ix e = DLArray
-  { dlComp    :: !Comp
-  , dlSize    :: !(Sz ix)
-  , dlLoad    :: Loader e
+  { dlComp :: !Comp
+  , dlSize :: !(Sz ix)
+  , dlLoad :: Loader e
   }
 
 instance Strategy DL where
   getComp = dlComp
   {-# INLINE getComp #-}
-  setComp c arr = arr {dlComp = c}
+  setComp c arr = arr{dlComp = c}
   {-# INLINE setComp #-}
   repr = DL
 
-
 instance Index ix => Shape DL ix where
   maxLinearSize = Just . SafeSz . elemsCount
   {-# INLINE maxLinearSize #-}
 
-
 instance Size DL where
   size = dlSize
   {-# INLINE size #-}
-  unsafeResize !sz !arr = arr { dlSize = sz }
+  unsafeResize !sz !arr = arr{dlSize = sz}
   {-# INLINE unsafeResize #-}
 
 instance Semigroup (Array DL Ix1 e) where
   (<>) = mappendDL
   {-# INLINE (<>) #-}
 
+{- FOURMOLU_DISABLE -}
 instance Monoid (Array DL Ix1 e) where
   mempty = DLArray {dlComp = mempty, dlSize = zeroSz, dlLoad = \_ _ _ _ -> pure ()}
   {-# INLINE mempty #-}
@@ -91,16 +94,22 @@
   mconcat [x, y] = x <> y
   mconcat xs = mconcatDL xs
   {-# INLINE mconcat #-}
+{- FOURMOLU_ENABLE -}
 
-mconcatDL :: forall e . [Array DL Ix1 e] -> Array DL Ix1 e
+mconcatDL :: forall e. [Array DL Ix1 e] -> Array DL Ix1 e
 mconcatDL !arrs =
-  DLArray {dlComp = foldMap getComp arrs, dlSize = SafeSz k, dlLoad = load}
+  DLArray{dlComp = foldMap getComp arrs, dlSize = SafeSz k, dlLoad = load}
   where
     !k = F.foldl' (+) 0 (unSz . size <$> arrs)
-    load :: forall s .
-      Scheduler s () -> Ix1 -> (Ix1 -> e -> ST s ()) -> (Ix1 -> Sz1 -> e -> ST s ()) -> ST s ()
+    load
+      :: forall s
+       . Scheduler s ()
+      -> Ix1
+      -> (Ix1 -> e -> ST s ())
+      -> (Ix1 -> Sz1 -> e -> ST s ())
+      -> ST s ()
     load scheduler startAt dlWrite dlSet =
-      let loadArr !startAtCur DLArray {dlSize = SafeSz kCur, dlLoad} = do
+      let loadArr !startAtCur DLArray{dlSize = SafeSz kCur, dlLoad} = do
             let !endAtCur = startAtCur + kCur
             scheduleWork_ scheduler $ dlLoad scheduler startAtCur dlWrite dlSet
             pure endAtCur
@@ -109,15 +118,19 @@
     {-# INLINE load #-}
 {-# INLINE mconcatDL #-}
 
-
-mappendDL :: forall e . Array DL Ix1 e -> Array DL Ix1 e -> Array DL Ix1 e
+mappendDL :: forall e. Array DL Ix1 e -> Array DL Ix1 e -> Array DL Ix1 e
 mappendDL (DLArray c1 sz1 load1) (DLArray c2 sz2 load2) =
-  DLArray {dlComp = c1 <> c2, dlSize = SafeSz (k1 + k2), dlLoad = load}
+  DLArray{dlComp = c1 <> c2, dlSize = SafeSz (k1 + k2), dlLoad = load}
   where
     !k1 = unSz sz1
     !k2 = unSz sz2
-    load :: forall s.
-      Scheduler s () -> Ix1 -> (Ix1 -> e -> ST s ()) -> (Ix1 -> Sz1 -> e -> ST s ()) -> ST s ()
+    load
+      :: forall s
+       . Scheduler s ()
+      -> Ix1
+      -> (Ix1 -> e -> ST s ())
+      -> (Ix1 -> Sz1 -> e -> ST s ())
+      -> ST s ()
     load scheduler !startAt dlWrite dlSet = do
       scheduleWork_ scheduler $ load1 scheduler startAt dlWrite dlSet
       scheduleWork_ scheduler $ load2 scheduler (startAt + k1) dlWrite dlSet
@@ -128,8 +141,9 @@
 -- agree, otherwise `SizeMismatchException`.
 --
 -- @since 0.4.4
-appendOuterM ::
-     forall ix e m. (Index ix, MonadThrow m)
+appendOuterM
+  :: forall ix e m
+   . (Index ix, MonadThrow m)
   => Array DL ix e
   -> Array DL ix e
   -> m (Array DL ix e)
@@ -138,7 +152,7 @@
       (!i2, !szl2) = unconsSz sz2
   unless (szl1 == szl2) $ throwM $ SizeMismatchException sz1 sz2
   pure $
-    DLArray {dlComp = c1 <> c2, dlSize = consSz (liftSz2 (+) i1 i2) szl1, dlLoad = load}
+    DLArray{dlComp = c1 <> c2, dlSize = consSz (liftSz2 (+) i1 i2) szl1, dlLoad = load}
   where
     load :: Loader e
     load scheduler !startAt dlWrite dlSet = do
@@ -151,23 +165,24 @@
 -- for all arrays in the list, otherwise `SizeMismatchException`.
 --
 -- @since 0.4.4
-concatOuterM ::
-     forall ix e m. (Index ix, MonadThrow m)
+concatOuterM
+  :: forall ix e m
+   . (Index ix, MonadThrow m)
   => [Array DL ix e]
   -> m (Array DL ix e)
 concatOuterM =
   \case
-    []     -> pure empty
-    (x:xs) -> F.foldlM appendOuterM x xs
+    [] -> pure empty
+    (x : xs) -> F.foldlM appendOuterM x xs
 {-# INLINE concatOuterM #-}
 
-
 -- | Describe how an array should be loaded into memory sequentially. For parallelizable
 -- version see `makeLoadArray`.
 --
 -- @since 0.3.1
-makeLoadArrayS ::
-     forall ix e. Index ix
+makeLoadArrayS
+  :: forall ix e
+   . Index ix
   => Sz ix
   -- ^ Size of the resulting array
   -> e
@@ -183,8 +198,9 @@
 -- of this function see `unsafeMakeLoadArray`.
 --
 -- @since 0.4.0
-makeLoadArray ::
-     forall ix e. Index ix
+makeLoadArray
+  :: forall ix e
+   . Index ix
   => Comp
   -- ^ Computation strategy to use. Directly affects the scheduler that gets created for
   -- the loading function.
@@ -199,8 +215,13 @@
   -> Array DL ix e
 makeLoadArray comp sz defVal writer = DLArray comp sz load
   where
-    load :: forall s.
-      Scheduler s () -> Ix1 -> (Ix1 -> e -> ST s ()) -> (Ix1 -> Sz1 -> e -> ST s ()) -> ST s ()
+    load
+      :: forall s
+       . Scheduler s ()
+      -> Ix1
+      -> (Ix1 -> e -> ST s ())
+      -> (Ix1 -> Sz1 -> e -> ST s ())
+      -> ST s ()
     load scheduler !startAt uWrite uSet = do
       uSet startAt (toLinearSz sz) defVal
       let safeWrite !ix !e
@@ -217,8 +238,9 @@
 -- function does not perform any bounds checking.
 --
 -- @since 0.3.1
-unsafeMakeLoadArray ::
-     forall ix e. Index ix
+unsafeMakeLoadArray
+  :: forall ix e
+   . Index ix
   => Comp
   -- ^ Computation strategy to use. Directly affects the scheduler that gets created for
   -- the loading function.
@@ -250,8 +272,9 @@
 -- adjusted. Which means the writing function gets one less argument.
 --
 -- @since 0.5.2
-unsafeMakeLoadArrayAdjusted ::
-     forall ix e. Index ix
+unsafeMakeLoadArrayAdjusted
+  :: forall ix e
+   . Index ix
   => Comp
   -> Sz ix
   -> Maybe e
@@ -259,8 +282,13 @@
   -> Array DL ix e
 unsafeMakeLoadArrayAdjusted comp sz mDefVal writer = DLArray comp sz load
   where
-    load :: forall s.
-      Scheduler s () -> Ix1 -> (Ix1 -> e -> ST s ()) -> (Ix1 -> Sz1 -> e -> ST s ()) -> ST s ()
+    load
+      :: forall s
+       . Scheduler s ()
+      -> Ix1
+      -> (Ix1 -> e -> ST s ())
+      -> (Ix1 -> Sz1 -> e -> ST s ())
+      -> ST s ()
     load scheduler !startAt uWrite dlSet = do
       S.traverse_ (dlSet startAt (toLinearSz sz)) mDefVal
       writer scheduler (\i -> uWrite (startAt + i))
@@ -270,26 +298,38 @@
 -- | Convert any `Load`able array into `DL` representation.
 --
 -- @since 0.3.0
-toLoadArray ::
-     forall r ix e. (Size r, Load r ix e)
+toLoadArray
+  :: forall r ix e
+   . (Size r, Load r ix e)
   => Array r ix e
   -> Array DL ix e
 toLoadArray arr = DLArray (getComp arr) sz load
   where
     !sz = size arr
-    load :: forall s.
-      Scheduler s () -> Ix1 -> (Ix1 -> e -> ST s ()) -> (Ix1 -> Sz1 -> e -> ST s ()) -> ST s ()
+    load
+      :: forall s
+       . Scheduler s ()
+      -> Ix1
+      -> (Ix1 -> e -> ST s ())
+      -> (Ix1 -> Sz1 -> e -> ST s ())
+      -> ST s ()
     load scheduler !startAt dlWrite dlSet =
-      iterArrayLinearWithSetST_ scheduler arr (dlWrite . (+ startAt)) (\offset -> dlSet (offset + startAt))
+      iterArrayLinearWithSetST_
+        scheduler
+        arr
+        (dlWrite . (+ startAt))
+        (\offset -> dlSet (offset + startAt))
     {-# INLINE load #-}
-{-# INLINE[1] toLoadArray #-}
+{-# INLINE [1] toLoadArray #-}
+
 {-# RULES "toLoadArray/id" toLoadArray = id #-}
 
 -- | Convert an array that can be loaded with stride into `DL` representation.
 --
 -- @since 0.3.0
-fromStrideLoad ::
-     forall r ix e. (StrideLoad r ix e)
+fromStrideLoad
+  :: forall r ix e
+   . StrideLoad r ix e
   => Stride ix
   -> Array r ix e
   -> Array DL ix e
@@ -313,26 +353,25 @@
   {-# INLINE makeArrayLinear #-}
   replicate comp !sz !e = makeLoadArray comp sz e $ \_ _ -> pure ()
   {-# INLINE replicate #-}
-  iterArrayLinearWithSetST_ scheduler DLArray {dlLoad} = dlLoad scheduler 0
+  iterArrayLinearWithSetST_ scheduler DLArray{dlLoad} = dlLoad scheduler 0
   {-# INLINE iterArrayLinearWithSetST_ #-}
 
 instance Index ix => Functor (Array DL ix) where
-  fmap f arr = arr {dlLoad = loadFunctor arr f}
+  fmap f arr = arr{dlLoad = loadFunctor arr f}
   {-# INLINE fmap #-}
   (<$) = overwriteFunctor
   {-# INLINE (<$) #-}
 
 overwriteFunctor :: forall ix a b. Index ix => a -> Array DL ix b -> Array DL ix a
-overwriteFunctor e arr = arr {dlLoad = load}
+overwriteFunctor e arr = arr{dlLoad = load}
   where
     load :: Loader a
     load _ !startAt _ dlSet = dlSet startAt (linearSize arr) e
     {-# INLINE load #-}
 {-# INLINE overwriteFunctor #-}
 
-
-loadFunctor ::
-     Array DL ix a
+loadFunctor
+  :: Array DL ix a
   -> (a -> b)
   -> Scheduler s ()
   -> Ix1
diff --git a/src/Data/Massiv/Array/Delayed/Windowed.hs b/src/Data/Massiv/Array/Delayed/Windowed.hs
--- a/src/Data/Massiv/Array/Delayed/Windowed.hs
+++ b/src/Data/Massiv/Array/Delayed/Windowed.hs
@@ -11,7 +11,7 @@
 
 -- |
 -- Module      : Data.Massiv.Array.Delayed.Windowed
--- Copyright   : (c) Alexey Kuleshevich 2018-2022
+-- Copyright   : (c) Alexey Kuleshevich 2018-2025
 -- License     : BSD3
 -- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
 -- Stability   : experimental
@@ -27,6 +27,7 @@
 ) where
 
 import Control.Monad (when)
+import Control.Scheduler (trivialScheduler_)
 import Data.Massiv.Array.Delayed.Pull
 import Data.Massiv.Array.Manifest.Boxed
 import Data.Massiv.Array.Manifest.Internal
@@ -34,6 +35,7 @@
 import Data.Massiv.Core.Common
 import Data.Massiv.Core.List (showArrayList, showsArrayPrec)
 import Data.Maybe (fromMaybe)
+import GHC.Base (modInt)
 import GHC.TypeLits
 
 -- | Delayed Windowed Array representation.
@@ -56,7 +58,9 @@
   fmap f arr@Window{windowIndex} = arr{windowIndex = f . windowIndex}
 
 data instance Array DW ix e = DWArray
-  { dwArray :: !(Array D ix e)
+  { dwComp :: !Comp
+  , dwSize :: !(Sz ix)
+  , dwIndex :: ix -> e
   , dwWindow :: !(Maybe (Window ix e))
   }
 
@@ -65,16 +69,16 @@
   showList = showArrayList
 
 instance Strategy DW where
-  setComp c arr = arr{dwArray = (dwArray arr){dComp = c}}
+  setComp c arr = arr{dwComp = c}
   {-# INLINE setComp #-}
-  getComp = dComp . dwArray
+  getComp = dwComp
   {-# INLINE getComp #-}
   repr = DW
 
 instance Functor (Array DW ix) where
-  fmap f arr@DWArray{dwArray, dwWindow} =
+  fmap f arr@DWArray{dwIndex, dwWindow} =
     arr
-      { dwArray = fmap f dwArray
+      { dwIndex = f . dwIndex
       , dwWindow = fmap f <$> dwWindow
       }
   {-# INLINE fmap #-}
@@ -147,7 +151,9 @@
   -> Array DW ix e
 insertWindow !arr !window =
   DWArray
-    { dwArray = delay arr
+    { dwComp = getComp arr
+    , dwSize = arrSize
+    , dwIndex = unsafeIndex arr
     , dwWindow =
         Just $!
           Window
@@ -159,7 +165,7 @@
     }
   where
     wStart' = unSz (Sz (liftIndex2 min wStart (liftIndex (subtract 1) sz)))
-    Sz sz = size arr
+    arrSize@(Sz sz) = size arr
     Window
       { windowStart = wStart
       , windowSize = Sz wSize
@@ -179,7 +185,12 @@
 --
 -- @since 0.3.0
 dropWindow :: Array DW ix e -> Array D ix e
-dropWindow = dwArray
+dropWindow DWArray{..} =
+  DArray
+    { dComp = dwComp
+    , dSize = dwSize
+    , dPrefIndex = PrefIndex dwIndex
+    }
 {-# INLINE dropWindow #-}
 
 zeroWindow :: Index ix => Window ix e
@@ -191,34 +202,34 @@
 instance Exception EmptyWindowException where
   displayException _ = "Index of zero size Window"
 
-windowError :: a
-windowError = throwImpossible EmptyWindowException
+windowError :: ix -> a
+windowError _ = throwImpossible EmptyWindowException
 {-# NOINLINE windowError #-}
 
 loadWithIx1
-  :: (Monad m)
+  :: Monad m
   => (m () -> m ())
   -> Array DW Ix1 e
   -> (Ix1 -> e -> m a)
   -> m (Ix1 -> Ix1 -> m (), Ix1, Ix1)
-loadWithIx1 with (DWArray a@(DArray _ sz _) mWindow) uWrite = do
-  let Window it wk indexW _ = fromMaybe zeroWindow mWindow
+loadWithIx1 with (DWArray _ sz uIndex mWindow) uWrite = do
+  let Window it wk uwIndex _ = fromMaybe zeroWindow mWindow
       wEnd = it + unSz wk
-  with $ iterA_ 0 it 1 (<) $ \ !i -> uWrite i (unsafeIndex a i)
-  with $ iterA_ wEnd (unSz sz) 1 (<) $ \ !i -> uWrite i (unsafeIndex a i)
-  return (\from to -> with $ iterA_ from to 1 (<) $ \ !i -> uWrite i (indexW i), it, wEnd)
+  with $ iterA_ 0 it 1 (<) $ \ !i -> uWrite i (uIndex i)
+  with $ iterA_ wEnd (unSz sz) 1 (<) $ \ !i -> uWrite i (uIndex i)
+  return (\from to -> with $ iterA_ from to 1 (<) $ \ !i -> uWrite i (uwIndex i), it, wEnd)
 {-# INLINE loadWithIx1 #-}
 
 instance Index ix => Shape DW ix where
   maxLinearSize = Just . linearSize
   {-# INLINE maxLinearSize #-}
-  linearSize = SafeSz . totalElem . dSize . dwArray
+  linearSize = SafeSz . totalElem . dwSize
   {-# INLINE linearSize #-}
-  outerSize = dSize . dwArray
+  outerSize = dwSize
   {-# INLINE outerSize #-}
 
 instance Load DW Ix1 e where
-  makeArray c sz f = DWArray (makeArray c sz f) Nothing
+  makeArray c sz f = DWArray c sz f Nothing
   {-# INLINE makeArray #-}
   iterArrayLinearST_ scheduler arr uWrite = do
     (loadWindow, wStart, wEnd) <- loadWithIx1 (scheduleWork scheduler) arr uWrite
@@ -244,26 +255,26 @@
   {-# INLINE iterArrayLinearWithStrideST_ #-}
 
 loadArrayWithIx1
-  :: (Monad m)
+  :: Monad m
   => (m () -> m ())
   -> Array DW Ix1 e
   -> Stride Ix1
   -> Sz1
   -> (Ix1 -> e -> m a)
   -> m ((Ix1, Ix1) -> m (), (Ix1, Ix1))
-loadArrayWithIx1 with (DWArray darr@(DArray _ arrSz _) mWindow) stride _ uWrite = do
-  let Window it wk indexW _ = fromMaybe zeroWindow mWindow
+loadArrayWithIx1 with (DWArray _ arrSz uIndex mWindow) stride _ uWrite = do
+  let Window it wk uwIndex _ = fromMaybe zeroWindow mWindow
       wEnd = it + unSz wk
       strideIx = unStride stride
-  with $ iterA_ 0 it strideIx (<) $ \ !i -> uWrite (i `div` strideIx) (unsafeIndex darr i)
+  with $ iterA_ 0 it strideIx (<) $ \ !i -> uWrite (i `div` strideIx) (uIndex i)
   with $
     iterA_ (strideStart stride wEnd) (unSz arrSz) strideIx (<) $ \ !i ->
-      uWrite (i `div` strideIx) (unsafeIndex darr i)
+      uWrite (i `div` strideIx) (uIndex i)
   return
     ( \(from, to) ->
         with $
           iterA_ (strideStart stride from) to strideIx (<) $ \ !i ->
-            uWrite (i `div` strideIx) (indexW i)
+            uWrite (i `div` strideIx) (uwIndex i)
     , (it, wEnd)
     )
 {-# INLINE loadArrayWithIx1 #-}
@@ -275,16 +286,14 @@
   -> (Int -> t1 -> m ())
   -> m (Ix2 -> m (), Ix2)
 loadWithIx2 with arr uWrite = do
-  let DWArray darr window = arr
-      Sz (m :. n) = dSize darr
-      Window (it :. jt) (Sz (wm :. wn)) indexW mUnrollHeight = fromMaybe zeroWindow window
+  let DWArray _ (Sz (m :. n)) uIndex window = arr
+      Window (it :. jt) (Sz (wm :. wn)) uwIndex mUnrollHeight = fromMaybe zeroWindow window
       ib :. jb = (wm + it) :. (wn + jt)
       !blockHeight = maybe 1 (min 7 . max 1) mUnrollHeight
-      stride = oneStride
-      !sz = strideSize stride $ outerSize arr
-      writeB !ix = uWrite (toLinearIndex sz ix) (unsafeIndex darr ix)
+      !sz = strideSize oneStride $ outerSize arr
+      writeB !ix = uWrite (toLinearIndex sz ix) (uIndex ix)
       {-# INLINE writeB #-}
-      writeW !ix = uWrite (toLinearIndex sz ix) (indexW ix)
+      writeW !ix = uWrite (toLinearIndex sz ix) (uwIndex ix)
       {-# INLINE writeW #-}
   with $ iterA_ (0 :. 0) (it :. n) (1 :. 1) (<) writeB
   with $ iterA_ (ib :. 0) (m :. n) (1 :. 1) (<) writeB
@@ -304,15 +313,14 @@
   -> (Int -> e -> m ())
   -> m (Ix2 -> m (), Ix2)
 loadArrayWithIx2 with arr stride sz uWrite = do
-  let DWArray darr window = arr
-      Sz (m :. n) = dSize darr
-      Window (it :. jt) (Sz (wm :. wn)) indexW mUnrollHeight = fromMaybe zeroWindow window
+  let DWArray _ (Sz (m :. n)) uIndex window = arr
+      Window (it :. jt) (Sz (wm :. wn)) uwIndex mUnrollHeight = fromMaybe zeroWindow window
       ib :. jb = (wm + it) :. (wn + jt)
       !blockHeight = maybe 1 (min 7 . max 1) mUnrollHeight
       strideIx@(is :. js) = unStride stride
-      writeB !ix = uWrite (toLinearIndexStride stride sz ix) (unsafeIndex darr ix)
+      writeB !ix = uWrite (toLinearIndexStride stride sz ix) (uIndex ix)
       {-# INLINE writeB #-}
-      writeW !ix = uWrite (toLinearIndexStride stride sz ix) (indexW ix)
+      writeW !ix = uWrite (toLinearIndexStride stride sz ix) (uwIndex ix)
       {-# INLINE writeW #-}
   with $ iterA_ (0 :. 0) (it :. n) strideIx (<) writeB
   with $ iterA_ (strideStart stride (ib :. 0)) (m :. n) strideIx (<) writeB
@@ -340,7 +348,7 @@
 {-# INLINE loadWindowIx2 #-}
 
 instance Load DW Ix2 e where
-  makeArray c sz f = DWArray (makeArray c sz f) Nothing
+  makeArray c sz f = DWArray c sz f Nothing
   {-# INLINE makeArray #-}
   iterArrayLinearST_ scheduler arr uWrite =
     loadWithIx2 (scheduleWork scheduler) arr uWrite
@@ -354,7 +362,7 @@
   {-# INLINE iterArrayLinearWithStrideST_ #-}
 
 instance (Index (IxN n), Load DW (Ix (n - 1)) e) => Load DW (IxN n) e where
-  makeArray c sz f = DWArray (makeArray c sz f) Nothing
+  makeArray c sz f = DWArray c sz f Nothing
   {-# INLINE makeArray #-}
   iterArrayLinearST_ = loadWithIxN
   {-# INLINE iterArrayLinearST_ #-}
@@ -372,47 +380,53 @@
   -> (Int -> e -> ST s ())
   -> ST s ()
 loadArrayWithIxN scheduler stride szResult arr uWrite = do
-  let DWArray darr window = arr
+  let DWArray _ sz uIndex window = arr
       Window{windowStart, windowSize, windowIndex, windowUnrollIx2} = fromMaybe zeroWindow window
-      !(headSourceSize, lowerSourceSize) = unconsSz (dSize darr)
+      !(!headSourceSize, !lowerSourceSize) = unconsSz sz
       !lowerSize = snd $ unconsSz szResult
-      !(s, lowerStrideIx) = unconsDim $ unStride stride
-      !(curWindowStart, lowerWindowStart) = unconsDim windowStart
-      !(headWindowSz, tailWindowSz) = unconsSz windowSize
+      !(!s, !lowerStrideIx) = unconsDim $ unStride stride
+      !(!curWindowStart, lowerWindowStart) = unconsDim windowStart
+      !(!headWindowSz, tailWindowSz) = unconsSz windowSize
       !curWindowEnd = curWindowStart + unSz headWindowSz
       !pageElements = totalElem lowerSize
-      mkLowerWindow i =
+      lowerWindow =
         Window
           { windowStart = lowerWindowStart
           , windowSize = tailWindowSz
-          , windowIndex = windowIndex . consDim i
+          , windowIndex = \_ -> error "Window index uninitialized"
           , windowUnrollIx2 = windowUnrollIx2
           }
-      mkLowerArray mw i =
-        DWArray
-          { dwArray =
-              darr
-                { dComp = Seq
-                , dSize = lowerSourceSize
-                , dPrefIndex = PrefIndex (unsafeIndex darr . consDim i)
-                }
-          , dwWindow = ($ i) <$> mw
+      mkLowerWindow !i =
+        lowerWindow
+          { windowIndex = windowIndex . consDim i
           }
-      loadLower mw !i =
-        iterArrayLinearWithStrideST_
-          scheduler
-          (Stride lowerStrideIx)
-          lowerSize
-          (mkLowerArray mw i)
-          (\k -> uWrite (k + pageElements * (i `div` s)))
-      {-# NOINLINE loadLower #-}
-  loopA_ 0 (< headDim windowStart) (+ s) (loadLower Nothing)
+      loadLower mkWindow !i =
+        let !lowerArray =
+              DWArray
+                { dwComp = Seq
+                , dwSize = lowerSourceSize
+                , dwIndex = uIndex . consDim i
+                , dwWindow = mkWindow i
+                }
+            !innerScheduler =
+              if numWorkers scheduler <= unSz (strideSize (Stride s) headSourceSize)
+                then trivialScheduler_
+                else scheduler
+         in scheduleWork_ scheduler $
+              iterArrayLinearWithStrideST_ innerScheduler (Stride lowerStrideIx) lowerSize lowerArray $ \k ->
+                uWrite (k + pageElements * (i `div` s))
+      {-# INLINE loadLower #-}
+  loopA_ 0 (< headDim windowStart) (+ s) (loadLower (const Nothing))
   loopA_
     (strideStart (Stride s) curWindowStart)
     (< curWindowEnd)
     (+ s)
-    (loadLower (Just mkLowerWindow))
-  loopA_ (strideStart (Stride s) curWindowEnd) (< unSz headSourceSize) (+ s) (loadLower Nothing)
+    (loadLower (Just . mkLowerWindow))
+  loopA_
+    (strideStart (Stride s) curWindowEnd)
+    (< unSz headSourceSize)
+    (+ s)
+    (loadLower (const Nothing))
 {-# INLINE loadArrayWithIxN #-}
 
 loadWithIxN
@@ -422,38 +436,47 @@
   -> (Int -> e -> ST s ())
   -> ST s ()
 loadWithIxN scheduler arr uWrite = do
-  let DWArray darr window = arr
+  let DWArray _ sz uIndex window = arr
       Window{windowStart, windowSize, windowIndex, windowUnrollIx2} = fromMaybe zeroWindow window
-      !(si, szL) = unconsSz (dSize darr)
+      !(!si, !szL) = unconsSz sz
       !windowEnd = liftIndex2 (+) windowStart (unSz windowSize)
-      !(t, windowStartL) = unconsDim windowStart
+      !(!t, windowStartL) = unconsDim windowStart
       !pageElements = totalElem szL
-      mkLowerWindow i =
+      lowerWindow =
         Window
           { windowStart = windowStartL
           , windowSize = snd $ unconsSz windowSize
-          , windowIndex = windowIndex . consDim i
+          , windowIndex = \_ -> error "Window index uninitialized"
           , windowUnrollIx2 = windowUnrollIx2
           }
-      mkLowerArray mw i =
-        DWArray
-          { dwArray =
-              darr{dComp = Seq, dSize = szL, dPrefIndex = PrefIndex (unsafeIndex darr . consDim i)}
-          , dwWindow = ($ i) <$> mw
+      mkLowerWindow !i =
+        lowerWindow
+          { windowIndex = windowIndex . consDim i
           }
-      loadLower mw !i =
-        scheduleWork_ scheduler $
-          iterArrayLinearST_ scheduler (mkLowerArray mw i) (\k -> uWrite (k + pageElements * i))
-      {-# NOINLINE loadLower #-}
-  loopA_ 0 (< headDim windowStart) (+ 1) (loadLower Nothing)
-  loopA_ t (< headDim windowEnd) (+ 1) (loadLower (Just mkLowerWindow))
-  loopA_ (headDim windowEnd) (< unSz si) (+ 1) (loadLower Nothing)
+      loadLower mkWindow !i =
+        let !lowerArray =
+              DWArray
+                { dwComp = Seq
+                , dwSize = szL
+                , dwIndex = uIndex . consDim i
+                , dwWindow = mkWindow i
+                }
+            !innerScheduler =
+              if numWorkers scheduler <= unSz si
+                then trivialScheduler_
+                else scheduler
+         in scheduleWork_ scheduler $
+              iterArrayLinearST_ innerScheduler lowerArray (\k -> uWrite (k + pageElements * i))
+      {-# INLINE loadLower #-}
+  loopA_ 0 (< headDim windowStart) (+ 1) (loadLower (const Nothing))
+  loopA_ t (< headDim windowEnd) (+ 1) (loadLower (Just . mkLowerWindow))
+  loopA_ (headDim windowEnd) (< unSz si) (+ 1) (loadLower (const Nothing))
 {-# INLINE loadWithIxN #-}
 
 unrollAndJam
   :: Monad m
   => Int
-  -- ^ Block height
+  -- ^ Block height. Must not be zero.
   -> Ix2
   -- ^ Top corner
   -> Ix2
@@ -464,21 +487,22 @@
   -- ^ Writing function
   -> m ()
 unrollAndJam !bH (it :. jt) (ib :. jb) js f = do
-  let f2 (i :. j) = f (i :. j) >> f ((i + 1) :. j)
-  let f3 (i :. j) = f (i :. j) >> f2 ((i + 1) :. j)
-  let f4 (i :. j) = f (i :. j) >> f3 ((i + 1) :. j)
-  let f5 (i :. j) = f (i :. j) >> f4 ((i + 1) :. j)
-  let f6 (i :. j) = f (i :. j) >> f5 ((i + 1) :. j)
-  let f7 (i :. j) = f (i :. j) >> f6 ((i + 1) :. j)
-  let f' = case bH of
-        1 -> f
-        2 -> f2
-        3 -> f3
-        4 -> f4
-        5 -> f5
-        6 -> f6
-        _ -> f7
-  let !ibS = ib - ((ib - it) `mod` bH)
+  let
+    f2 (i :. j) = f (i :. j) >> f ((i + 1) :. j)
+    f3 (i :. j) = f (i :. j) >> f2 ((i + 1) :. j)
+    f4 (i :. j) = f (i :. j) >> f3 ((i + 1) :. j)
+    f5 (i :. j) = f (i :. j) >> f4 ((i + 1) :. j)
+    f6 (i :. j) = f (i :. j) >> f5 ((i + 1) :. j)
+    f7 (i :. j) = f (i :. j) >> f6 ((i + 1) :. j)
+    f' = case bH of
+      1 -> f
+      2 -> f2
+      3 -> f3
+      4 -> f4
+      5 -> f5
+      6 -> f6
+      _ -> f7
+    !ibS = ib - ((ib - it) `modInt` bH)
   loopA_ it (< ibS) (+ bH) $ \ !i ->
     loopA_ jt (< jb) (+ js) $ \ !j ->
       f' (i :. j)
diff --git a/src/Data/Massiv/Array/Manifest.hs b/src/Data/Massiv/Array/Manifest.hs
--- a/src/Data/Massiv/Array/Manifest.hs
+++ b/src/Data/Massiv/Array/Manifest.hs
@@ -6,6 +6,7 @@
 {-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
+
 -- |
 -- Module      : Data.Massiv.Array.Manifest
 -- Copyright   : (c) Alexey Kuleshevich 2018-2022
@@ -13,125 +14,145 @@
 -- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
 -- Stability   : experimental
 -- Portability : non-portable
---
-module Data.Massiv.Array.Manifest
-  ( -- * Manifest
-    Manifest
+module Data.Massiv.Array.Manifest (
+  -- * Manifest
+  Manifest,
+
   -- ** Generate
-  , generateArray
-  , generateArrayLinear
-  , generateArrayS
-  , generateArrayLinearS
-  , generateSplitSeedArray
+  generateArray,
+  generateArrayLinear,
+  generateArrayS,
+  generateArrayLinearS,
+  generateSplitSeedArray,
+
   -- ** Stateful worker threads
-  , generateArrayWS
-  , generateArrayLinearWS
+  generateArrayWS,
+  generateArrayLinearWS,
+
   -- ** Unfold
-  , unfoldrPrimM_
-  , iunfoldrPrimM_
-  , unfoldrPrimM
-  , iunfoldrPrimM
-  , unfoldlPrimM_
-  , iunfoldlPrimM_
-  , unfoldlPrimM
-  , iunfoldlPrimM
+  unfoldrPrimM_,
+  iunfoldrPrimM_,
+  unfoldrPrimM,
+  iunfoldrPrimM,
+  unfoldlPrimM_,
+  iunfoldlPrimM_,
+  unfoldlPrimM,
+  iunfoldlPrimM,
+
   -- ** Mapping
-  , forPrimM
-  , forPrimM_
-  , iforPrimM
-  , iforPrimM_
-  , iforLinearPrimM
-  , iforLinearPrimM_
-  , for2PrimM_
-  , ifor2PrimM_
+  forPrimM,
+  forPrimM_,
+  iforPrimM,
+  iforPrimM_,
+  iforLinearPrimM,
+  iforLinearPrimM_,
+  for2PrimM_,
+  ifor2PrimM_,
+
   -- * Boxed
-  , B(..)
-  , BL(..)
-  , BN(..)
-  , N
-  , pattern N
-  , Uninitialized(..)
+  B (..),
+  BL (..),
+  BN (..),
+  N,
+  pattern N,
+  Uninitialized (..),
+
   -- ** Access
-  , findIndex
+  findIndex,
+
   -- ** Conversion
   -- $boxed_conversion_note
-  , toLazyArray
-  , evalLazyArray
-  , forceLazyArray
-  , unwrapNormalForm
-  , evalNormalForm
+  toLazyArray,
+  evalLazyArray,
+  forceLazyArray,
+  unwrapNormalForm,
+  evalNormalForm,
+
   -- *** Primitive Boxed Array
-  , unwrapLazyArray
-  , wrapLazyArray
-  , unwrapArray
-  , evalArray
-  , unwrapMutableArray
-  , unwrapMutableLazyArray
-  , evalMutableArray
-  , unwrapNormalFormArray
-  , evalNormalFormArray
-  , unwrapNormalFormMutableArray
-  , evalNormalFormMutableArray
+  unwrapLazyArray,
+  wrapLazyArray,
+  unwrapArray,
+  evalArray,
+  unwrapMutableArray,
+  unwrapMutableLazyArray,
+  evalMutableArray,
+  unwrapNormalFormArray,
+  evalNormalFormArray,
+  unwrapNormalFormMutableArray,
+  evalNormalFormMutableArray,
+
   -- *** Boxed Vector
-  , toBoxedVector
-  , toBoxedMVector
-  , fromBoxedVector
-  , fromBoxedMVector
-  , evalBoxedVector
-  , evalBoxedMVector
+  toBoxedVector,
+  toBoxedMVector,
+  fromBoxedVector,
+  fromBoxedMVector,
+  evalBoxedVector,
+  evalBoxedMVector,
+
   -- * Primitive
-  , P(..)
-  , Prim
+  P (..),
+  Prim,
+
   -- ** Conversion
+
   -- *** Primitive ByteArray
-  , toByteArray
-  , toByteArrayM
-  , unwrapByteArray
-  , unwrapByteArrayOffset
-  , fromByteArray
-  , fromByteArrayM
-  , fromByteArrayOffsetM
-  , toMutableByteArray
-  , unwrapMutableByteArray
-  , unwrapMutableByteArrayOffset
-  , fromMutableByteArray
-  , fromMutableByteArrayM
-  , fromMutableByteArrayOffsetM
+  toByteArray,
+  toByteArrayM,
+  unwrapByteArray,
+  unwrapByteArrayOffset,
+  fromByteArray,
+  fromByteArrayM,
+  fromByteArrayOffsetM,
+  toMutableByteArray,
+  unwrapMutableByteArray,
+  unwrapMutableByteArrayOffset,
+  fromMutableByteArray,
+  fromMutableByteArrayM,
+  fromMutableByteArrayOffsetM,
+
   -- *** Primitive Vector
-  , toPrimitiveVector
-  , toPrimitiveMVector
-  , fromPrimitiveVector
-  , fromPrimitiveMVector
+  toPrimitiveVector,
+  toPrimitiveMVector,
+  fromPrimitiveVector,
+  fromPrimitiveMVector,
+
   -- * Storable
-  , S(..)
-  , Storable
-  , mallocCompute
-  , mallocCopy
+  S (..),
+  Storable,
+  mallocCompute,
+  mallocCopy,
+
   -- ** Conversion
+
   -- *** Storable Vector
-  , toStorableVector
-  , toStorableMVector
-  , fromStorableVector
-  , fromStorableMVector
+  toStorableVector,
+  toStorableMVector,
+  fromStorableVector,
+  fromStorableMVector,
+
   -- *** Direct Pointer Access
-  , withPtr
+  withPtr,
+
   -- * Unboxed
-  , U(..)
-  , Unbox
+  U (..),
+  Unbox,
+
   -- ** Conversion
+
   -- *** Unboxed Vector
-  , toUnboxedVector
-  , toUnboxedMVector
-  , fromUnboxedVector
-  , fromUnboxedMVector
+  toUnboxedVector,
+  toUnboxedMVector,
+  fromUnboxedVector,
+  fromUnboxedMVector,
+
   -- * ByteString Conversion
-  , fromByteString
-  , castFromByteString
-  , toByteString
-  , castToByteString
-  , toBuilder
-  , castToBuilder
-  ) where
+  fromByteString,
+  castFromByteString,
+  toByteString,
+  castToByteString,
+  toBuilder,
+  castToBuilder,
+) where
 
 import Control.Monad
 import Data.ByteString as S hiding (findIndex)
@@ -152,14 +173,17 @@
 -- doesn't match the total number of elements of new array.
 --
 -- @since 0.2.1
-fromByteString ::
-     Load r Ix1 Word8
-  => Comp -- ^ Computation strategy
-  -> ByteString -- ^ Strict ByteString to use as a source.
+fromByteString
+  :: Load r Ix1 Word8
+  => Comp
+  -- ^ Computation strategy
+  -> ByteString
+  -- ^ Strict ByteString to use as a source.
   -> Vector r Word8
 fromByteString comp bs = makeArrayLinear comp (SafeSz (S.length bs)) (SU.unsafeIndex bs)
 {-# INLINE fromByteString #-}
 
+{- FOURMOLU_DISABLE -}
 -- | /O(n)/ - Convert any source array into a strict `ByteString`. In case when the source array is
 -- actually storable, no memory copy will occur.
 --
@@ -176,6 +200,7 @@
   compute
 #endif
 {-# INLINE toByteString #-}
+{- FOURMOLU_ENABLE -}
 
 -- | /O(n)/ - Conversion of array monoidally into a ByteString `Builder`.
 --
@@ -212,8 +237,6 @@
 -- kept as the same array. Conversion to Massiv boxed array will undergo evaluation during which
 -- computation strategies will be respected.
 
-
-
 -- | /O(n)/ - Perform a row-major search starting at @0@ for an element. Returns the index
 -- of the first occurance of an element or `Nothing` if a predicate could not be satisifed
 -- after it was applyied to all elements of the array.
@@ -231,13 +254,13 @@
         else go (i + 1)
 {-# INLINE findIndex #-}
 
-
 -- | Very similar to @`computeAs` `S`@ except load the source array into memory allocated
 -- with @malloc@ on C heap. It can potentially be useful when iteroperating with some C
 -- programs.
 --
 -- @since 0.5.9
-mallocCompute :: forall r ix e. (Size r, Load r ix e, Storable e) => Array r ix e -> IO (Array S ix e)
+mallocCompute
+  :: forall r ix e. (Size r, Load r ix e, Storable e) => Array r ix e -> IO (Array S ix e)
 mallocCompute arr = do
   let sz = size arr
   marr <- unsafeMallocMArray sz
diff --git a/src/Data/Massiv/Array/Manifest/Boxed.hs b/src/Data/Massiv/Array/Manifest/Boxed.hs
--- a/src/Data/Massiv/Array/Manifest/Boxed.hs
+++ b/src/Data/Massiv/Array/Manifest/Boxed.hs
@@ -1,4 +1,3 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
@@ -9,6 +8,8 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
 -- |
 -- Module      : Data.Massiv.Array.Manifest.Boxed
 -- Copyright   : (c) Alexey Kuleshevich 2018-2022
@@ -16,50 +17,49 @@
 -- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
 -- Stability   : experimental
 -- Portability : non-portable
---
-module Data.Massiv.Array.Manifest.Boxed
-  ( B(..)
-  , BL(..)
-  , BN(..)
-  , N
-  , pattern N
-  , Array(..)
-  , MArray(..)
-  , wrapLazyArray
-  , unwrapLazyArray
-  , unwrapNormalForm
-  , evalNormalForm
-  , unwrapArray
-  , evalArray
-  , toLazyArray
-  , evalLazyArray
-  , forceLazyArray
-  , unwrapMutableArray
-  , unwrapMutableLazyArray
-  , evalMutableArray
-  , unwrapNormalFormArray
-  , evalNormalFormArray
-  , unwrapNormalFormMutableArray
-  , evalNormalFormMutableArray
-  , toBoxedVector
-  , toBoxedMVector
-  , fromBoxedVector
-  , fromBoxedMVector
-  , evalBoxedVector
-  , evalBoxedMVector
-  , evalNormalBoxedVector
-  , evalNormalBoxedMVector
-  , coerceBoxedArray
-  , coerceNormalBoxedArray
-  , seqArray
-  , deepseqArray
-  ) where
+module Data.Massiv.Array.Manifest.Boxed (
+  B (..),
+  BL (..),
+  BN (..),
+  N,
+  pattern N,
+  Array (..),
+  MArray (..),
+  wrapLazyArray,
+  unwrapLazyArray,
+  unwrapNormalForm,
+  evalNormalForm,
+  unwrapArray,
+  evalArray,
+  toLazyArray,
+  evalLazyArray,
+  forceLazyArray,
+  unwrapMutableArray,
+  unwrapMutableLazyArray,
+  evalMutableArray,
+  unwrapNormalFormArray,
+  evalNormalFormArray,
+  unwrapNormalFormMutableArray,
+  evalNormalFormMutableArray,
+  toBoxedVector,
+  toBoxedMVector,
+  fromBoxedVector,
+  fromBoxedMVector,
+  evalBoxedVector,
+  evalBoxedMVector,
+  evalNormalBoxedVector,
+  evalNormalBoxedMVector,
+  coerceBoxedArray,
+  coerceNormalBoxedArray,
+  seqArray,
+  deepseqArray,
+) where
 
-import Control.DeepSeq (NFData(..), deepseq)
+import Control.DeepSeq (NFData (..), deepseq)
 import Control.Exception
 import Control.Monad ((>=>))
 import Control.Monad.Primitive
-import qualified Data.Foldable as F (Foldable(..))
+import qualified Data.Foldable as F (Foldable (..))
 import Data.Massiv.Array.Delayed.Pull (D)
 import Data.Massiv.Array.Delayed.Push (DL)
 import Data.Massiv.Array.Delayed.Stream (DS)
@@ -77,8 +77,8 @@
 import qualified Data.Vector as VB
 import qualified Data.Vector.Mutable as MVB
 import GHC.Exts as GHC
-import Prelude hiding (mapM, replicate)
 import System.IO.Unsafe (unsafePerformIO)
+import Prelude hiding (mapM, replicate)
 #if !MIN_VERSION_vector(0,13,0)
 import Unsafe.Coerce (unsafeCoerce)
 #endif
@@ -112,17 +112,18 @@
 -- 30414093201713378043612608166064768844377641568960512000000000000
 -- >>> length $ show $ fact 5000
 -- 16326
---
-data BL = BL deriving Show
+data BL = BL deriving (Show)
 
-data instance Array BL ix e = BLArray { blComp   :: !Comp
-                                      , blSize   :: !(Sz ix)
-                                      , blOffset :: {-# UNPACK #-} !Int
-                                      , blData   :: {-# UNPACK #-} !(A.Array e)
-                                      }
-data instance MArray s BL ix e =
-  MBLArray !(Sz ix) {-# UNPACK #-} !Int {-# UNPACK #-} !(A.MutableArray s e)
+data instance Array BL ix e = BLArray
+  { blComp :: !Comp
+  , blSize :: !(Sz ix)
+  , blOffset :: {-# UNPACK #-} !Int
+  , blData :: {-# UNPACK #-} !(A.Array e)
+  }
 
+data instance MArray s BL ix e
+  = MBLArray !(Sz ix) {-# UNPACK #-} !Int {-# UNPACK #-} !(A.MutableArray s e)
+
 instance (Ragged L ix e, Show e) => Show (Array BL ix e) where
   showsPrec = showsArrayPrec id
   showList = showArrayList
@@ -135,7 +136,6 @@
   showsPrec = showsArrayPrec (computeAs BL)
   showList = showArrayList
 
-
 instance (Index ix, NFData e) => NFData (Array BL ix e) where
   rnf = (`deepseqArray` ())
   {-# INLINE rnf #-}
@@ -149,13 +149,12 @@
   {-# INLINE compare #-}
 
 instance Strategy BL where
-  setComp c arr = arr { blComp = c }
+  setComp c arr = arr{blComp = c}
   {-# INLINE setComp #-}
   getComp = blComp
   {-# INLINE getComp #-}
   repr = BL
 
-
 instance Source BL e where
   unsafeLinearIndex (BLArray _ _sz o a) i =
     indexAssert "BL.unsafeLinearIndex" (SafeSz . A.sizeofArray) A.indexArray a (i + o)
@@ -168,7 +167,6 @@
   {-# INLINE unsafeLinearSlice #-}
 
 instance Manifest BL e where
-
   unsafeLinearIndexM (BLArray _ _sz o a) i =
     indexAssert "BL.unsafeLinearIndexM" (SafeSz . A.sizeofArray) A.indexArray a (i + o)
   {-# INLINE unsafeLinearIndexM #-}
@@ -208,10 +206,9 @@
 instance Size BL where
   size = blSize
   {-# INLINE size #-}
-  unsafeResize !sz !arr = arr { blSize = sz }
+  unsafeResize !sz !arr = arr{blSize = sz}
   {-# INLINE unsafeResize #-}
 
-
 instance Index ix => Shape BL ix where
   maxLinearSize = Just . SafeSz . elemsCount
   {-# INLINE maxLinearSize #-}
@@ -238,7 +235,6 @@
   toStreamIx = S.isteps
   {-# INLINE toStreamIx #-}
 
-
 -- | Row-major sequential folding over a Boxed array.
 instance Index ix => Foldable (Array BL ix) where
   fold = fold
@@ -257,10 +253,9 @@
   {-# INLINE null #-}
   length = totalElem . size
   {-# INLINE length #-}
-  toList arr = build (\ c n -> foldrFB c n arr)
+  toList arr = build (\c n -> foldrFB c n arr)
   {-# INLINE toList #-}
 
-
 instance Index ix => Functor (Array BL ix) where
   fmap f arr = makeArrayLinear (blComp arr) (blSize arr) (f . unsafeLinearIndex arr)
   {-# INLINE fmap #-}
@@ -292,15 +287,13 @@
   unsafeLiftArray2 = defaultUnsafeLiftArray2
   {-# INLINE unsafeLiftArray2 #-}
 
-
-
 ------------------
 -- Boxed Strict --
 ------------------
 
 -- | Array representation for Boxed elements. Its elements are strict to Weak
 -- Head Normal Form (WHNF) only.
-data B = B deriving Show
+data B = B deriving (Show)
 
 newtype instance Array B ix e = BArray (Array BL ix e)
 
@@ -322,7 +315,6 @@
   compare = compareArrays compare
   {-# INLINE compare #-}
 
-
 instance Source B e where
   unsafeLinearIndex arr = unsafeLinearIndex (toLazyArray arr)
   {-# INLINE unsafeLinearIndex #-}
@@ -336,11 +328,10 @@
 instance Strategy B where
   getComp = blComp . coerce
   {-# INLINE getComp #-}
-  setComp c arr = coerceBoxedArray (coerce arr) { blComp = c }
+  setComp c arr = coerceBoxedArray (coerce arr){blComp = c}
   {-# INLINE setComp #-}
   repr = B
 
-
 instance Index ix => Shape B ix where
   maxLinearSize = Just . SafeSz . elemsCount
   {-# INLINE maxLinearSize #-}
@@ -348,12 +339,10 @@
 instance Size B where
   size = blSize . coerce
   {-# INLINE size #-}
-  unsafeResize sz = coerce (\arr -> arr { blSize = sz })
+  unsafeResize sz = coerce (\arr -> arr{blSize = sz})
   {-# INLINE unsafeResize #-}
 
-
 instance Manifest B e where
-
   unsafeLinearIndexM = coerce unsafeLinearIndexM
   {-# INLINE unsafeLinearIndexM #-}
 
@@ -408,7 +397,6 @@
   toStreamIx = S.isteps
   {-# INLINE toStreamIx #-}
 
-
 -- | Row-major sequential folding over a Boxed array.
 instance Index ix => Foldable (Array B ix) where
   fold = fold
@@ -427,10 +415,9 @@
   {-# INLINE null #-}
   length = totalElem . size
   {-# INLINE length #-}
-  toList arr = build (\ c n -> foldrFB c n arr)
+  toList arr = build (\c n -> foldrFB c n arr)
   {-# INLINE toList #-}
 
-
 instance Index ix => Functor (Array B ix) where
   fmap f arr = makeArrayLinear (getComp arr) (size arr) (f . unsafeLinearIndex arr)
   {-# INLINE fmap #-}
@@ -466,21 +453,25 @@
 -- Boxed Normal Form --
 -----------------------
 
-  -- | Array representation for Boxed elements. Its elements are always in Normal
+-- | Array representation for Boxed elements. Its elements are always in Normal
 -- Form (NF), therefore `NFData` instance is required.
-data BN = BN deriving Show
+data BN = BN deriving (Show)
 
 -- | Type and pattern `N` have been added for backwards compatibility and will be replaced
 -- in the future in favor of `BN`.
 --
 -- /Deprecated/ - since 1.0.0
 type N = BN
+
 pattern N :: N
 pattern N = BN
+
 {-# COMPLETE N #-}
+
 {-# DEPRECATED N "In favor of more consistently named `BN`" #-}
 
 newtype instance Array BN ix e = BNArray (Array BL ix e)
+
 newtype instance MArray s BN ix e = MBNArray (MArray s BL ix e)
 
 instance (Ragged L ix e, Show e, NFData e) => Show (Array BN ix e) where
@@ -515,7 +506,6 @@
   unsafeOuterSlice (BNArray a) i = coerce (unsafeOuterSlice a i)
   {-# INLINE unsafeOuterSlice #-}
 
-
 instance Index ix => Shape BN ix where
   maxLinearSize = Just . SafeSz . elemsCount
   {-# INLINE maxLinearSize #-}
@@ -580,7 +570,6 @@
   toStreamIx = toStreamIx . coerce
   {-# INLINE toStreamIx #-}
 
-
 instance (NFData e, IsList (Array L ix e), Ragged L ix e) => IsList (Array BN ix e) where
   type Item (Array BN ix e) = Item (Array L ix e)
   fromList = L.fromLists' Seq
@@ -624,14 +613,15 @@
 -- | /O(n)/ - Wrap a boxed array and evaluate all elements to a WHNF.
 --
 -- @since 0.2.1
-evalArray ::
-     Comp -- ^ Computation strategy
-  -> A.Array e -- ^ Lazy boxed array from @primitive@ package.
+evalArray
+  :: Comp
+  -- ^ Computation strategy
+  -> A.Array e
+  -- ^ Lazy boxed array from @primitive@ package.
   -> Vector B e
 evalArray comp a = evalLazyArray $ setComp comp $ wrapLazyArray a
 {-# INLINE evalArray #-}
 
-
 -- | /O(1)/ - Unwrap boxed array. This will discard any possible slicing that has been
 -- applied to the array.
 --
@@ -647,7 +637,6 @@
 wrapLazyArray a = BLArray Seq (SafeSz (A.sizeofArray a)) 0 a
 {-# INLINE wrapLazyArray #-}
 
-
 -- | /O(1)/ - Cast a strict boxed array into a lazy boxed array.
 --
 -- @since 0.6.0
@@ -677,7 +666,6 @@
 unwrapMutableArray (MBArray (MBLArray _ _ marr)) = marr
 {-# INLINE unwrapMutableArray #-}
 
-
 -- | /O(1)/ - Unwrap mutable boxed lazy array. This will discard any possible slicing that has been
 -- applied to the array.
 --
@@ -686,13 +674,13 @@
 unwrapMutableLazyArray (MBLArray _ _ marr) = marr
 {-# INLINE unwrapMutableLazyArray #-}
 
-
 -- | /O(n)/ - Wrap mutable boxed array and evaluate all elements to WHNF.
 --
 -- @since 0.2.1
-evalMutableArray ::
-     PrimMonad m
-  => A.MutableArray (PrimState m) e -- ^ Mutable array that will get wrapped
+evalMutableArray
+  :: PrimMonad m
+  => A.MutableArray (PrimState m) e
+  -- ^ Mutable array that will get wrapped
   -> m (MArray (PrimState m) B Ix1 e)
 evalMutableArray = fmap MBArray . fromMutableArraySeq seq
 {-# INLINE evalMutableArray #-}
@@ -712,15 +700,16 @@
 -- | /O(n)/ - Wrap a boxed array and evaluate all elements to a Normal Form (NF).
 --
 -- @since 0.2.1
-evalNormalFormArray ::
-     NFData e
-  => Comp -- ^ Computation strategy
-  -> A.Array e -- ^ Lazy boxed array
+evalNormalFormArray
+  :: NFData e
+  => Comp
+  -- ^ Computation strategy
+  -> A.Array e
+  -- ^ Lazy boxed array
   -> Array N Ix1 e
 evalNormalFormArray comp = forceLazyArray . setComp comp . wrapLazyArray
 {-# INLINE evalNormalFormArray #-}
 
-
 -- | /O(1)/ - Unwrap a fully evaluated mutable boxed array. This will discard any possible
 -- slicing that has been applied to the array.
 --
@@ -729,24 +718,22 @@
 unwrapNormalFormMutableArray = unwrapMutableLazyArray . coerce
 {-# INLINE unwrapNormalFormMutableArray #-}
 
-
 -- | /O(n)/ - Wrap mutable boxed array and evaluate all elements to NF.
 --
 -- @since 0.2.1
-evalNormalFormMutableArray ::
-     (PrimMonad m, NFData e)
+evalNormalFormMutableArray
+  :: (PrimMonad m, NFData e)
   => A.MutableArray (PrimState m) e
   -> m (MArray (PrimState m) N Ix1 e)
 evalNormalFormMutableArray marr = MBNArray <$> fromMutableArraySeq deepseq marr
 {-# INLINE evalNormalFormMutableArray #-}
 
-
 ----------------------
 -- Helper functions --
 ----------------------
 
-fromMutableArraySeq ::
-     PrimMonad m
+fromMutableArraySeq
+  :: PrimMonad m
   => (e -> m () -> m a)
   -> A.MutableArray (PrimState m) e
   -> m (MArray (PrimState m) BL Ix1 e)
@@ -756,17 +743,14 @@
   return $! MBLArray (SafeSz sz) 0 ma
 {-# INLINE fromMutableArraySeq #-}
 
-
 seqArray :: Index ix => Array BL ix a -> t -> t
 seqArray !arr t = foldlInternal (flip seq) () (flip seq) () arr `seq` t
 {-# INLINE seqArray #-}
 
-
 deepseqArray :: (NFData a, Index ix) => Array BL ix a -> t -> t
 deepseqArray !arr t = foldlInternal (flip deepseq) () (flip seq) () arr `seq` t
 {-# INLINE deepseqArray #-}
 
-
 -- | /O(1)/ - Converts array from `N` to `B` representation.
 --
 -- @since 0.5.0
@@ -781,6 +765,7 @@
 evalNormalForm (BArray arr) = arr `deepseqArray` BNArray arr
 {-# INLINE evalNormalForm #-}
 
+{- FOURMOLU_DISABLE -}
 -- | /O(1)/ - Converts a boxed `Array` into a `VB.Vector` without touching any
 -- elements.
 --
@@ -798,8 +783,7 @@
 fromVectorCast :: VectorCast a -> VB.Vector a
 fromVectorCast = unsafeCoerce
 #endif
-
-
+{- FOURMOLU_ENABLE -}
 
 -- | /O(1)/ - Converts a boxed `MArray` into a `MVB.MVector`.
 --
@@ -816,7 +800,6 @@
 evalBoxedVector comp = evalLazyArray . setComp comp . fromBoxedVector
 {-# INLINE evalBoxedVector #-}
 
-
 -- | /O(n)/ - Convert mutable boxed vector and evaluate all elements to WHNF
 -- sequentially. Both keep pointing to the same memory
 --
@@ -827,14 +810,13 @@
    in marr <$ loopA_ o (< k) (+ 1) (A.readArray ma >=> (`seq` pure ()))
 {-# INLINE evalBoxedMVector #-}
 
-
 -- | /O(1)/ - Cast a boxed vector without touching any elements.
 --
 -- @since 0.6.0
 fromBoxedVector :: VB.Vector a -> Vector BL a
 {-# INLINE fromBoxedVector #-}
 fromBoxedVector v =
-  BLArray {blComp = Seq, blSize = SafeSz n, blOffset = offset, blData = arr}
+  BLArray{blComp = Seq, blSize = SafeSz n, blOffset = offset, blData = arr}
   where
 #if MIN_VERSION_vector(0,13,0)
     (arr, offset, n) = VB.toArraySlice v
@@ -850,7 +832,6 @@
 toVectorCast = unsafeCoerce
 #endif
 
-
 -- | /O(1)/ - Convert mutable boxed vector to a lazy mutable boxed array. Both keep
 -- pointing to the same memory
 --
@@ -859,7 +840,6 @@
 fromBoxedMVector (MVB.MVector o k ma) = MBLArray (SafeSz k) o ma
 {-# INLINE fromBoxedMVector #-}
 
-
 -- | /O(1)/ - Cast a boxed lazy array. It is unsafe because it can violate the invariant
 -- that all elements of `N` array are in NF.
 --
@@ -868,7 +848,6 @@
 coerceNormalBoxedArray = coerce
 {-# INLINE coerceNormalBoxedArray #-}
 
-
 -- | /O(1)/ - Cast a boxed lazy array. It is unsafe because it can violate the invariant
 -- that all elements of `B` array are in WHNF.
 --
@@ -881,8 +860,8 @@
 -- sequentially. Both keep pointing to the same memory
 --
 -- @since 0.5.0
-evalNormalBoxedMVector ::
-     (NFData a, PrimMonad m) => MVB.MVector (PrimState m) a -> m (MArray (PrimState m) N Ix1 a)
+evalNormalBoxedMVector
+  :: (NFData a, PrimMonad m) => MVB.MVector (PrimState m) a -> m (MArray (PrimState m) N Ix1 a)
 evalNormalBoxedMVector (MVB.MVector o k ma) =
   let marr = MBNArray (MBLArray (SafeSz k) o ma)
    in marr <$ loopA_ o (< k) (+ 1) (A.readArray ma >=> pure . rnf)
@@ -898,4 +877,3 @@
     MVB.MVector o k ma <- VB.unsafeThaw v
     forceLazyArray <$> unsafeFreeze comp (MBLArray (SafeSz k) o ma)
 {-# INLINE evalNormalBoxedVector #-}
-
diff --git a/src/Data/Massiv/Array/Manifest/Storable.hs b/src/Data/Massiv/Array/Manifest/Storable.hs
--- a/src/Data/Massiv/Array/Manifest/Storable.hs
+++ b/src/Data/Massiv/Array/Manifest/Storable.hs
@@ -50,6 +50,9 @@
 import Data.Massiv.Vector.Stream as S (isteps, steps)
 import Data.Primitive.ByteArray
 import Data.Primitive.Ptr (setPtr)
+import qualified Data.Vector.Generic.Mutable as MVG
+import qualified Data.Vector.Storable as VS
+import qualified Data.Vector.Storable.Mutable as MVS
 import Data.Word
 import Foreign.ForeignPtr
 import Foreign.Marshal.Alloc
@@ -61,10 +64,6 @@
 import System.IO.Unsafe (unsafePerformIO)
 import Unsafe.Coerce
 import Prelude hiding (mapM)
-
-import qualified Data.Vector.Generic.Mutable as MVG
-import qualified Data.Vector.Storable as VS
-import qualified Data.Vector.Storable.Mutable as MVS
 
 -- | Representation for `Storable` elements
 data S = S deriving (Show)
diff --git a/src/Data/Massiv/Array/Manifest/Unboxed.hs b/src/Data/Massiv/Array/Manifest/Unboxed.hs
--- a/src/Data/Massiv/Array/Manifest/Unboxed.hs
+++ b/src/Data/Massiv/Array/Manifest/Unboxed.hs
@@ -50,6 +50,7 @@
   , uSize :: !(Sz ix)
   , uData :: !(VU.Vector e)
   }
+
 data instance MArray s U ix e = MUArray !(Sz ix) !(VU.MVector s e)
 
 instance (Ragged L ix e, Show e, Unbox e) => Show (Array U ix e) where
diff --git a/src/Data/Massiv/Array/Mutable.hs b/src/Data/Massiv/Array/Mutable.hs
--- a/src/Data/Massiv/Array/Mutable.hs
+++ b/src/Data/Massiv/Array/Mutable.hs
@@ -291,7 +291,8 @@
 --   ]
 --
 -- @since 0.1.0
-thaw :: forall r ix e m. (Manifest r e, Index ix, MonadIO m) => Array r ix e -> m (MArray RealWorld r ix e)
+thaw
+  :: forall r ix e m. (Manifest r e, Index ix, MonadIO m) => Array r ix e -> m (MArray RealWorld r ix e)
 thaw arr =
   liftIO $ do
     let sz = size arr
@@ -982,7 +983,8 @@
 -- action to it. There is no mutation to the array, unless the action itself modifies it.
 --
 -- @since 0.4.0
-forPrimM_ :: (Manifest r e, Index ix, PrimMonad m) => MArray (PrimState m) r ix e -> (e -> m ()) -> m ()
+forPrimM_
+  :: (Manifest r e, Index ix, PrimMonad m) => MArray (PrimState m) r ix e -> (e -> m ()) -> m ()
 forPrimM_ marr f =
   loopA_ 0 (< totalElem (sizeOfMArray marr)) (+ 1) (unsafeLinearRead marr >=> f)
 {-# INLINE forPrimM_ #-}
@@ -990,7 +992,8 @@
 -- | Sequentially loop over a mutable array while modifying each element with an action.
 --
 -- @since 0.4.0
-forPrimM :: (Manifest r e, Index ix, PrimMonad m) => MArray (PrimState m) r ix e -> (e -> m e) -> m ()
+forPrimM
+  :: (Manifest r e, Index ix, PrimMonad m) => MArray (PrimState m) r ix e -> (e -> m e) -> m ()
 forPrimM marr f =
   loopA_ 0 (< totalElem (sizeOfMArray marr)) (+ 1) (unsafeLinearModify marr f)
 {-# INLINE forPrimM #-}
@@ -1278,7 +1281,8 @@
 --
 -- @since 0.4.0
 writeM
-  :: (Manifest r e, Index ix, PrimMonad m, MonadThrow m) => MArray (PrimState m) r ix e -> ix -> e -> m ()
+  :: (Manifest r e, Index ix, PrimMonad m, MonadThrow m)
+  => MArray (PrimState m) r ix e -> ix -> e -> m ()
 writeM marr ix e =
   write marr ix e >>= (`unless` throwM (IndexOutOfBoundsException (sizeOfMArray marr) ix))
 {-# INLINE writeM #-}
@@ -1367,7 +1371,8 @@
 -- otherwise.
 --
 -- @since 0.1.0
-swap :: (Manifest r e, Index ix, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> ix -> m (Maybe (e, e))
+swap
+  :: (Manifest r e, Index ix, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> ix -> m (Maybe (e, e))
 swap marr ix1 ix2 =
   let !sz = sizeOfMArray marr
    in if isSafeIndex sz ix1 && isSafeIndex sz ix2
diff --git a/src/Data/Massiv/Array/Numeric.hs b/src/Data/Massiv/Array/Numeric.hs
--- a/src/Data/Massiv/Array/Numeric.hs
+++ b/src/Data/Massiv/Array/Numeric.hs
@@ -128,7 +128,9 @@
 import Prelude as P
 
 infixr 8 .^, .^^
+
 infixl 7 !*!, .*., .*, *., !/!, ./., ./, /., `quotA`, `remA`, `divA`, `modA`
+
 infixl 6 !+!, .+., .+, +., !-!, .-., .-, -.
 
 -- | Similar to `liftArray2M`, except it can be applied only to representations
@@ -1248,7 +1250,8 @@
 -- size, otherwise it will result in an error.
 --
 -- @since 1.0.0
-sumArrays' :: (HasCallStack, Foldable t, Load r ix e, Numeric r e) => t (Array r ix e) -> Array r ix e
+sumArrays'
+  :: (HasCallStack, Foldable t, Load r ix e, Numeric r e) => t (Array r ix e) -> Array r ix e
 sumArrays' = throwEither . sumArraysM
 {-# INLINE sumArrays' #-}
 
diff --git a/src/Data/Massiv/Array/Ops/Construct.hs b/src/Data/Massiv/Array/Ops/Construct.hs
--- a/src/Data/Massiv/Array/Ops/Construct.hs
+++ b/src/Data/Massiv/Array/Ops/Construct.hs
@@ -76,7 +76,6 @@
 import Control.Monad.ST
 import Data.Massiv.Array.Delayed.Pull
 import Data.Massiv.Array.Delayed.Push
-
 -- import Data.Massiv.Array.Delayed.Stream (unfoldr, unfoldrN)
 import Data.Massiv.Array.Mutable
 import Data.Massiv.Core.Common
diff --git a/src/Data/Massiv/Array/Ops/Fold.hs b/src/Data/Massiv/Array/Ops/Fold.hs
--- a/src/Data/Massiv/Array/Ops/Fold.hs
+++ b/src/Data/Massiv/Array/Ops/Fold.hs
@@ -347,7 +347,8 @@
 -- | Monoidal fold over the inner most dimension.
 --
 -- @since 0.4.3
-foldInner :: (Monoid e, Index (Lower ix), Index ix, Source r e) => Array r ix e -> Array D (Lower ix) e
+foldInner
+  :: (Monoid e, Index (Lower ix), Index ix, Source r e) => Array r ix e -> Array D (Lower ix) e
 foldInner = foldlInner mappend mempty
 {-# INLINE foldInner #-}
 
diff --git a/src/Data/Massiv/Core/Common.hs b/src/Data/Massiv/Core/Common.hs
--- a/src/Data/Massiv/Core/Common.hs
+++ b/src/Data/Massiv/Core/Common.hs
@@ -116,8 +116,8 @@
 import Data.Massiv.Core.Exception
 import Data.Massiv.Core.Index
 import Data.Massiv.Core.Index.Internal (Sz (SafeSz))
-import Data.Typeable
 import qualified Data.Stream.Monadic as S (Stream)
+import Data.Typeable
 import Data.Vector.Fusion.Util
 import GHC.Exts (IsList)
 
diff --git a/src/Data/Massiv/Core/Index.hs b/src/Data/Massiv/Core/Index.hs
--- a/src/Data/Massiv/Core/Index.hs
+++ b/src/Data/Massiv/Core/Index.hs
@@ -3,6 +3,7 @@
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE ExplicitNamespaces #-}
 {-# LANGUAGE GADTs #-}
+{-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE PatternSynonyms #-}
 
 -- |
@@ -121,6 +122,7 @@
 import Data.Massiv.Core.Index.Stride
 import Data.Massiv.Core.Index.Tuple
 import Data.Massiv.Core.Loop
+import GHC.Base (modInt)
 import GHC.TypeLits
 
 #include "massiv.h"
@@ -193,13 +195,21 @@
   deriving (Eq, Show)
 
 instance NFData e => NFData (Border e) where
-  rnf b = case b of
+  rnf = \case
     Fill e -> rnf e
     Wrap -> ()
     Edge -> ()
     Reflect -> ()
     Continue -> ()
 
+instance Functor Border where
+  fmap f = \case
+    Fill e -> Fill (f e)
+    Wrap -> Wrap
+    Edge -> Edge
+    Reflect -> Reflect
+    Continue -> Continue
+
 -- | Apply a border resolution technique to an index
 --
 -- ==== __Examples__
@@ -225,28 +235,21 @@
   -> e
 handleBorderIndex border !sz getVal !ix =
   case border of
-    Fill val -> if isSafeIndex sz ix then getVal ix else val
-    Wrap -> getVal (repairIndex sz ix wrap wrap)
-    Edge -> getVal (repairIndex sz ix (const (const 0)) (\(SafeSz k) _ -> k - 1))
+    Fill val
+      | isSafeIndex sz ix -> getVal ix
+      | otherwise -> val
+    Wrap ->
+      getVal $
+        repairIndex sz ix (\(SafeSz k) i -> i `modInt` k) (\(SafeSz k) i -> i `modInt` k)
+    Edge ->
+      getVal $
+        repairIndex sz ix (const (const 0)) (\(SafeSz k) _ -> k - 1)
     Reflect ->
-      getVal
-        ( repairIndex
-            sz
-            ix
-            (\(SafeSz k) !i -> (abs i - 1) `mod` k)
-            (\(SafeSz k) !i -> (-i - 1) `mod` k)
-        )
+      getVal $
+        repairIndex sz ix (\(SafeSz k) i -> (-i - 1) `modInt` k) (\(SafeSz k) i -> (-i - 1) `modInt` k)
     Continue ->
-      getVal
-        ( repairIndex
-            sz
-            ix
-            (\(SafeSz k) !i -> abs i `mod` k)
-            (\(SafeSz k) !i -> (-i - 2) `mod` k)
-        )
-  where
-    wrap (SafeSz k) i = i `mod` k
-    {-# INLINE [1] wrap #-}
+      getVal $
+        repairIndex sz ix (\(SafeSz k) i -> negate i `modInt` k) (\(SafeSz k) i -> (-i - 2) `modInt` k)
 {-# INLINE [1] handleBorderIndex #-}
 
 -- | Index with all zeros
diff --git a/src/Data/Massiv/Core/Index/Internal.hs b/src/Data/Massiv/Core/Index/Internal.hs
--- a/src/Data/Massiv/Core/Index/Internal.hs
+++ b/src/Data/Massiv/Core/Index/Internal.hs
@@ -739,6 +739,9 @@
 
   -- | Similar to `iterM`, but no restriction on a Monad.
   --
+  -- iterF (-10) 20 4 (<) [] (:) :: [Int]
+  -- [-10,-6,-2,2,6,10,14,18]
+  --
   -- @since 1.0.2
   iterF :: ix -> ix -> ix -> (Int -> Int -> Bool) -> f a -> (ix -> f a -> f a) -> f a
   default iterF
@@ -1000,6 +1003,11 @@
 
 type instance Lower Int = Ix0
 
+-- This is needed to avoid GHC from doing redundant allocations
+throwIndexZeroException :: Int -> a
+throwIndexZeroException = throw . IndexZeroException
+{-# NOINLINE throwIndexZeroException #-}
+
 instance Index Ix1 where
   type Dimensions Ix1 = 1
   dimensions _ = 1
@@ -1017,7 +1025,7 @@
   fromLinearIndexAcc n k = k `quotRem` n
   {-# INLINE [1] fromLinearIndexAcc #-}
   repairIndex k@(SafeSz ksz) !i rBelow rOver
-    | ksz <= 0 = throw $ IndexZeroException ksz
+    | ksz <= 0 = throwIndexZeroException ksz
     | i < 0 = rBelow k i
     | i >= ksz = rOver k i
     | otherwise = i
diff --git a/src/Data/Massiv/Core/Index/Iterator.hs b/src/Data/Massiv/Core/Index/Iterator.hs
--- a/src/Data/Massiv/Core/Index/Iterator.hs
+++ b/src/Data/Massiv/Core/Index/Iterator.hs
@@ -284,6 +284,7 @@
 pattern RowMajor f <- RowMajorInternal f
   where
     RowMajor = RowMajorInternal . max 1
+
 {-# COMPLETE RowMajor #-}
 
 instance Iterator RowMajor where
@@ -369,6 +370,7 @@
 pattern RowMajorUnbalanced f <- RowMajorUnbalancedInternal f
   where
     RowMajorUnbalanced = RowMajorUnbalancedInternal . max 1
+
 {-# COMPLETE RowMajorUnbalanced #-}
 
 instance Iterator RowMajorUnbalanced where
diff --git a/src/Data/Massiv/Core/Index/Ix.hs b/src/Data/Massiv/Core/Index/Ix.hs
--- a/src/Data/Massiv/Core/Index/Ix.hs
+++ b/src/Data/Massiv/Core/Index/Ix.hs
@@ -157,6 +157,7 @@
   Ix n = IxN n
 
 type instance Lower Ix2 = Ix1
+
 type instance Lower (IxN n) = Ix (n - 1)
 
 instance Show Ix2 where
diff --git a/src/Data/Massiv/Core/Index/Tuple.hs b/src/Data/Massiv/Core/Index/Tuple.hs
--- a/src/Data/Massiv/Core/Index/Tuple.hs
+++ b/src/Data/Massiv/Core/Index/Tuple.hs
@@ -65,8 +65,11 @@
 type Ix5T = (Int, Int, Int, Int, Int)
 
 type instance Lower Ix2T = Ix1T
+
 type instance Lower Ix3T = Ix2T
+
 type instance Lower Ix4T = Ix3T
+
 type instance Lower Ix5T = Ix4T
 
 -- | Convert an `Int` tuple to `Ix2`
diff --git a/src/Data/Massiv/Core/List.hs b/src/Data/Massiv/Core/List.hs
--- a/src/Data/Massiv/Core/List.hs
+++ b/src/Data/Massiv/Core/List.hs
@@ -37,7 +37,7 @@
 import qualified Data.Massiv.Vector.Stream as S
 import Data.Monoid
 import Data.Typeable
-import GHC.Exts (IsList(..))
+import GHC.Exts (IsList (..))
 import GHC.TypeLits
 import System.IO.Unsafe (unsafePerformIO)
 
diff --git a/src/Data/Massiv/Core/Loop.hs b/src/Data/Massiv/Core/Loop.hs
--- a/src/Data/Massiv/Core/Loop.hs
+++ b/src/Data/Massiv/Core/Loop.hs
@@ -454,8 +454,12 @@
 {-# INLINE [0] scheduleMassivWork #-}
 
 {-# RULES
-"scheduleWork/scheduleWork_/ST" forall (scheduler :: Scheduler s ()) (action :: ST s ()). scheduleMassivWork scheduler action = scheduleWork_ scheduler action
-"scheduleWork/scheduleWork_/IO" forall (scheduler :: Scheduler RealWorld ()) (action :: IO ()). scheduleMassivWork scheduler action = scheduleWork_ scheduler action
+"scheduleWork/scheduleWork_/ST" forall (scheduler :: Scheduler s ()) (action :: ST s ()).
+  scheduleMassivWork scheduler action =
+    scheduleWork_ scheduler action
+"scheduleWork/scheduleWork_/IO" forall (scheduler :: Scheduler RealWorld ()) (action :: IO ()).
+  scheduleMassivWork scheduler action =
+    scheduleWork_ scheduler action
   #-}
 
 -- | Selects an optimal scheduler for the supplied strategy, but it works only in `IO`
diff --git a/src/Data/Massiv/Vector.hs b/src/Data/Massiv/Vector.hs
--- a/src/Data/Massiv/Vector.hs
+++ b/src/Data/Massiv/Vector.hs
@@ -979,7 +979,8 @@
 -- ==== __Examples__
 --
 -- @since 0.5.0
-sliceAtM :: forall r e m. (Source r e, MonadThrow m) => Sz1 -> Vector r e -> m (Vector r e, Vector r e)
+sliceAtM
+  :: forall r e m. (Source r e, MonadThrow m) => Sz1 -> Vector r e -> m (Vector r e, Vector r e)
 sliceAtM k v = do
   l <- takeM k v
   pure (l, unsafeDrop k v)
@@ -2800,7 +2801,6 @@
 spostscanlAcc :: Stream r ix e => (c -> e -> (a, c)) -> c -> Array r ix e -> Vector DS a
 spostscanlAcc f acc = DSArray . S.postscanlAccM (\a b -> pure (f a b)) acc . toStream
 {-# INLINE spostscanlAcc #-}
-
 
 -- | /O(n)/ - left scan with strict accumulator. First element is the value of the accumulator.
 --
diff --git a/src/Data/Massiv/Vector/Stream.hs b/src/Data/Massiv/Vector/Stream.hs
--- a/src/Data/Massiv/Vector/Stream.hs
+++ b/src/Data/Massiv/Vector/Stream.hs
@@ -479,7 +479,9 @@
   -> Steps m e
   -> Steps m f
 zipWith5 f (Steps sa ka) (Steps sb kb) (Steps sc kc) (Steps sd kd) (Steps se ke) =
-  Steps (S.zipWith5 f sa sb sc sd se) (minLengthHint ka (minLengthHint kb (minLengthHint kc (minLengthHint kd ke))))
+  Steps
+    (S.zipWith5 f sa sb sc sd se)
+    (minLengthHint ka (minLengthHint kb (minLengthHint kc (minLengthHint kd ke))))
 {-# INLINE zipWith5 #-}
 
 zipWith6
@@ -529,7 +531,9 @@
   -> Steps m e
   -> Steps m f
 zipWith5M f (Steps sa ka) (Steps sb kb) (Steps sc kc) (Steps sd kd) (Steps se ke) =
-  Steps (S.zipWith5M f sa sb sc sd se) (minLengthHint ka (minLengthHint kb (minLengthHint kc (minLengthHint kd ke))))
+  Steps
+    (S.zipWith5M f sa sb sc sd se)
+    (minLengthHint ka (minLengthHint kb (minLengthHint kc (minLengthHint kd ke))))
 {-# INLINE zipWith5M #-}
 
 zipWith6M
