diff --git a/massiv.cabal b/massiv.cabal
--- a/massiv.cabal
+++ b/massiv.cabal
@@ -1,5 +1,5 @@
 name:                massiv
-version:             0.2.6.0
+version:             0.2.7.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/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
@@ -107,7 +107,7 @@
   :: Source r ix e
   => Array r ix e -- ^ Source array that will have a window inserted into it
   -> ix -- ^ Start index for the window
-  -> ix -- ^ Size of the window
+  -> Sz ix -- ^ Size of the window
   -> (ix -> e) -- ^ Inside window indexing function
   -> Array DW ix e
 makeWindowedArray !arr !windowStart !windowSize windowIndex
diff --git a/src/Data/Massiv/Array/Manifest/Internal.hs b/src/Data/Massiv/Array/Manifest/Internal.hs
--- a/src/Data/Massiv/Array/Manifest/Internal.hs
+++ b/src/Data/Massiv/Array/Manifest/Internal.hs
@@ -107,7 +107,7 @@
   {-# INLINE unsafeMakeArray #-}
 
 -- | Create a boxed from usual size and index to element function
-makeBoxedVector :: Index ix => ix -> (ix -> a) -> V.Vector a
+makeBoxedVector :: Index ix => Sz ix -> (ix -> a) -> V.Vector a
 makeBoxedVector !sz f = V.generate (totalElem sz) (f . fromLinearIndex sz)
 {-# INLINE makeBoxedVector #-}
 
diff --git a/src/Data/Massiv/Array/Manifest/Vector.hs b/src/Data/Massiv/Array/Manifest/Vector.hs
--- a/src/Data/Massiv/Array/Manifest/Vector.hs
+++ b/src/Data/Massiv/Array/Manifest/Vector.hs
@@ -57,7 +57,7 @@
 -- been sliced before or if some non-standard vector type is supplied.
 castFromVector :: forall v r ix e. (VG.Vector v e, Typeable v, Mutable r ix e, ARepr v ~ r)
                => Comp
-               -> ix -- ^ Size of the result Array
+               -> Sz ix -- ^ Size of the result Array
                -> v e -- ^ Source Vector
                -> Maybe (Array r ix e)
 castFromVector comp sz vector = do
@@ -88,7 +88,7 @@
 fromVector ::
      (Typeable v, VG.Vector v a, Mutable (ARepr v) ix a, Mutable r ix a)
   => Comp
-  -> ix -- ^ Resulting size of the array
+  -> Sz ix -- ^ Resulting size of the array
   -> v a -- ^ Source Vector
   -> Array r ix a
 fromVector comp sz v =
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
@@ -60,7 +60,7 @@
 import           Data.Massiv.Core.Scheduler
 
 -- | Initialize a new mutable array. Negative size will result in an empty array.
-new :: (Mutable r ix e, PrimMonad m) => ix -> m (MArray (PrimState m) r ix e)
+new :: (Mutable r ix e, PrimMonad m) => Sz ix -> m (MArray (PrimState m) r ix e)
 new sz = unsafeNewZero (liftIndex (max 0) sz)
 {-# INLINE new #-}
 
@@ -80,7 +80,7 @@
 --
 -- ====__Examples__
 --
--- >>> createArray_ Seq (Ix1 2) (\ marr -> write marr 0 10 >> write marr 1 11) :: IO (Array P Ix1 Int)
+-- >>> createArray_ Seq (Sz1 2) (\ marr -> write marr 0 10 >> write marr 1 11) :: IO (Array P Ix1 Int)
 -- (Array P Seq (2)
 --   [ 10,11 ])
 --
@@ -89,7 +89,7 @@
 createArray_ ::
      (Mutable r ix e, PrimMonad m)
   => Comp -- ^ Computation strategy to use after `MArray` gets frozen and onward.
-  -> ix -- ^ Size of the newly created array
+  -> Sz ix -- ^ Size of the newly created array
   -> (MArray (PrimState m) r ix e -> m a)
   -- ^ An action that should fill all elements of the brand new mutable array
   -> m (Array r ix e)
@@ -103,7 +103,7 @@
 createArray ::
      (Mutable r ix e, PrimMonad m)
   => Comp -- ^ Computation strategy to use after `MArray` gets frozen and onward.
-  -> ix -- ^ Size of the newly created array
+  -> Sz ix -- ^ Size of the newly created array
   -> (MArray (PrimState m) r ix e -> m a)
   -- ^ An action that should fill all elements of the brand new mutable array
   -> m (a, Array r ix e)
@@ -119,7 +119,7 @@
 -- @since 0.2.6
 --
 createArrayST_ ::
-     Mutable r ix e => Comp -> ix -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e
+     Mutable r ix e => Comp -> Sz ix -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e
 createArrayST_ comp sz action = runST $ createArray_ comp sz action
 {-# INLINE createArrayST_ #-}
 
@@ -129,7 +129,7 @@
 -- @since 0.2.6
 --
 createArrayST ::
-     Mutable r ix e => Comp -> ix -> (forall s. MArray s r ix e -> ST s a) -> (a, Array r ix e)
+     Mutable r ix e => Comp -> Sz ix -> (forall s. MArray s r ix e -> ST s a) -> (a, Array r ix e)
 createArrayST comp sz action = runST $ createArray comp sz action
 {-# INLINE createArrayST #-}
 
@@ -146,7 +146,7 @@
 --
 -- >>> import Data.IORef
 -- >>> ref <- newIORef (0 :: Int)
--- >>> generateArray Seq (Ix1 6) (\ i -> modifyIORef' ref (+i) >> print i >> pure i) :: IO (Array U Ix1 Int)
+-- >>> generateArray Seq (Sz1 6) (\ i -> modifyIORef' ref (+i) >> print i >> pure i) :: IO (Array U Ix1 Int)
 -- 0
 -- 1
 -- 2
@@ -161,7 +161,7 @@
 generateArray ::
      (Mutable r ix e, PrimMonad m)
   => Comp -- ^ Computation strategy (ingored during generation)
-  -> ix -- ^ Resulting size of the array
+  -> Sz ix -- ^ Resulting size of the array
   -> (ix -> m e) -- ^ Element producing generator
   -> m (Array r ix e)
 generateArray comp sz' gen = do
@@ -179,7 +179,7 @@
 generateArrayIO ::
      (Mutable r ix e)
   => Comp
-  -> ix
+  -> Sz ix
   -> (ix -> IO e)
   -> IO (Array r ix e)
 generateArrayIO comp sz' gen = do
@@ -224,7 +224,7 @@
 unfoldlPrim_ ::
      (Mutable r ix e, PrimMonad m)
   => Comp -- ^ Computation strategy (ignored during initial creation)
-  -> ix -- ^ Size of the desired array
+  -> Sz ix -- ^ Size of the desired array
   -> (a -> ix -> m (a, e)) -- ^ Unfolding action
   -> a -- ^ Initial accumulator
   -> m (Array r ix e)
@@ -232,14 +232,14 @@
 {-# INLINE unfoldlPrim_ #-}
 
 
--- | Just like `unfoldlPrim`, but also returns the final value of the accumulator.
+-- | Just like `unfoldlPrim_`, but also returns the final value of the accumulator.
 --
 -- @since 0.2.6
 --
 unfoldlPrim ::
      (Mutable r ix e, PrimMonad m)
   => Comp -- ^ Computation strategy (ignored during initial creation)
-  -> ix -- ^ Size of the desired array
+  -> Sz ix -- ^ Size of the desired array
   -> (a -> ix -> m (a, e)) -- ^ Unfolding action
   -> a -- ^ Initial accumulator
   -> m (a, Array r ix e)
diff --git a/src/Data/Massiv/Array/Numeric/Integral.hs b/src/Data/Massiv/Array/Numeric/Integral.hs
--- a/src/Data/Massiv/Array/Numeric/Integral.hs
+++ b/src/Data/Massiv/Array/Numeric/Integral.hs
@@ -118,7 +118,7 @@
      (Fractional e, Load DW ix e, Mutable r ix e)
   => (e -> Dim -> Int -> Stencil ix e e) -- ^ Integration Stencil
   -> e -- ^ @d@ - Length of interval per cell
-  -> ix -- ^ @sz@ - Result size of the matrix
+  -> Sz ix -- ^ @sz@ - Result size of the matrix
   -> Int -- ^ @n@ - Number of samples
   -> Array r ix e -- ^ Array with values of @f(x,y,..)@ that will be used as source for integration.
   -> Array M ix e
@@ -139,7 +139,7 @@
   -> ((Int -> e) -> ix -> e) -- ^ @f(x,y,...)@ - Function to integrate
   -> e -- ^ @a@ - Starting value point.
   -> e -- ^ @d@ - Distance per matrix cell.
-  -> ix -- ^ @sz@ - Result matrix size.
+  -> Sz ix -- ^ @sz@ - Result matrix size.
   -> Int -- ^ @n@ - Number of sample points per cell in each direction.
   -> Array M ix e
 midpointRule comp r f a d sz n =
@@ -155,7 +155,7 @@
   -> ((Int -> e) -> ix -> e) -- ^ @f(x,y,...)@ - function to integrate
   -> e -- ^ @a@ - starting point
   -> e -- ^ @d@ - distance per matrix cell
-  -> ix -- ^ @sz@ - end matrix size
+  -> Sz ix -- ^ @sz@ - end matrix size
   -> Int -- ^ @n@ - number of sample points per cell in each direction
   -> Array M ix e
 trapezoidRule comp r f a d sz n =
@@ -170,7 +170,7 @@
   -> ((Int -> e) -> ix -> e) -- ^ @f(x,y,...)@ - function to integrate
   -> e -- ^ @a@ - starting point
   -> e -- ^ @d@ - distance per matrix cell
-  -> ix -- ^ @sz@ - end matrix size
+  -> Sz ix -- ^ @sz@ - end matrix size
   -> Int -- ^ @n@ - number of sample points per cell in each direction. This value must be even,
          -- otherwise error..
   -> Array M ix e
@@ -202,7 +202,7 @@
   -- function that should be applied to individual indicies.
   -> a -- ^ @a@ - Starting point
   -> a -- ^ @d@ - Distance per cell
-  -> ix -- ^ @sz@ - Size of the desired array
+  -> Sz ix -- ^ @sz@ - Size of the desired array
   -> Int -- ^ @n@ - Scaling factor, i.e. number of sample points per cell.
   -> Array D ix e
 fromFunction comp f a d sz n =
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
@@ -44,7 +44,7 @@
 -- | Just like `makeArray` but with ability to specify the result representation as an
 -- argument. Note the `Data.Massiv.Array.U`nboxed type constructor in the below example.
 --
--- >>> makeArrayR U Par (2 :> 3 :. 4) (\ (i :> j :. k) -> i * i + j * j == k * k)
+-- >>> makeArrayR U Par (Sz (2 :> 3 :. 4)) (\ (i :> j :. k) -> i * i + j * j == k * k)
 -- (Array U Par (2 :> 3 :. 4)
 --   [ [ [ True,False,False,False ]
 --     , [ False,True,False,False ]
@@ -56,13 +56,13 @@
 --     ]
 --   ])
 --
-makeArrayR :: Construct r ix e => r -> Comp -> ix -> (ix -> e) -> Array r ix e
+makeArrayR :: Construct r ix e => r -> Comp -> Sz ix -> (ix -> e) -> Array r ix e
 makeArrayR _ = makeArray
 {-# INLINE makeArrayR #-}
 
 
 -- | Same as `makeArrayR`, but restricted to 1-dimensional arrays.
-makeVectorR :: Construct r Ix1 e => r -> Comp -> Ix1-> (Ix1 -> e) -> Array r Ix1 e
+makeVectorR :: Construct r Ix1 e => r -> Comp -> Sz1 -> (Ix1 -> e) -> Array r Ix1 e
 makeVectorR _ = makeArray
 {-# INLINE makeVectorR #-}
 
@@ -71,7 +71,7 @@
 --
 -- @since 0.2.6
 --
-makeArrayA :: (Mutable r a b, Applicative f) => Comp -> a -> (a -> f b) -> f (Array r a b)
+makeArrayA :: (Mutable r ix b, Applicative f) => Comp -> Sz ix -> (ix -> f b) -> f (Array r ix b)
 makeArrayA comp sz f = traverseA f $ makeArrayR D comp sz id
 {-# INLINE makeArrayA #-}
 
@@ -79,7 +79,7 @@
 --
 -- @since 0.2.6
 --
-makeArrayAR :: (Mutable r a b, Applicative f) => r -> Comp -> a -> (a -> f b) -> f (Array r a b)
+makeArrayAR :: (Mutable r ix b, Applicative f) => r -> Comp -> Sz ix -> (ix -> f b) -> f (Array r ix b)
 makeArrayAR _ = makeArrayA
 {-# INLINE makeArrayAR #-}
 
diff --git a/src/Data/Massiv/Array/Ops/Transform.hs b/src/Data/Massiv/Array/Ops/Transform.hs
--- a/src/Data/Massiv/Array/Ops/Transform.hs
+++ b/src/Data/Massiv/Array/Ops/Transform.hs
@@ -47,7 +47,7 @@
 -- fully encapsulated in a source array, otherwise `Nothing` is returned,
 extract :: Size r ix e
         => ix -- ^ Starting index
-        -> ix -- ^ Size of the resulting array
+        -> Sz ix -- ^ Size of the resulting array
         -> Array r ix e -- ^ Source array
         -> Maybe (Array (EltRepr r ix) ix e)
 extract !sIx !newSz !arr
@@ -63,7 +63,7 @@
 -- | Same as `extract`, but will throw an error if supplied dimensions are incorrect.
 extract' :: Size r ix e
         => ix -- ^ Starting index
-        -> ix -- ^ Size of the resulting array
+        -> Sz ix -- ^ Size of the resulting array
         -> Array r ix e -- ^ Source array
         -> Array (EltRepr r ix) ix e
 extract' !sIx !newSz !arr =
@@ -100,14 +100,14 @@
 
 -- | /O(1)/ - Changes the shape of an array. Returns `Nothing` if total
 -- number of elements does not match the source array.
-resize :: (Index ix', Size r ix e) => ix' -> Array r ix e -> Maybe (Array r ix' e)
+resize :: (Index ix', Size r ix e) => Sz ix' -> Array r ix e -> Maybe (Array r ix' e)
 resize !sz !arr
   | totalElem sz == totalElem (size arr) = Just $ unsafeResize sz arr
   | otherwise = Nothing
 {-# INLINE resize #-}
 
 -- | Same as `resize`, but will throw an error if supplied dimensions are incorrect.
-resize' :: (Index ix', Size r ix e) => ix' -> Array r ix e -> Array r ix' e
+resize' :: (Index ix', Size r ix e) => Sz ix' -> Array r ix e -> Array r ix' e
 resize' !sz !arr =
   maybe
     (error $
@@ -261,7 +261,7 @@
 --   ])
 --
 backpermute :: (Source r' ix' e, Index ix) =>
-               ix -- ^ Size of the result array
+               Sz ix -- ^ Size of the result array
             -> (ix -> ix') -- ^ A function that maps indices of the new array into the source one.
             -> Array r' ix' e -- ^ Source array.
             -> Array D ix e
@@ -373,7 +373,7 @@
 -- | Create an array by traversing a source array.
 traverse
   :: (Source r1 ix1 e1, Index ix)
-  => ix -- ^ Size of the result array
+  => Sz ix -- ^ Size of the result array
   -> ((ix1 -> e1) -> ix -> e) -- ^ Function that will receive a source array safe index function and
                               -- an index for an element it should return a value of.
   -> Array r1 ix1 e1 -- ^ Source array
@@ -385,7 +385,7 @@
 -- | Create an array by traversing two source arrays.
 traverse2
   :: (Source r1 ix1 e1, Source r2 ix2 e2, Index ix)
-  => ix
+  => Sz ix
   -> ((ix1 -> e1) -> (ix2 -> e2) -> ix -> e)
   -> Array r1 ix1 e1
   -> Array r2 ix2 e2
diff --git a/src/Data/Massiv/Array/Stencil.hs b/src/Data/Massiv/Array/Stencil.hs
--- a/src/Data/Massiv/Array/Stencil.hs
+++ b/src/Data/Massiv/Array/Stencil.hs
@@ -96,7 +96,7 @@
 makeStencilDef
   :: Index ix
   => e
-  -> ix -- ^ Size of the stencil
+  -> Sz ix -- ^ Size of the stencil
   -> ix -- ^ Center of the stencil
   -> ((ix -> Value e) -> Value a)
   -- ^ Stencil function.
diff --git a/src/Data/Massiv/Array/Stencil/Convolution.hs b/src/Data/Massiv/Array/Stencil/Convolution.hs
--- a/src/Data/Massiv/Array/Stencil/Convolution.hs
+++ b/src/Data/Massiv/Array/Stencil/Convolution.hs
@@ -36,7 +36,7 @@
 --
 makeConvolutionStencil
   :: (Index ix, Num e)
-  => ix
+  => Sz ix
   -> ix
   -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e)
   -> Stencil ix e e
@@ -71,7 +71,7 @@
 -- | Make a <https://en.wikipedia.org/wiki/Cross-correlation cross-correlation> stencil.
 makeCorrelationStencil
   :: (Index ix, Num e)
-  => ix
+  => Sz ix
   -> ix
   -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e)
   -> Stencil ix e e
diff --git a/src/Data/Massiv/Array/Stencil/Internal.hs b/src/Data/Massiv/Array/Stencil/Internal.hs
--- a/src/Data/Massiv/Array/Stencil/Internal.hs
+++ b/src/Data/Massiv/Array/Stencil/Internal.hs
@@ -135,28 +135,31 @@
 instance Functor (Stencil ix e) where
   fmap = rmapStencil
   {-# INLINE fmap #-}
-  --  f stencil@(Stencil {stencilFunc = g}) = stencil {stencilFunc = stF}
-  --   where
-  --     stF s = Value . f . unValue . g s
-  --     {-# INLINE stF #-}
 
+
 -- Profunctor
 
 
-dimapStencil :: (t -> e) -> (b -> a) -> Stencil ix e b -> Stencil ix t a
-dimapStencil f g stencil@(Stencil {stencilFunc = sf}) =
-  stencil {stencilFunc = \s -> Value . g . unValue . sf (Value . f . unValue . s)}
+dimapStencil :: (c -> d) -> (a -> b) -> Stencil ix d a -> Stencil ix c b
+dimapStencil f g stencil@(Stencil {stencilFunc = sf}) = stencil {stencilFunc = sf'}
+  where
+    sf' s = Value . g . unValue . sf (Value . f . unValue . s)
+    {-# INLINE sf' #-}
 {-# INLINE dimapStencil #-}
 
 
-lmapStencil :: (b -> e) -> Stencil ix e a -> Stencil ix b a
-lmapStencil f stencil@(Stencil {stencilFunc = sf}) =
-  stencil {stencilFunc = \s -> sf (Value . f . unValue . s)}
+lmapStencil :: (c -> d) -> Stencil ix d a -> Stencil ix c a
+lmapStencil f stencil@(Stencil {stencilFunc = sf}) = stencil {stencilFunc = sf'}
+  where
+    sf' s = sf (Value . f . unValue . s)
+    {-# INLINE sf' #-}
 {-# INLINE lmapStencil #-}
 
 rmapStencil :: (a -> b) -> Stencil ix e a -> Stencil ix e b
-rmapStencil g stencil@(Stencil {stencilFunc = sf}) =
-  stencil {stencilFunc = \s -> Value . g . unValue . sf s}
+rmapStencil f stencil@(Stencil {stencilFunc = sf}) = stencil {stencilFunc = sf'}
+  where
+    sf' s = Value . f . unValue . sf s
+    {-# INLINE sf' #-}
 {-# INLINE rmapStencil #-}
 
 -- TODO: Figure out interchange law (u <*> pure y = pure ($ y) <*> u) and issue
diff --git a/src/Data/Massiv/Array/Stencil/Unsafe.hs b/src/Data/Massiv/Array/Stencil/Unsafe.hs
--- a/src/Data/Massiv/Array/Stencil/Unsafe.hs
+++ b/src/Data/Massiv/Array/Stencil/Unsafe.hs
@@ -30,7 +30,7 @@
 forStencilUnsafe ::
      (Source r ix e, Manifest r ix e)
   => Array r ix e
-  -> ix -- ^ Size of the stencil
+  -> Sz ix -- ^ Size of the stencil
   -> ix -- ^ Center of the stencil
   -> ((ix -> Maybe e) -> a)
   -- ^ Stencil function that receives a "get" function as it's argument that can
diff --git a/src/Data/Massiv/Array/Unsafe.hs b/src/Data/Massiv/Array/Unsafe.hs
--- a/src/Data/Massiv/Array/Unsafe.hs
+++ b/src/Data/Massiv/Array/Unsafe.hs
@@ -50,7 +50,7 @@
 
 
 unsafeBackpermute :: (Source r' ix' e, Index ix) =>
-                     ix -> (ix -> ix') -> Array r' ix' e -> Array D ix e
+                     Sz ix -> (ix -> ix') -> Array r' ix' e -> Array D ix e
 unsafeBackpermute !sz ixF !arr =
   unsafeMakeArray (getComp arr) sz $ \ !ix -> unsafeIndex arr (ixF ix)
 {-# INLINE unsafeBackpermute #-}
@@ -58,7 +58,7 @@
 
 unsafeTraverse
   :: (Source r1 ix1 e1, Index ix)
-  => ix
+  => Sz ix
   -> ((ix1 -> e1) -> ix -> e)
   -> Array r1 ix1 e1
   -> Array D ix e
@@ -69,7 +69,7 @@
 
 unsafeTraverse2
   :: (Source r1 ix1 e1, Source r2 ix2 e2, Index ix)
-  => ix
+  => Sz ix
   -> ((ix1 -> e1) -> (ix2 -> e2) -> ix -> e)
   -> Array r1 ix1 e1
   -> Array r2 ix2 e2
@@ -93,7 +93,7 @@
 
 
 -- | Create an array sequentially using mutable interface
-unsafeGenerateArray :: Mutable r ix e => ix -> (ix -> e) -> Array r ix e
+unsafeGenerateArray :: Mutable r ix e => Sz ix -> (ix -> e) -> Array r ix e
 unsafeGenerateArray !sz f = runST $ do
   marr <- unsafeNew sz
   iterLinearM_ sz 0 (totalElem sz) 1 (<) $ \ !k !ix ->
@@ -101,11 +101,10 @@
   unsafeFreeze Seq marr
 {-# INLINE unsafeGenerateArray #-}
 
-
 -- | Create an array in parallel using mutable interface
 --
 -- @since 0.1.5
-unsafeGenerateArrayP :: Mutable r ix e => [Int] -> ix -> (ix -> e) -> Array r ix e
+unsafeGenerateArrayP :: Mutable r ix e => [Int] -> Sz ix -> (ix -> e) -> Array r ix e
 unsafeGenerateArrayP wIds !sz f = unsafePerformIO $ do
   marr <- unsafeNew sz
   divideWork_ wIds sz $ \ !scheduler !chunkLength !totalLength !slackStart -> do
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
@@ -87,7 +87,7 @@
   setComp :: Comp -> Array r ix e -> Array r ix e
 
   -- | Construct an array. No size validation is performed.
-  unsafeMakeArray :: Comp -> ix -> (ix -> e) -> Array r ix e
+  unsafeMakeArray :: Comp -> Sz ix -> (ix -> e) -> Array r ix e
 
 
 -- | An array that contains size information. They can be resized and new arrays extracted from it
@@ -95,14 +95,14 @@
 class Construct r ix e => Size r ix e where
 
   -- | /O(1)/ - Get the size of an array
-  size :: Array r ix e -> ix
+  size :: Array r ix e -> Sz ix
 
   -- | /O(1)/ - Change the size of an array. New size is not validated.
-  unsafeResize :: Index ix' => ix' -> Array r ix e -> Array r ix' e
+  unsafeResize :: Index ix' => Sz ix' -> Array r ix e -> Array r ix' e
 
   -- | /O(1)/ - Extract a portion of an array. Staring index and new size are
   -- not validated.
-  unsafeExtract :: ix -> ix -> Array r ix e -> Array (EltRepr r ix) ix e
+  unsafeExtract :: ix -> Sz ix -> Array r ix e -> Array (EltRepr r ix) ix e
 
 
 -- | Arrays that can be used as source to practically any manipulation function.
@@ -157,7 +157,7 @@
     -> (m () -> m ()) -- ^ A monadic action that will schedule work for the workers (for `Seq` it's
                       -- always `id`)
     -> Stride ix -- ^ Stride to use
-    -> ix -- ^ Size of the target array affected by the stride.
+    -> Sz ix -- ^ Size of the target array affected by the stride.
     -> Array r ix e -- ^ Array that is being loaded
     -> (Int -> m e) -- ^ Function that reads an element from target array
     -> (Int -> e -> m ()) -- ^ Function that writes an element into target array
@@ -167,7 +167,7 @@
        Int
     -> (m () -> m ())
     -> Stride ix
-    -> ix
+    -> Sz ix
     -> Array r ix e
     -> (Int -> m e)
     -> (Int -> e -> m ())
@@ -215,10 +215,10 @@
   outerLength = headDim . size
 
 class Size r ix e => InnerSlice r ix e where
-  unsafeInnerSlice :: Array r ix e -> (Lower ix, Int) -> Int -> Elt r ix e
+  unsafeInnerSlice :: Array r ix e -> (Sz (Lower ix), Sz1) -> Int -> Elt r ix e
 
 class Size r ix e => Slice r ix e where
-  unsafeSlice :: Array r ix e -> ix -> ix -> Dim -> Maybe (Elt r ix e)
+  unsafeSlice :: Array r ix e -> ix -> Sz ix -> Dim -> Maybe (Elt r ix e)
 
 
 -- | Manifest arrays are backed by actual memory and values are looked up versus
@@ -238,7 +238,7 @@
   data MArray s r ix e :: *
 
   -- | Get the size of a mutable array.
-  msize :: MArray s r ix e -> ix
+  msize :: MArray s r ix e -> Sz ix
 
   unsafeThaw :: PrimMonad m =>
                 Array r ix e -> m (MArray (PrimState m) r ix e)
@@ -249,12 +249,12 @@
   -- | Create new mutable array, leaving it's elements uninitialized. Size isn't validated
   -- either.
   unsafeNew :: PrimMonad m =>
-               ix -> m (MArray (PrimState m) r ix e)
+               Sz ix -> m (MArray (PrimState m) r ix e)
 
   -- | Create new mutable array, leaving it's elements uninitialized. Size isn't validated
   -- either.
   unsafeNewZero :: PrimMonad m =>
-                   ix -> m (MArray (PrimState m) r ix e)
+                   Sz ix -> m (MArray (PrimState m) r ix e)
 
   unsafeLinearRead :: PrimMonad m =>
                       MArray (PrimState m) r ix e -> Int -> m e
@@ -313,9 +313,9 @@
 
   -- tail :: Array r ix e -> Maybe (Elt r ix e, Array r ix e)
 
-  unsafeGenerateM :: Monad m => Comp -> ix -> (ix -> m e) -> m (Array r ix e)
+  unsafeGenerateM :: Monad m => Comp -> Sz ix -> (ix -> m e) -> m (Array r ix e)
 
-  edgeSize :: Array r ix e -> ix
+  edgeSize :: Array r ix e -> Sz ix
 
   flatten :: Array r ix e -> Array r Ix1 e
 
@@ -331,7 +331,7 @@
 -- | Create an Array. Resulting type either has to be unambiguously inferred or restricted manually,
 -- like in the example below.
 --
--- >>> makeArray Seq (3 :. 4) (\ (i :. j) -> if i == j then i else 0) :: Array D Ix2 Int
+-- >>> makeArray Seq (Sz (3 :. 4)) (\ (i :. j) -> if i == j then i else 0) :: Array D Ix2 Int
 -- (Array D Seq (3 :. 4)
 -- [ [ 0,0,0,0 ]
 -- , [ 0,1,0,0 ]
@@ -340,7 +340,7 @@
 --
 makeArray :: Construct r ix e =>
              Comp -- ^ Computation strategy. Useful constructors are `Seq` and `Par`
-          -> ix -- ^ Size of the result array. Negative values will result in an empty array.
+          -> Sz ix -- ^ Size of the result array. Negative values will result in an empty array.
           -> (ix -> e) -- ^ Function to generate elements at a particular index
           -> Array r ix e
 makeArray !c = unsafeMakeArray c . liftIndex (max 0)
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
@@ -55,7 +55,6 @@
 import           Data.Massiv.Core.Iterator
 import           GHC.TypeLits
 
-
 -- | Approach to be used near the borders during various transformations.
 -- Whenever a function needs information not only about an element of interest, but
 -- also about it's neighbors, it will go out of bounds near the array edges,
@@ -111,7 +110,7 @@
 handleBorderIndex ::
      Index ix
   => Border e -- ^ Broder resolution technique
-  -> ix -- ^ Size
+  -> Sz ix -- ^ Size
   -> (ix -> e) -- ^ Index function that produces an element
   -> ix -- ^ Index
   -> e
@@ -132,13 +131,15 @@
 {-# INLINE [1] zeroIndex #-}
 
 -- | Checks whether the size is valid.
-isSafeSize :: Index ix => ix -> Bool
+--
+-- __Note__ Will be removed in /massiv-0.3.0/
+isSafeSize :: Index ix => Sz ix -> Bool
 isSafeSize = (zeroIndex >=)
 {-# INLINE [1] isSafeSize #-}
 
 
 -- | Checks whether array with this size can hold at least one element.
-isNonEmpty :: Index ix => ix -> Bool
+isNonEmpty :: Index ix => Sz ix -> Bool
 isNonEmpty !sz = isSafeIndex sz zeroIndex
 {-# INLINE [1] isNonEmpty #-}
 
@@ -264,7 +265,7 @@
 -- | Iterate over N-dimensional space lenarly from start to end in row-major fashion with an
 -- accumulator
 iterLinearM :: (Index ix, Monad m)
-            => ix -- ^ Size
+            => Sz ix -- ^ Size
             -> Int -- ^ Linear start
             -> Int -- ^ Linear end
             -> Int -- ^ Increment
@@ -278,7 +279,7 @@
 
 -- | Same as `iterLinearM`, except without an accumulator.
 iterLinearM_ :: (Index ix, Monad m) =>
-                ix -- ^ Size
+                Sz ix -- ^ Size
              -> Int -- ^ Start
              -> Int -- ^ End
              -> Int -- ^ Increment
diff --git a/src/Data/Massiv/Core/Index/Class.hs b/src/Data/Massiv/Core/Index/Class.hs
--- a/src/Data/Massiv/Core/Index/Class.hs
+++ b/src/Data/Massiv/Core/Index/Class.hs
@@ -7,6 +7,7 @@
 {-# LANGUAGE GADTs                      #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE PatternSynonyms            #-}
 {-# LANGUAGE TypeFamilies               #-}
 {-# LANGUAGE TypeOperators              #-}
 -- |
@@ -24,6 +25,19 @@
 import           Data.Massiv.Core.Iterator
 import           GHC.TypeLits
 
+
+-- | Helpful type synonym for migrating to newer version @0.3@
+type Sz ix = ix
+
+-- | Helpful pattern synonym for migrating to newer version @0.3@
+pattern Sz :: ix -> Sz ix
+pattern Sz ix = ix
+
+type Sz1 = Sz Int
+pattern Sz1 :: Int -> Int
+pattern Sz1 ix = ix
+
+
 -- | A way to select Array dimension at a value level.
 newtype Dim = Dim Int deriving (Show, Eq, Ord, Num, Real, Integral, Enum)
 
@@ -79,7 +93,7 @@
   dimensions :: ix -> Dim
 
   -- | Total number of elements in an array of this size.
-  totalElem :: ix -> Int
+  totalElem :: Sz ix -> Int
 
   -- | Prepend a dimension to the index
   consDim :: Int -> Lower ix -> ix
@@ -144,7 +158,7 @@
   {-# INLINE [1] foldlIndex #-}
 
   -- | Check whether index is within the size.
-  isSafeIndex :: ix -- ^ Size
+  isSafeIndex :: Sz ix -- ^ Size
               -> ix -- ^ Index
               -> Bool
   default isSafeIndex :: Index (Lower ix) => ix -> ix -> Bool
@@ -155,7 +169,7 @@
   {-# INLINE [1] isSafeIndex #-}
 
   -- | Convert linear index from size and index
-  toLinearIndex :: ix -- ^ Size
+  toLinearIndex :: Sz ix -- ^ Size
                 -> ix -- ^ Index
                 -> Int
   default toLinearIndex :: Index (Lower ix) => ix -> ix -> Int
@@ -174,16 +188,16 @@
   {-# INLINE [1] toLinearIndexAcc #-}
 
   -- | Compute an index from size and linear index
-  fromLinearIndex :: ix -> Int -> ix
-  default fromLinearIndex :: Index (Lower ix) => ix -> Int -> ix
+  fromLinearIndex :: Sz ix -> Int -> ix
+  default fromLinearIndex :: Index (Lower ix) => Sz ix -> Int -> ix
   fromLinearIndex sz k = consDim q ixL
     where !(q, ixL) = fromLinearIndexAcc (snd (unconsDim sz)) k
   {-# INLINE [1] fromLinearIndex #-}
 
   -- | Compute an index from size and linear index using an accumulator, thus trying to optimize for
   -- tail recursion while getting the index computed.
-  fromLinearIndexAcc :: ix -> Int -> (Int, ix)
-  default fromLinearIndexAcc :: Index (Lower ix) => ix -> Int -> (Int, ix)
+  fromLinearIndexAcc ::Sz  ix -> Int -> (Int, ix)
+  default fromLinearIndexAcc :: Index (Lower ix) => Sz ix -> Int -> (Int, ix)
   fromLinearIndexAcc ix' !k = (q, consDim r ixL)
     where !(m, ix) = unconsDim ix'
           !(kL, ixL) = fromLinearIndexAcc ix k
@@ -192,13 +206,13 @@
 
   -- | A way to make sure index is withing the bounds for the supplied size. Takes two functions
   -- that will be invoked whenever index (2nd arg) is outsize the supplied size (1st arg)
-  repairIndex :: ix -- ^ Size
+  repairIndex :: Sz ix -- ^ Size
               -> ix -- ^ Index
               -> (Int -> Int -> Int) -- ^ Repair when below zero
               -> (Int -> Int -> Int) -- ^ Repair when higher than size
               -> ix
   default repairIndex :: Index (Lower ix)
-    => ix -> ix -> (Int -> Int -> Int) -> (Int -> Int -> Int) -> ix
+    => Sz ix -> ix -> (Int -> Int -> Int) -> (Int -> Int -> Int) -> ix
   repairIndex !sz !ix rBelow rOver =
     consDim (repairIndex n i rBelow rOver) (repairIndex szL ixL rBelow rOver)
     where !(n, szL) = unconsDim sz
@@ -330,15 +344,15 @@
   {-# INLINE [1] unsnocDim #-}
   getIndex (i2,  _) 2 = Just i2
   getIndex ( _, i1) 1 = Just i1
-  getIndex _      _ = Nothing
+  getIndex _      _   = Nothing
   {-# INLINE [1] getIndex #-}
   setIndex (_, i1) 2 i2 = Just (i2, i1)
   setIndex (i2, _) 1 i1 = Just (i2, i1)
-  setIndex _      _ _ = Nothing
+  setIndex _      _ _   = Nothing
   {-# INLINE [1] setIndex #-}
   dropDim (_, i1) 2 = Just i1
   dropDim (i2, _) 1 = Just i2
-  dropDim _      _ = Nothing
+  dropDim _      _  = Nothing
   {-# INLINE [1] dropDim #-}
   pullOutDim (i2, i1) 2 = Just (i2, i1)
   pullOutDim (i2, i1) 1 = Just (i1, i2)
@@ -376,22 +390,22 @@
   setIndex ( _, i2, i1) 3 i3 = Just (i3, i2, i1)
   setIndex (i3,  _, i1) 2 i2 = Just (i3, i2, i1)
   setIndex (i3, i2,  _) 1 i1 = Just (i3, i2, i1)
-  setIndex _      _ _    = Nothing
+  setIndex _      _ _        = Nothing
   {-# INLINE [1] setIndex #-}
   dropDim ( _, i2, i1) 3 = Just (i2, i1)
   dropDim (i3,  _, i1) 2 = Just (i3, i1)
   dropDim (i3, i2,  _) 1 = Just (i3, i2)
-  dropDim _      _    = Nothing
+  dropDim _      _       = Nothing
   {-# INLINE [1] dropDim #-}
   pullOutDim (i3, i2, i1) 3 = Just (i3, (i2, i1))
   pullOutDim (i3, i2, i1) 2 = Just (i2, (i3, i1))
   pullOutDim (i3, i2, i1) 1 = Just (i1, (i3, i2))
-  pullOutDim _      _    = Nothing
+  pullOutDim _      _       = Nothing
   {-# INLINE [1] pullOutDim #-}
   insertDim (i2, i1) 3 i3 = Just (i3, i2, i1)
   insertDim (i3, i1) 2 i2 = Just (i3, i2, i1)
   insertDim (i3, i2) 1 i1 = Just (i3, i2, i1)
-  insertDim _      _ _ = Nothing
+  insertDim _      _ _    = Nothing
   pureIndex i = (i, i, i)
   {-# INLINE [1] pureIndex #-}
   liftIndex2 f (i3, i2, i1) (i3', i2', i1') = (f i3 i3', f i2 i2', f i1 i1')
@@ -504,7 +518,7 @@
   {-# INLINE [1] liftIndex2 #-}
 
 -- | Helper function for throwing out of bounds errors
-errorIx :: (Show ix, Show ix') => String -> ix -> ix' -> a
+errorIx :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a
 errorIx fName sz ix =
   error $
   fName ++
@@ -513,7 +527,7 @@
 
 
 -- | Helper function for throwing error when sizes do not match
-errorSizeMismatch :: (Show ix, Show ix') => String -> ix -> ix' -> a
+errorSizeMismatch :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a
 errorSizeMismatch fName sz sz' =
   error $ fName ++ ": Mismatch in size of arrays " ++ show sz ++ " vs " ++ show sz'
 {-# NOINLINE errorSizeMismatch #-}
diff --git a/src/Data/Massiv/Core/Index/Stride.hs b/src/Data/Massiv/Core/Index/Stride.hs
--- a/src/Data/Massiv/Core/Index/Stride.hs
+++ b/src/Data/Massiv/Core/Index/Stride.hs
@@ -96,7 +96,7 @@
 {-# INLINE strideStart #-}
 
 -- | Adjust size according to the stride.
-strideSize :: Index ix => Stride ix -> ix -> ix
+strideSize :: Index ix => Stride ix -> Sz ix -> ix
 strideSize (SafeStride stride) sz = liftIndex (+ 1) $ liftIndex2 div (liftIndex (subtract 1) sz) stride
 {-# INLINE strideSize #-}
 
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
@@ -239,7 +239,7 @@
 unsafeGenerateParM ::
      (Elt LN ix e ~ Array LN (Lower ix) e, Index ix, Monad m, Ragged L (Lower ix) e)
   => [Int]
-  -> ix
+  -> Sz ix
   -> (ix -> m e)
   -> m (Array L ix e)
 unsafeGenerateParM wws !sz f = do
@@ -323,7 +323,7 @@
   , Ragged r (Lower ix) e
   , Elt r ix e ~ Array r (Lower ix) e )
   => Comp
-  -> ix
+  -> Sz ix
   -> (ix -> e)
   -> Array r ix e
 unsafeGenerateN Seq sz f = runIdentity $ unsafeGenerateM Seq sz (return . f)
diff --git a/tests/Data/Massiv/Core/IndexSpec.hs b/tests/Data/Massiv/Core/IndexSpec.hs
--- a/tests/Data/Massiv/Core/IndexSpec.hs
+++ b/tests/Data/Massiv/Core/IndexSpec.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE ExplicitNamespaces #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE FlexibleContexts    #-}
 {-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE GADTs               #-}
@@ -7,7 +9,7 @@
 module Data.Massiv.Core.IndexSpec (Sz(..), SzZ(..), SzIx(..), DimIx(..), spec) where
 
 import           Control.Monad
-import           Data.Massiv.Core.Index
+import           Data.Massiv.Core.Index          hiding (type Sz, pattern Sz)
 import           Data.Functor.Identity
 import           Test.Hspec
 import           Test.QuickCheck
diff --git a/tests/Data/Massiv/CoreArbitrary.hs b/tests/Data/Massiv/CoreArbitrary.hs
--- a/tests/Data/Massiv/CoreArbitrary.hs
+++ b/tests/Data/Massiv/CoreArbitrary.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE ExplicitNamespaces #-}
+{-# LANGUAGE PatternSynonyms #-}
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
@@ -25,7 +27,7 @@
 
 import           Control.DeepSeq            (NFData, deepseq)
 import           Control.Exception          (Exception, SomeException, catch)
-import           Data.Massiv.Array
+import           Data.Massiv.Array          hiding (type Sz, pattern Sz)
 import           Data.Massiv.Core.IndexSpec hiding (spec)
 import           Data.Typeable
 import           Test.QuickCheck
