diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,16 @@
+2.1.0.0 [2026.01.27]
+-------------
+* New API for working with vectors that are not parametric in element:
+  `Data.Vector.Fixed.Mono`. It support data types like `data V2 = V2 !Double
+  !Double` as well as all existing data types.
+* Support for GHC<9.2 dropped.
+* `Prim` could be derived using `ViaFixed` by deriving via mechanism and add
+  data types defined in library now has `Prim` instance.
+* `Foldable1` could be derived using `ViaFixed`. All types for which it could be
+  defined now has it. For GHC<9.6 `foldable1-classes-compat` is used.
+* `ifoldl'` added.
+
+
 2.0.0.0 [2025.07.10]
 ------------------
 * Type family `Dim` returns Peano numbers instead of standard type level
diff --git a/Data/Vector/Fixed.hs b/Data/Vector/Fixed.hs
--- a/Data/Vector/Fixed.hs
+++ b/Data/Vector/Fixed.hs
@@ -1,6 +1,7 @@
-{-# LANGUAGE CPP                   #-}
+{-# LANGUAGE MagicHash             #-}
 {-# LANGUAGE PolyKinds             #-}
 {-# LANGUAGE QuantifiedConstraints #-}
+{-# LANGUAGE UnboxedTuples         #-}
 {-# LANGUAGE UndecidableInstances  #-}
 -- |
 -- @fixed-vector@ library provides general API for working with short
@@ -128,6 +129,7 @@
   , fold
   , foldMap
   , ifoldl
+  , ifoldl'
   , ifoldr
   , foldM
   , ifoldM
@@ -188,23 +190,30 @@
   , sequenceA
   ) where
 
-import Control.Applicative (Applicative(..))
-import Control.DeepSeq     (NFData(..))
+import Control.Applicative     (Applicative(..))
+import Control.DeepSeq         (NFData(..))
+import Control.Monad.Primitive (PrimBase(..))
 import Data.Coerce
-import Data.Data           (Data)
-import Data.Monoid         (Monoid(..))
-import Data.Semigroup      (Semigroup(..))
-import Data.Foldable       qualified as F
-import Data.Traversable    qualified as T
-import Foreign.Storable    (Storable(..))
+import Data.Data               (Data)
+import Data.Monoid             (Monoid(..))
+import Data.Semigroup          (Semigroup(..))
+import Data.Foldable           qualified as F
+import Data.Traversable        qualified as T
+import Data.Foldable1          qualified as F1
+import Data.Primitive.Types    (Prim(..))
+import Foreign.Storable        (Storable(..))
 import GHC.TypeLits
+import GHC.Exts                (Proxy#,proxy#,(*#),(+#),Int(..),Int#)
+import GHC.ST                  (ST(..))
 
-import Data.Vector.Fixed.Cont     (Vector(..),Dim,length,ContVec,PeanoNum(..),
-                                   vector,cvec,empty,Arity,ArityPeano,Fun(..),accum,apply)
-import Data.Vector.Fixed.Cont     qualified as C
+import Data.Vector.Fixed.Cont  (Vector(..),Dim,length,ContVec,PeanoNum(..),
+                                vector,cvec,empty,Arity,ArityPeano,Fun(..),accum,apply)
+import Data.Vector.Fixed.Cont  qualified as C
+import Data.Vector.Fixed.Mono  qualified as FM
 import Data.Vector.Fixed.Internal as I
+import Data.Vector.Fixed.Compat
 
-import Prelude (Show(..),Eq(..),Ord(..),Num(..),Functor(..),id,(.),($),(<$>))
+import Prelude (Show(..),Eq(..),Ord(..),Num(..),Functor(..),id,(.),($),(<$>),undefined,flip)
 
 
 -- $construction
@@ -254,15 +263,24 @@
   Nil  :: VecPeano 'Z a
   Cons :: a -> VecPeano n a -> VecPeano ('S n) a
 
-type instance Dim (VecList  n) = C.Peano n
-type instance Dim (VecPeano n) = n
+type instance Dim (VecList  n)   = C.Peano n
+type instance Dim (VecList  n a) = C.Peano n
+type instance Dim (VecPeano n)   = n
+type instance Dim (VecPeano n a) = n
 
 instance Arity n => Vector (VecList n) a where
   construct = VecList <$> construct @(VecPeano (C.Peano n)) @a
   inspect (VecList v) = inspect v
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance Arity n => FM.Prod a (VecList n a) where
+  construct = construct
+  inspect   = inspect
+  {-# INLINE construct #-}
+  {-# INLINE inspect   #-}
+instance Arity n => FM.Vector a (VecList n a) where
 
+
 instance C.ArityPeano n => Vector (VecPeano n) a where
   construct = accum
     (\(T_List f) a -> T_List (f . Cons a))
@@ -275,6 +293,12 @@
       step (Flip (Cons a xs)) = (a, Flip xs)
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance C.ArityPeano n => FM.Prod a (VecPeano n a) where
+  construct = construct
+  inspect   = inspect
+  {-# INLINE construct #-}
+  {-# INLINE inspect   #-}
+instance C.ArityPeano n => FM.Vector a (VecPeano n a) where
 
 newtype Flip f a n = Flip (f n a)
 newtype T_List a n k = T_List (VecPeano k a -> VecPeano n a)
@@ -284,6 +308,9 @@
 deriving via ViaFixed (VecList n) instance (Arity n) => Functor     (VecList n)
 deriving via ViaFixed (VecList n) instance (Arity n) => Applicative (VecList n)
 deriving via ViaFixed (VecList n) instance (Arity n) => F.Foldable  (VecList n)
+-- | @since @2.0.1.0
+deriving via ViaFixed (VecList n)
+    instance (Arity n, C.Peano n ~ S k) => F1.Foldable1 (VecList n)
 
 instance Arity n => T.Traversable (VecList n) where
   sequence  = sequence
@@ -302,12 +329,17 @@
 deriving via ViaFixed (VecList n) a instance (Arity n, Semigroup a) => Semigroup (VecList n a)
 deriving via ViaFixed (VecList n) a instance (Arity n, Monoid    a) => Monoid    (VecList n a)
 deriving via ViaFixed (VecList n) a instance (Arity n, Storable  a) => Storable  (VecList n a)
+-- | @since 2.0.1.0
+deriving via ViaFixed (VecList n) a instance (Arity n, Prim      a) => Prim      (VecList n a)
 
 
 
 deriving via ViaFixed (VecPeano n) instance (ArityPeano n) => Functor     (VecPeano n)
 deriving via ViaFixed (VecPeano n) instance (ArityPeano n) => Applicative (VecPeano n)
 deriving via ViaFixed (VecPeano n) instance (ArityPeano n) => F.Foldable  (VecPeano n)
+-- | @since @2.0.1.0
+deriving via ViaFixed (VecPeano n)
+    instance (ArityPeano n, n ~ S k) => F1.Foldable1 (VecPeano n)
 
 instance ArityPeano n => T.Traversable (VecPeano n) where
   sequence  = sequence
@@ -326,6 +358,8 @@
 deriving via ViaFixed (VecPeano n) a instance (ArityPeano n, Semigroup a) => Semigroup (VecPeano n a)
 deriving via ViaFixed (VecPeano n) a instance (ArityPeano n, Monoid    a) => Monoid    (VecPeano n a)
 deriving via ViaFixed (VecPeano n) a instance (ArityPeano n, Storable  a) => Storable  (VecPeano n a)
+-- | @since 2.0.1.0
+deriving via ViaFixed (VecPeano n) a instance (ArityPeano n, Prim      a) => Prim      (VecPeano n a)
 
 
 
@@ -333,6 +367,10 @@
 newtype Only a = Only a
                  deriving (Show,Eq,Ord,Data,Functor,F.Foldable,T.Traversable)
 
+-- | @since @2.0.1.0
+deriving via ViaFixed Only instance F1.Foldable1 Only
+
+
 instance Monoid a => Monoid (Only a) where
   mempty  = Only mempty
   mappend = (<>)
@@ -344,13 +382,20 @@
 instance NFData a => NFData (Only a) where
   rnf (Only a) = rnf a
 
-type instance Dim Only = C.N1
+type instance Dim  Only    = C.N1
+type instance Dim (Only a) = C.N1
 
 instance Vector Only a where
   construct = Fun Only
   inspect (Only a) (Fun f) = f a
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance FM.Prod a (Only a) where
+  construct = construct
+  inspect   = inspect
+  {-# INLINE construct #-}
+  {-# INLINE inspect   #-}
+instance FM.Vector a (Only a) where
 
 instance (Storable a) => Storable (Only a) where
   alignment = coerce (alignment @a)
@@ -366,13 +411,20 @@
 instance NFData (Empty a) where
   rnf Empty = ()
 
-type instance Dim Empty = 'Z
+type instance Dim  Empty    = 'Z
+type instance Dim (Empty a) = 'Z
 
 instance Vector Empty a where
   construct = Fun Empty
   inspect _ (Fun b) = b
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
+instance FM.Prod a (Empty a) where
+  construct = construct
+  inspect   = inspect
+  {-# INLINE construct #-}
+  {-# INLINE inspect   #-}
+instance FM.Vector a (Empty a) where
 
 type Tuple2 a = (a,a)
 type Tuple3 a = (a,a,a)
@@ -389,7 +441,8 @@
 --   'Storable', 'NFData', 'Functor', 'Applicative', 'Foldable'.
 newtype ViaFixed v a = ViaFixed (v a)
 
-type instance Dim (ViaFixed v) = Dim v
+type instance Dim (ViaFixed v)   = Dim v
+type instance Dim (ViaFixed v a) = Dim v
 
 instance Vector v a => Vector (ViaFixed v) a where
   construct = ViaFixed <$> construct
@@ -397,6 +450,13 @@
   {-# INLINE construct #-}
   {-# INLINE inspect   #-}
 
+instance Vector v a => FM.Prod a (ViaFixed v a) where
+  construct = ViaFixed <$> construct
+  inspect (ViaFixed v) = inspect v
+  {-# INLINE construct #-}
+  {-# INLINE inspect   #-}
+instance Vector v a => FM.Vector a (ViaFixed v a) where
+
 instance (Vector v a, Show a) => Show (ViaFixed v a) where
   showsPrec = coerce (I.showsPrec @v @a)
 
@@ -430,6 +490,66 @@
   {-# INLINE peek      #-}
   {-# INLINE poke      #-}
 
+-- | @since 2.0.1.0
+instance (Vector v a, Prim a) => Prim (ViaFixed v a) where
+  sizeOf# _ = sizeOf# (undefined :: a) *# dim where
+    dim = case C.peanoToInt (proxy# @(Dim v)) of I# i -> i
+  alignment# _ = alignment# (undefined :: a)
+  {-# INLINE sizeOf#    #-}
+  {-# INLINE alignment# #-}
+  -- Bytearray
+  indexByteArray# ba k
+    = generate $ \(I# i) -> indexByteArray# ba (off +# i)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  readByteArray# ba k
+    = internal
+    $ generateM
+    $ \(I# i) -> ST (\s -> readByteArray# ba (off +# i) s)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  writeByteArray# ba k (ViaFixed vec) =
+    case loop of
+      ST st -> \s -> case st s of
+                       (# s', () #) -> s'
+    where
+      off  = vectorOff (proxy# @(Dim v))  k
+      loop = flip imapM_ vec $ \(I# i) a -> ST $ \s ->
+        (# writeByteArray# ba (off +# i) a s, () #)
+  {-# INLINE indexByteArray# #-}
+  {-# INLINE readByteArray#  #-}
+  {-# INLINE writeByteArray# #-}
+  -- Addr
+  indexOffAddr# addr k
+    = generate $ \(I# i) -> indexOffAddr# addr (off +# i)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  readOffAddr# ba k
+    = internal
+    $ generateM
+    $ \(I# i) -> ST (\s -> readOffAddr# ba (off +# i) s)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  writeOffAddr# addr k (ViaFixed vec) =
+    case loop of
+      ST st -> \s -> case st s of
+                       (# s', () #) -> s'
+    where
+      off  = vectorOff (proxy# @(Dim v))  k
+      loop = flip imapM_ vec $ \(I# i) a -> ST $ \s ->
+        (# writeOffAddr# addr (off +# i) a s, () #)
+  {-# INLINE indexOffAddr# #-}
+  {-# INLINE readOffAddr#  #-}
+  {-# INLINE writeOffAddr# #-}
+
+
+vectorOff :: (ArityPeano n) => Proxy# n -> Int# -> Int#
+{-# INLINE vectorOff #-}
+vectorOff n k =
+  case C.peanoToInt n of
+    I# dim -> dim *# k
+
+
 instance (forall a. Vector v a) => Functor (ViaFixed v) where
   fmap = map
   {-# INLINE fmap #-}
@@ -454,6 +574,7 @@
   toList     = toList
   sum        = sum
   product    = foldl' (*) 0
+  length     = length
   {-# INLINE foldMap' #-}
   {-# INLINE foldr    #-}
   {-# INLINE foldl    #-}
@@ -461,13 +582,29 @@
   {-# INLINE toList   #-}
   {-# INLINE sum      #-}
   {-# INLINE product  #-}
--- GHC<9.2 fails to compile this
-#if MIN_VERSION_base(4,16,0)
-  length = length
-  {-# INLINE length #-}
-#endif
+  {-# INLINE length   #-}
 
 
+-- | @since @2.0.1.0
+instance (forall a. Vector v a, Dim v ~ S k) => F1.Foldable1 (ViaFixed v) where
+  fold1       = foldl1 (<>)
+  foldMap1  f = F1.foldMap1  f . cvec
+  foldMap1' f = F1.foldMap1' f . cvec
+  toNonEmpty  = F1.toNonEmpty . cvec
+  head        = head
+  last        = F1.last . cvec
+  maximum     = maximum
+  minimum     = minimum
+  {-# INLINE fold1      #-}
+  {-# INLINE foldMap1   #-}
+  {-# INLINE foldMap1'  #-}
+  {-# INLINE toNonEmpty #-}
+  {-# INLINE maximum    #-}
+  {-# INLINE minimum    #-}
+  {-# INLINE head       #-}
+  {-# INLINE last       #-}
+
+
 ----------------------------------------------------------------
 -- Patterns
 ----------------------------------------------------------------
@@ -475,34 +612,26 @@
 pattern V1 :: (Vector v a, Dim v ~ C.N1) => a -> v a
 pattern V1 x <- (convert -> (Only x)) where
   V1 x = mk1 x
-#if MIN_VERSION_base(4,16,0)
 {-# INLINE   V1 #-}
 {-# COMPLETE V1 #-}
-#endif
 
 pattern V2 :: (Vector v a, Dim v ~ C.N2) => a -> a -> v a
 pattern V2 x y <- (convert -> (x,y)) where
   V2 x y = mk2 x y
-#if MIN_VERSION_base(4,16,0)
 {-# INLINE   V2 #-}
 {-# COMPLETE V2 #-}
-#endif
 
 pattern V3 :: (Vector v a, Dim v ~ C.N3) => a -> a -> a -> v a
 pattern V3 x y z <- (convert -> (x,y,z)) where
   V3 x y z = mk3 x y z
-#if MIN_VERSION_base(4,16,0)
 {-# INLINE   V3 #-}
 {-# COMPLETE V3 #-}
-#endif
 
 pattern V4 :: (Vector v a, Dim v ~ C.N4) => a -> a -> a -> a -> v a
 pattern V4 t x y z <- (convert -> (t,x,y,z)) where
   V4 t x y z = mk4 t x y z
-#if MIN_VERSION_base(4,16,0)
 {-# INLINE   V4 #-}
 {-# COMPLETE V4 #-}
-#endif
 
 -- $setup
 --
diff --git a/Data/Vector/Fixed/Boxed.hs b/Data/Vector/Fixed/Boxed.hs
--- a/Data/Vector/Fixed/Boxed.hs
+++ b/Data/Vector/Fixed/Boxed.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE MagicHash            #-}
+{-# LANGUAGE UnboxedTuples        #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- |
 -- Lazy vector which could hold any value. For strict variant see
@@ -21,15 +22,19 @@
 import Data.Monoid          (Monoid(..))
 import Data.Semigroup       (Semigroup(..))
 import Data.Data
+import Data.Primitive.Types (Prim)
 import qualified Data.Foldable    as F
+import qualified Data.Foldable1   as F1
 import qualified Data.Traversable as T
-import Foreign.Storable (Storable(..))
+import Foreign.Storable (Storable)
 import GHC.TypeLits
 import GHC.Exts (proxy#)
 import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..)
                , ($!),error,(<$>))
 
+import Data.Vector.Fixed.Compat 
 import Data.Vector.Fixed hiding (index)
+import Data.Vector.Fixed.Mono qualified as FM
 import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index)
 import qualified Data.Vector.Fixed.Cont     as C
 import           Data.Vector.Fixed.Cont     (ArityPeano(..))
@@ -52,9 +57,10 @@
 type Vec4 = Vec 4
 type Vec5 = Vec 5
 
-type instance Mutable (Vec  n) = MVec n
-type instance Dim     (Vec  n) = Peano n
-type instance DimM    (MVec n) = Peano n
+type instance Mutable (Vec  n)   = MVec n
+type instance Dim     (Vec  n)   = Peano n
+type instance Dim     (Vec  n a) = Peano n
+type instance DimM    (MVec n)   = Peano n
 
 
 ----------------------------------------------------------------
@@ -64,6 +70,9 @@
 deriving via ViaFixed (Vec n) instance Arity n => Functor    (Vec n)
 deriving via ViaFixed (Vec n) instance Arity n => Applicative (Vec n)
 deriving via ViaFixed (Vec n) instance Arity n => F.Foldable  (Vec n)
+-- | @since @2.0.1.0
+deriving via ViaFixed (Vec n)
+    instance (Arity n, Peano n ~ S k) => F1.Foldable1 (Vec n)
 
 instance Arity n => T.Traversable (Vec n) where
   sequence  = sequence
@@ -82,6 +91,8 @@
 deriving via ViaFixed (Vec n) a instance (Arity n, Semigroup a) => Semigroup (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Arity n, Monoid    a) => Monoid    (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Arity n, Storable  a) => Storable  (Vec n a)
+-- | @since 2.0.1.0
+deriving via ViaFixed (Vec n) a instance (Arity n, Prim      a) => Prim      (Vec n a)
 
 instance (Arity n) => MVector (MVec n) a where
   basicNew =
@@ -117,6 +128,12 @@
   {-# INLINE construct  #-}
   {-# INLINE inspect    #-}
   {-# INLINE basicIndex #-}
+instance (Arity n) => FM.Prod a (Vec n a) where
+  construct  = constructVec
+  inspect    = inspectVec
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+instance (Arity n) => FM.Vector a (Vec n a)
 
 instance (Typeable n, Arity n, Data a) => Data (Vec n a) where
   gfoldl       = C.gfoldl
diff --git a/Data/Vector/Fixed/Compat.hs b/Data/Vector/Fixed/Compat.hs
new file mode 100644
--- /dev/null
+++ b/Data/Vector/Fixed/Compat.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE CPP #-}
+-- | Compatibility for old GHC
+module Data.Vector.Fixed.Compat
+  (
+#if MIN_VERSION_base(4,17,0)
+  type(~)
+#endif
+  ) where
diff --git a/Data/Vector/Fixed/Cont.hs b/Data/Vector/Fixed/Cont.hs
--- a/Data/Vector/Fixed/Cont.hs
+++ b/Data/Vector/Fixed/Cont.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP                  #-}
 {-# LANGUAGE MagicHash            #-}
 {-# LANGUAGE PolyKinds            #-}
 {-# LANGUAGE UndecidableInstances #-}
@@ -30,7 +29,7 @@
   , shuffleFun
   , withFun
   , dimapFun
-    -- * Vector type class
+    -- * Vector type Boxedclass
   , Dim
   , Vector(..)
   , length
@@ -126,9 +125,11 @@
 import Data.Kind             (Type)
 import Data.Functor.Identity (Identity(..))
 import Data.Typeable         (Proxy(..))
-import qualified Data.Foldable    as F
-import qualified Data.Traversable as T
-import Unsafe.Coerce       (unsafeCoerce)
+import Data.Foldable         qualified as F
+import Data.Traversable      qualified as T
+import Data.List.NonEmpty    qualified as NE
+import Data.Foldable1        qualified as F1
+import Unsafe.Coerce         (unsafeCoerce)
 import GHC.TypeLits
 import GHC.Exts       (Proxy#, proxy#)
 import Prelude        ( Bool(..), Int, Maybe(..), Either(..)
@@ -136,7 +137,7 @@
                       , Semigroup(..), Monoid(..)
                       , (.), ($), (&&), (||), (<$>), id, error, otherwise, fst
                       )
-
+import Data.Vector.Fixed.Compat
 
 ----------------------------------------------------------------
 -- Naturals
@@ -434,7 +435,7 @@
 ----------------------------------------------------------------
 
 -- | Size of vector expressed as Peano natural.
-type family Dim (v :: Type -> Type) :: PeanoNum
+type family Dim (v :: k) :: PeanoNum
 
 -- | Type class for vectors with fixed length. Instance should provide
 --   two functions: one to create vector from @N@ elements and another
@@ -477,7 +478,8 @@
 --   Church encoded N-element vector.
 newtype ContVec n a = ContVec (forall r. Fun n a r -> r)
 
-type instance Dim (ContVec n) = n
+type instance Dim (ContVec n)   = n
+type instance Dim (ContVec n a) = n
 
 -- | Cons values to the @ContVec@.
 consPeano :: a -> ContVec n a -> ContVec ('S n) a
@@ -532,6 +534,7 @@
   toList     = toList
   sum        = sum
   product    = foldl' (*) 0
+  length     = length
   {-# INLINE foldMap' #-}
   {-# INLINE foldr    #-}
   {-# INLINE foldl    #-}
@@ -539,12 +542,28 @@
   {-# INLINE toList   #-}
   {-# INLINE sum      #-}
   {-# INLINE product  #-}
--- GHC<9.2 fails to compile this
-#if MIN_VERSION_base(4,16,0)
-  length = length
   {-# INLINE length #-}
-#endif
 
+
+instance (ArityPeano n, n ~ S k) => F1.Foldable1 (ContVec n) where
+  fold1        = foldl1 (<>)
+  foldMap1   f = foldl1  (<>) . map f
+  foldMap1'  f = foldl1' (<>) . map f
+  toNonEmpty v = dictionaryPred (proxy# @n)
+               $ head v NE.:| toList (tail v)
+  maximum = maximum
+  minimum = minimum
+  head    = head
+  last    = F1.last . F1.toNonEmpty
+  {-# INLINE fold1      #-}
+  {-# INLINE foldMap1   #-}
+  {-# INLINE foldMap1'  #-}
+  {-# INLINE toNonEmpty #-}
+  {-# INLINE maximum    #-}
+  {-# INLINE minimum    #-}
+  {-# INLINE head       #-}
+  {-# INLINE last       #-}
+
 instance (ArityPeano n) => T.Traversable (ContVec n) where
   sequence  = sequence
   sequenceA = sequence
@@ -1013,7 +1032,6 @@
   $ runContVec
   $ uncurryFirst pure
 
-
 -- | /O(n)/ Get value at specified index.
 index :: ArityPeano n => Int -> ContVec n a -> a
 {-# INLINE index #-}
@@ -1284,7 +1302,8 @@
 -- Instances
 ----------------------------------------------------------------
 
-type instance Dim Complex = N2
+type instance Dim Complex     = N2
+type instance Dim (Complex a) = N2
 
 instance Vector Complex a where
   construct = Fun (:+)
@@ -1293,7 +1312,8 @@
   {-# INLINE inspect #-}
 
 
-type instance Dim Identity = N1
+type instance Dim Identity     = N1
+type instance Dim (Identity a) = N1
 
 instance Vector Identity a where
   construct = Fun Identity
@@ -1302,7 +1322,8 @@
   {-# INLINE inspect #-}
 
 
-type instance Dim ((,) a) = N2
+type instance Dim ((,) a)   = N2
+type instance Dim ((,) a b) = N2
 
 -- | Note this instance (and other instances for tuples) is
 --   essentially monomorphic in element type. Vector type /v/ of 2
@@ -1315,7 +1336,8 @@
   {-# INLINE inspect #-}
 
 
-type instance Dim ((,,) a b) = N3
+type instance Dim ((,,) a b)   = N3
+type instance Dim ((,,) a b c) = N3
 
 instance (b~a, c~a) => Vector ((,,) b c) a where
   construct = Fun (,,)
@@ -1324,7 +1346,8 @@
   {-# INLINE inspect #-}
 
 
-type instance Dim ((,,,) a b c) = N4
+type instance Dim ((,,,) a b c)   = N4
+type instance Dim ((,,,) a b c d) = N4
 
 instance (b~a, c~a, d~a) => Vector ((,,,) b c d) a where
   construct = Fun (,,,)
@@ -1333,7 +1356,8 @@
   {-# INLINE inspect #-}
 
 
-type instance Dim ((,,,,) a b c d) = N5
+type instance Dim ((,,,,) a b c d)   = N5
+type instance Dim ((,,,,) a b c d e) = N5
 
 instance (b~a, c~a, d~a, e~a) => Vector ((,,,,) b c d e) a where
   construct = Fun (,,,,)
@@ -1342,7 +1366,8 @@
   {-# INLINE inspect #-}
 
 
-type instance Dim ((,,,,,) a b c d e) = N6
+type instance Dim ((,,,,,) a b c d e)   = N6
+type instance Dim ((,,,,,) a b c d e f) = N6
 
 instance (b~a, c~a, d~a, e~a, f~a) => Vector ((,,,,,) b c d e f) a where
   construct = Fun (,,,,,)
@@ -1351,7 +1376,8 @@
   {-# INLINE inspect #-}
 
 
-type instance Dim ((,,,,,,) a b c d e f) = N7
+type instance Dim ((,,,,,,) a b c d e f)   = N7
+type instance Dim ((,,,,,,) a b c d e f g) = N7
 
 instance (b~a, c~a, d~a, e~a, f~a, g~a) => Vector ((,,,,,,) b c d e f g) a where
   construct = Fun (,,,,,,)
@@ -1359,7 +1385,8 @@
   {-# INLINE construct #-}
   {-# INLINE inspect #-}
 
-type instance Dim Proxy = Z
+type instance Dim Proxy     = Z
+type instance Dim (Proxy a) = Z
 
 instance Vector Proxy a where
   construct = Fun Proxy
diff --git a/Data/Vector/Fixed/Internal.hs b/Data/Vector/Fixed/Internal.hs
--- a/Data/Vector/Fixed/Internal.hs
+++ b/Data/Vector/Fixed/Internal.hs
@@ -273,9 +273,7 @@
           => proxy k -> (a -> f a) -> (v a -> f (v a))
 {-# INLINE elementTy #-}
 elementTy _ f v
-  = fmap vector
-  $ inspect (C.cvec v) 
-    (C.lensF (proxy# @(Peano k)) f construct)
+  = inspect v (C.lensF (proxy# @(Peano k)) f construct)
 
 -- | Left fold over vector
 foldl :: Vector v a => (b -> a -> b) -> b -> v a -> b
@@ -607,7 +605,7 @@
 -- | Zip two vector elementwise using monadic function and discard
 --   result
 izipWithM_
-  :: (Vector v a, Vector v b, Vector v c, Applicative f, Vector v (f c))
+  :: (Vector v a, Vector v b, Vector v c, Applicative f)
   => (Int -> a -> b -> f c) -> v a -> v b -> f ()
 {-# INLINE izipWithM_ #-}
 izipWithM_ f xs ys = C.izipWithM_ f (C.cvec xs) (C.cvec ys)
diff --git a/Data/Vector/Fixed/Mono.hs b/Data/Vector/Fixed/Mono.hs
new file mode 100644
--- /dev/null
+++ b/Data/Vector/Fixed/Mono.hs
@@ -0,0 +1,974 @@
+{-# LANGUAGE DataKinds           #-}
+{-# LANGUAGE MagicHash           #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies        #-}
+{-# LANGUAGE UnboxedTuples       #-}
+module Data.Vector.Fixed.Mono
+  ( -- * Vector type class
+    Prod(..)
+  , Vector
+  , Dim
+  , C.Arity
+  , C.ArityPeano
+  , C.Fun(..)
+  , length
+    -- ** Peano numbers
+  , PeanoNum(..)
+  , Peano
+  , N1, N2, N3, N4, N5, N6, N7, N8
+    -- * Construction and destructions
+    -- $construction
+
+    -- ** Constructors
+  , mk0
+  , mk1
+  , mk2
+  , mk3
+  , mk4
+  , mk5
+  , mk6
+  , mk7
+  , mk8
+  , mkN
+    -- ** Pattern synonyms
+  , pattern V1
+  , pattern V2
+  , pattern V3
+  , pattern V4
+    -- * Functions
+    -- ** Creation
+  , replicate
+  , replicateM
+  , generate
+  , generateM
+  , unfoldr
+  , basis
+    -- ** Transformations
+  , head
+  , tail
+  , cons
+  , snoc
+  , concat
+  , reverse
+    -- ** Indexing & lenses
+  , C.Index
+  , (!)
+  , index
+  , set
+  , element
+  , elementTy
+    -- ** Maps
+  , map
+  , gmap
+  , mapM
+  , gmapM
+  , mapM_
+  , imap
+  , igmap
+  , imapM
+  , igmapM
+  , imapM_
+  , scanl
+  , scanl1
+  -- , traverse
+    -- ** Folds
+  , foldl
+  , foldl'
+  , foldr
+  , foldl1
+  , fold
+  , foldMap
+  , ifoldl
+  , ifoldl'
+  , ifoldr
+  , foldM
+  , ifoldM
+    -- *** Special folds
+  , sum
+  , maximum
+  , minimum
+  , and
+  , or
+  , all
+  , any
+  , find
+    -- ** Zips
+  , zipWith
+  , zipWith3
+  , zipWithM
+  , zipWithM_
+  , izipWith
+  , izipWith3
+  , izipWithM
+  , izipWithM_
+    -- *** Special zips
+  , eq
+  , ord
+    -- ** Conversion
+  , convert
+  , toList
+  , fromList
+  , fromList'
+  , fromListM
+  , fromFoldable
+    -- ** Continuation-based vectors
+  , C.ContVec
+  , vector
+  , cvec
+    -- * Instance deriving
+  , ViaFixed(..)
+  ) where
+
+import Control.DeepSeq         (NFData(..))
+import Control.Monad.Primitive (PrimBase(..))
+import Data.Complex
+import Data.Foldable           qualified as T
+import Data.Primitive.Types    (Prim(..))
+import Foreign.Ptr             (castPtr)
+import Foreign.Storable        (Storable(..))
+
+import GHC.Exts (Proxy#,proxy#,Int(..),Int#,(+#),(*#))
+import GHC.ST   (ST(..))
+
+import Prelude (Eq(..),Ord(..),Show(..),Num(..),Functor,Applicative,Monad
+               ,Semigroup(..),Monoid(..)
+               ,Bool,Maybe(..),Ordering
+               ,fmap,(<$>),(.),($),shows,flip,undefined
+               )
+
+import Data.Vector.Fixed.Compat
+import Data.Vector.Fixed.Cont qualified as C
+import Data.Vector.Fixed.Cont (Dim,Add,ArityPeano,Peano,Index,PeanoNum(..),
+                               N1,N2,N3,N4,N5,N6,N7,N8)
+
+
+
+----------------------------------------------------------------
+-- Classes
+----------------------------------------------------------------
+
+
+class C.ArityPeano (Dim v) => Prod a v | v -> a where
+  inspect   :: v -> C.Fun (Dim v) a r -> r
+  construct :: C.Fun (Dim v) a v
+
+class Prod a v => Vector a v
+
+-- | Convert regular vector to continuation based one.
+cvec :: (Prod a v) => v -> C.ContVec (Dim v) a
+cvec v = C.ContVec (inspect v)
+{-# INLINE[0] cvec #-}
+
+-- | Convert continuation to the vector.
+vector :: (Prod a v) => C.ContVec (Dim v) a -> v
+vector = C.runContVec construct
+{-# INLINE[1] vector #-}
+
+{-# RULES
+"cvec/vector[mono]" forall v.
+  cvec (vector v) = v
+  #-}
+
+
+
+----------------------------------------------------------------
+-- Constructors
+----------------------------------------------------------------
+
+mk0 :: forall v a. (Vector a v, Dim v ~ 'Z) => v
+mk0 = vector C.empty
+{-# INLINE mk0 #-}
+
+mk1 :: forall v a. (Vector a v, Dim v ~ N1) => a -> v
+mk1 a1 = vector $ C.mk1 a1
+{-# INLINE mk1 #-}
+
+mk2 :: forall v a. (Vector a v, Dim v ~ N2) => a -> a -> v
+mk2 a1 a2 = vector $ C.mk2 a1 a2
+{-# INLINE mk2 #-}
+
+mk3 :: forall v a. (Vector a v, Dim v ~ N3) => a -> a -> a -> v
+mk3 a1 a2 a3 = vector $ C.mk3 a1 a2 a3
+{-# INLINE mk3 #-}
+
+mk4 :: forall v a. (Vector a v, Dim v ~ N4) => a -> a -> a -> a -> v
+mk4 a1 a2 a3 a4 = vector $ C.mk4 a1 a2 a3 a4
+{-# INLINE mk4 #-}
+
+mk5 :: forall v a. (Vector a v, Dim v ~ N5) => a -> a -> a -> a -> a -> v
+mk5 a1 a2 a3 a4 a5 = vector $ C.mk5 a1 a2 a3 a4 a5
+{-# INLINE mk5 #-}
+
+mk6 :: forall v a. (Vector a v, Dim v ~ N6) => a -> a -> a -> a -> a -> a -> v
+mk6 a1 a2 a3 a4 a5 a6 = vector $ C.mk6 a1 a2 a3 a4 a5 a6
+{-# INLINE mk6 #-}
+
+mk7 :: forall v a. (Vector a v, Dim v ~ N7) => a -> a -> a -> a -> a -> a -> a -> v
+mk7 a1 a2 a3 a4 a5 a6 a7 = vector $ C.mk7 a1 a2 a3 a4 a5 a6 a7
+{-# INLINE mk7 #-}
+
+mk8 :: forall v a. (Vector a v, Dim v ~ N8) => a -> a -> a -> a -> a -> a -> a -> a -> v
+mk8 a1 a2 a3 a4 a5 a6 a7 a8 = vector $ C.mk8 a1 a2 a3 a4 a5 a6 a7 a8
+{-# INLINE mk8 #-}
+
+-- | N-ary constructor. Despite scary signature it's just N-ary
+--   function with additional type parameter which is used to fix type
+--   of vector being constructed. It could be used as:
+--
+--   > v = mkN (Proxy :: Proxy (Int,Int,Int)) 1 2 3
+--
+--   or using @TypeApplications@ syntax:
+--
+--   > v = mkN (Proxy @(Int,Int,Int)) 1 2 3
+--
+--   or if type of @v@ is fixed elsewhere
+--
+--   > v = mkN [v] 1 2 3
+mkN :: forall proxy v a. (Vector a v)
+    => proxy v -> C.Fn (Dim v) a v
+mkN _ = C.unFun (construct :: C.Fun (Dim v) a v)
+
+----------------------------------------------------------------
+-- Generic functions
+----------------------------------------------------------------
+
+-- | Length of vector. Function doesn't evaluate its argument.
+length :: forall v. C.ArityPeano (Dim v) => v -> Int
+{-# INLINE length #-}
+length _ = C.peanoToInt (proxy# @(Dim v))
+
+-- | Replicate value /n/ times.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec2)
+--   >>> replicate 1 :: Vec2 Int
+--   [1,1]
+--
+--   >>> replicate 2 :: (Double,Double,Double)
+--   (2.0,2.0,2.0)
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec4)
+--   >>> replicate "foo" :: Vec4 String
+--   ["foo","foo","foo","foo"]
+replicate :: forall v a. Vector a v => a -> v
+{-# INLINE replicate #-}
+replicate
+  = vector . C.replicate
+
+
+-- | Execute monadic action for every element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec2,Vec3)
+--   >>> replicateM (Just 3) :: Maybe (Vec3 Int)
+--   Just [3,3,3]
+--   >>> replicateM (putStrLn "Hi!") :: IO (Vec2 ())
+--   Hi!
+--   Hi!
+--   [(),()]
+replicateM :: forall v f a. (Vector a v, Applicative f) => f a -> f (v)
+{-# INLINE replicateM #-}
+replicateM
+  = fmap vector . C.replicateM
+
+
+-- | Unit vector along Nth axis. If index is larger than vector
+--   dimensions returns zero vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> basis 0 :: Vec3 Int
+--   [1,0,0]
+--   >>> basis 1 :: Vec3 Int
+--   [0,1,0]
+--   >>> basis 3 :: Vec3 Int
+--   [0,0,0]
+basis :: forall v a. (Vector a v, Num a) => Int -> v
+{-# INLINE basis #-}
+basis = vector . C.basis
+
+
+-- | Unfold vector.
+unfoldr :: forall v a b. (Vector a v) => (b -> (a,b)) -> b -> v
+{-# INLINE unfoldr #-}
+unfoldr f = vector . C.unfoldr f
+
+
+-- | Generate vector from function which maps element's index to its
+--   value.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Unboxed (Vec4)
+--   >>> generate (^2) :: Vec4 Int
+--   [0,1,4,9]
+generate :: forall v a. (Vector a v) => (Int -> a) -> v
+{-# INLINE generate #-}
+generate = vector . C.generate
+
+
+-- | Generate vector from monadic function which maps element's index
+--   to its value.
+generateM :: forall v f a. (Applicative f, Vector a v) => (Int -> f a) -> f v
+{-# INLINE generateM #-}
+generateM = fmap vector . C.generateM
+
+
+
+----------------------------------------------------------------
+
+-- | First element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let x = mk3 1 2 3 :: Vec3 Int
+--   >>> head x
+--   1
+head :: forall v k a. (Vector a v, Dim v ~ 'S k) => v -> a
+{-# INLINE head #-}
+head = C.head . cvec
+
+
+-- | Tail of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Complex
+--   >>> tail (1,2,3) :: Complex Double
+--   2.0 :+ 3.0
+tail :: forall v w a. (Vector a v, Vector a w, Dim v ~ 'S (Dim w))
+     => v -> w
+{-# INLINE tail #-}
+tail = vector . C.tail . cvec
+
+-- | Cons element to the vector
+cons :: forall v w a. (Vector a v, Vector a w, Dim w ~ 'S (Dim v))
+     => a -> v -> w
+{-# INLINE cons #-}
+cons a = vector . C.cons a . cvec
+
+-- | Append element to the vector
+snoc :: forall v w a. (Vector a v, Vector a w, Dim w ~ 'S (Dim v))
+     => a -> v -> w
+{-# INLINE snoc #-}
+snoc a = vector . C.snoc a . cvec
+
+concat :: forall v u w a.
+  ( Vector a v, Vector a u, Vector a w
+  , (Dim v `Add` Dim u) ~ Dim w
+  )
+  => v -> u -> w
+{-# INLINE concat #-}
+concat v u = vector $ C.concat (cvec v) (cvec u)
+
+-- | Reverse order of elements in the vector
+reverse :: forall v a. Vector a v => v -> v
+reverse = vector . C.reverse . cvec
+{-# INLINE reverse #-}
+
+
+-- | Retrieve vector's element at index. Generic implementation is
+--   /O(n)/ but more efficient one is used when possible.
+(!) :: forall v a. (Vector a v) => v -> Int -> a
+{-# INLINE (!) #-}
+v ! i = C.index i (cvec v)
+
+-- | Get element from vector at statically known index
+index :: forall v k a proxy. (Vector a v, Index (Peano k) (Dim v))
+      => v -> proxy k -> a
+{-# INLINE index #-}
+index v _ = inspect v (C.getF (proxy# @(Peano k)))
+
+-- | Set n'th element in the vector
+set :: forall v k a proxy. (Vector a v, Index (Peano k) (Dim v))
+    => proxy k -> a -> v -> v
+{-# INLINE set #-}
+set _ a v
+  = inspect v
+  $ C.putF (proxy# @(Peano k)) a construct
+
+-- | Twan van Laarhoven's lens for element of vector
+element :: forall v f a. (Vector a v, Functor f) => Int -> (a -> f a) -> (v -> f v)
+{-# INLINE element #-}
+element i f v = vector `fmap` C.element i f (cvec v)
+
+-- | Twan van Laarhoven's lens for element of vector with statically
+--   known index.
+elementTy
+  :: forall v f k a proxy. (Vector a v, Index (Peano k) (Dim v), Functor f)
+  => proxy k -> (a -> f a) -> (v -> f v)
+{-# INLINE elementTy #-}
+elementTy _ f v
+  = inspect v (C.lensF (proxy# @(Peano k)) f construct)
+
+-- | Left fold over vector
+foldl :: forall v b a. Vector a v => (b -> a -> b) -> b -> v -> b
+{-# INLINE foldl #-}
+foldl f x = C.foldl f x
+          . cvec
+
+-- | Strict left fold over vector
+foldl' :: forall v b a. Vector a v => (b -> a -> b) -> b -> v -> b
+{-# INLINE foldl' #-}
+foldl' f x = C.foldl' f x
+           . cvec
+
+-- | Right fold over vector
+foldr :: forall v b a. Vector a v => (a -> b -> b) -> b -> v -> b
+{-# INLINE foldr #-}
+foldr f x = C.foldr f x
+          . cvec
+
+
+-- | Left fold over vector
+foldl1 :: forall v a k. (Vector a v, Dim v ~ 'S k) => (a -> a -> a) -> v -> a
+{-# INLINE foldl1 #-}
+foldl1 f = C.foldl1 f
+         . cvec
+
+-- | Combine the elements of a structure using a monoid. Similar to
+--   'T.fold'
+fold :: forall v m. (Vector m v, Monoid m) => v -> m
+{-# INLINE fold #-}
+fold = T.fold
+     . cvec
+
+-- | Map each element of the structure to a monoid,
+--   and combine the results. Similar to 'T.foldMap'
+foldMap :: forall v m a. (Vector a v, Monoid m) => (a -> m) -> v -> m
+{-# INLINE foldMap #-}
+foldMap f = T.foldMap f
+          . cvec
+
+-- | Right fold over vector
+ifoldr :: forall v b a. Vector a v => (Int -> a -> b -> b) -> b -> v -> b
+{-# INLINE ifoldr #-}
+ifoldr f x = C.ifoldr f x
+           . cvec
+
+-- | Left fold over vector. Function is applied to each element and
+--   its index.
+ifoldl :: forall v b a. Vector a v => (b -> Int -> a -> b) -> b -> v -> b
+{-# INLINE ifoldl #-}
+ifoldl f z = C.ifoldl f z
+           . cvec
+
+-- | Strict left fold over vector. Function is applied to each element
+--   and its index.
+ifoldl' :: forall v b a. Vector a v => (b -> Int -> a -> b) -> b -> v -> b
+{-# INLINE ifoldl' #-}
+ifoldl' f z = C.ifoldl' f z
+            . cvec
+
+-- | Monadic fold over vector.
+foldM :: forall v m b a. (Vector a v, Monad m) => (b -> a -> m b) -> b -> v -> m b
+{-# INLINE foldM #-}
+foldM f x = C.foldM f x . cvec
+
+-- | Left monadic fold over vector. Function is applied to each element and
+--   its index.
+ifoldM :: forall v m b a. (Vector a v, Monad m) => (b -> Int -> a -> m b) -> b -> v -> m b
+{-# INLINE ifoldM #-}
+ifoldM f x = C.ifoldM f x . cvec
+
+
+----------------------------------------------------------------
+
+-- | Sum all elements in the vector.
+sum :: forall v a. (Vector a v, Num a) => v -> a
+sum = C.sum . cvec
+{-# INLINE sum #-}
+
+-- | Maximal element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let x = mk3 1 2 3 :: Vec3 Int
+--   >>> maximum x
+--   3
+maximum :: forall v a k. (Vector a v, Dim v ~ S k, Ord a) => v -> a
+maximum = C.maximum . cvec
+{-# INLINE maximum #-}
+
+-- | Minimal element of vector.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let x = mk3 1 2 3 :: Vec3 Int
+--   >>> minimum x
+--   1
+minimum :: forall v a k. (Vector a v, Dim v ~ S k, Ord a) => v -> a
+minimum = C.minimum . cvec
+{-# INLINE minimum #-}
+
+-- | Conjunction of all elements of a vector.
+and :: forall v. (Vector Bool v) => v -> Bool
+and = C.and . cvec
+{-# INLINE and #-}
+
+-- | Disjunction of all elements of a vector.
+or :: forall v. (Vector Bool v) => v -> Bool
+or = C.or . cvec
+{-# INLINE or #-}
+
+-- | Determines whether all elements of vector satisfy predicate.
+all :: forall v a. (Vector a v) => (a -> Bool) -> v -> Bool
+all f = (C.all f) . cvec
+{-# INLINE all #-}
+
+-- | Determines whether any of element of vector satisfy predicate.
+any :: forall v a. (Vector a v) => (a -> Bool) -> v -> Bool
+any f = (C.any f) . cvec
+{-# INLINE any #-}
+
+-- | The 'find' function takes a predicate and a vector and returns
+--   the leftmost element of the vector matching the predicate,
+--   or 'Nothing' if there is no such element.
+find :: forall v a. (Vector a v) => (a -> Bool) -> v -> Maybe a
+find f = (C.find f) . cvec
+{-# INLINE find #-}
+
+----------------------------------------------------------------
+
+-- | Test two vectors for equality.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec2)
+--   >>> let v0 = basis 0 :: Vec2 Int
+--   >>> let v1 = basis 1 :: Vec2 Int
+--   >>> v0 `eq` v0
+--   True
+--   >>> v0 `eq` v1
+--   False
+eq :: (Vector a v, Eq a) => v -> v -> Bool
+{-# INLINE eq #-}
+eq v w = C.and
+       $ C.zipWith (==) (cvec v) (cvec w)
+
+
+-- | Lexicographic ordering of two vectors.
+ord :: (Vector a v, Ord a) => v -> v -> Ordering
+{-# INLINE ord #-}
+ord v w = C.foldl mappend mempty
+        $ C.zipWith compare (cvec v) (cvec w)
+
+
+----------------------------------------------------------------
+
+-- | Map over vector
+map :: forall v a. (Vector a v) => (a -> a) -> v -> v
+{-# INLINE map #-}
+map f = vector
+      . C.map f
+      . cvec
+
+-- | Map over vector
+gmap :: forall v w a b. (Vector a v, Vector b w, Dim v ~ Dim w) => (a -> b) -> v -> w
+{-# INLINE gmap #-}
+gmap f = vector
+       . C.map f
+       . cvec
+
+-- | Effectful map over vector.
+mapM :: forall v f a. (Vector a v, Applicative f) => (a -> f a) -> v -> f v
+{-# INLINE mapM #-}
+mapM f = fmap vector
+       . C.mapM f
+       . cvec
+
+-- | Effectful map over vector.
+gmapM :: forall v w f a b. (Vector a v, Vector b w, Applicative f, Dim v ~ Dim w)
+      => (a -> f b) -> v -> f w
+{-# INLINE gmapM #-}
+gmapM f = fmap vector
+        . C.mapM f
+        . cvec
+
+-- | Apply monadic action to each element of vector and ignore result.
+mapM_ :: forall v f b a. (Vector a v, Applicative f) => (a -> f b) -> v -> f ()
+{-# INLINE mapM_ #-}
+mapM_ f = C.mapM_ f
+        . cvec
+
+
+-- | Apply function to every element of the vector and its index.
+imap :: forall v a. (Vector a v) => (Int -> a -> a) -> v -> v
+{-# INLINE imap #-}
+imap f = vector
+       . C.imap f
+       . cvec
+
+-- | Apply function to every element of the vector and its index.
+igmap :: forall v w a b. (Vector a v, Vector b w, Dim v ~ Dim w)
+      => (Int -> a -> b) -> v -> w
+{-# INLINE igmap #-}
+igmap f = vector
+       . C.imap f
+       . cvec
+
+-- | Apply monadic function to every element of the vector and its index.
+imapM :: forall v f a. (Vector a v, Applicative f)
+      => (Int -> a -> f a) -> v -> f v
+{-# INLINE imapM #-}
+imapM f = fmap vector
+        . C.imapM f
+        . cvec
+
+-- | Apply monadic function to every element of the vector and its index.
+igmapM :: forall v w f a b. (Vector a v, Vector b w, Dim v ~ Dim w, Applicative f)
+       => (Int -> a -> f b) -> v -> f w
+{-# INLINE igmapM #-}
+igmapM f = fmap vector
+         . C.imapM f
+         . cvec
+
+-- | Apply monadic function to every element of the vector and its
+--   index and discard result.
+imapM_ :: forall v f b a. (Vector a v, Applicative f) => (Int -> a -> f b) -> v -> f ()
+{-# INLINE imapM_ #-}
+imapM_ f = C.imapM_ f
+         . cvec
+
+-- | Left scan over vector
+scanl :: forall v w a b. (Vector a v, Vector b w, Dim w ~ 'S (Dim v))
+      => (b -> a -> b) -> b -> v -> w
+{-# INLINE scanl #-}
+scanl f x0 = vector . C.scanl f x0 . cvec
+
+-- | Left scan over vector
+scanl1 :: forall v a. (Vector a v)
+      => (a -> a -> a) -> v -> v
+{-# INLINE scanl1 #-}
+scanl1 f = vector . C.scanl1 f . cvec
+
+
+
+----------------------------------------------------------------
+
+-- | Zip two vector together using function.
+--
+--   Examples:
+--
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> let b0 = basis 0 :: Vec3 Int
+--   >>> let b1 = basis 1 :: Vec3 Int
+--   >>> let b2 = basis 2 :: Vec3 Int
+--   >>> let vplus x y = zipWith (+) x y
+--   >>> vplus b0 b1
+--   [1,1,0]
+--   >>> vplus b0 b2
+--   [1,0,1]
+--   >>> vplus b1 b2
+--   [0,1,1]
+zipWith :: forall v a. (Vector a v)
+        => (a -> a -> a) -> v -> v -> v
+{-# INLINE zipWith #-}
+zipWith f v u = vector
+              $ C.zipWith f (cvec v) (cvec u)
+
+-- | Zip three vector together
+zipWith3
+  :: forall v a. (Vector a v)
+  => (a -> a -> a -> a)
+  -> v -> v -> v -> v
+{-# INLINE zipWith3 #-}
+zipWith3 f v1 v2 v3
+  = vector
+  $ C.zipWith3 f (cvec v1) (cvec v2) (cvec v3)
+
+-- | Zip two vector together using monadic function.
+zipWithM :: forall v f a. (Vector a v, Applicative f)
+         => (a -> a -> f a) -> v -> v -> f v
+{-# INLINE zipWithM #-}
+zipWithM f v u = fmap vector
+               $ C.zipWithM f (cvec v) (cvec u)
+
+-- | Zip two vector elementwise using monadic function and discard
+--   result
+zipWithM_
+  :: forall v f b a. (Vector a v, Applicative f)
+  => (a -> a -> f b) -> v -> v -> f ()
+{-# INLINE zipWithM_ #-}
+zipWithM_ f xs ys = C.zipWithM_ f (cvec xs) (cvec ys)
+
+-- | Zip two vector together using function which takes element index
+--   as well.
+izipWith :: forall v a. (Vector a v)
+         => (Int -> a -> a -> a) -> v -> v -> v
+{-# INLINE izipWith #-}
+izipWith f v u = vector
+               $ C.izipWith f (cvec v) (cvec u)
+
+-- | Zip three vector together
+izipWith3
+  :: forall v a. (Vector a v)
+  => (Int -> a -> a -> a -> a)
+  -> v -> v -> v
+  -> v
+{-# INLINE izipWith3 #-}
+izipWith3 f v1 v2 v3
+  = vector
+  $ C.izipWith3 f (cvec v1) (cvec v2) (cvec v3)
+
+-- | Zip two vector together using monadic function which takes element
+--   index as well..
+izipWithM :: forall v f a. (Vector a v, Applicative f)
+          => (Int -> a -> a -> f a) -> v -> v -> f v
+{-# INLINE izipWithM #-}
+izipWithM f v u = fmap vector
+                $ C.izipWithM f (cvec v) (cvec u)
+
+-- | Zip two vector elementwise using monadic function and discard
+--   result
+izipWithM_
+  :: forall v f b a. (Vector a v, Applicative f)
+  => (Int -> a -> a -> f b) -> v -> v -> f ()
+{-# INLINE izipWithM_ #-}
+izipWithM_ f xs ys = C.izipWithM_ f (cvec xs) (cvec ys)
+
+
+----------------------------------------------------------------
+
+-- | Convert between different vector types
+convert :: forall v w a. (Vector a v, Vector a w, Dim v ~ Dim w) => v -> w
+{-# INLINE convert #-}
+convert = vector . cvec
+
+-- | Convert vector to the list
+toList :: forall v a. (Vector a v) => v -> [a]
+toList = foldr (:) []
+{-# INLINE toList #-}
+
+-- | Create vector form list. Will throw error if list is shorter than
+--   resulting vector.
+fromList :: forall v a. (Vector a v) => [a] -> v
+{-# INLINE fromList #-}
+fromList = vector . C.fromList
+
+-- | Create vector form list. Will throw error if list has different
+--   length from resulting vector.
+fromList' :: forall v a. (Vector a v) => [a] -> v
+{-# INLINE fromList' #-}
+fromList' = vector . C.fromList'
+
+-- | Create vector form list. Will return @Nothing@ if list has different
+--   length from resulting vector.
+fromListM :: forall v a. (Vector a v) => [a] -> Maybe v
+{-# INLINE fromListM #-}
+fromListM = fmap vector . C.fromListM
+
+-- | Create vector from 'Foldable' data type. Will return @Nothing@ if
+--   data type different number of elements that resulting vector.
+fromFoldable :: forall v f a. (Vector a v, T.Foldable f) => f a -> Maybe v
+{-# INLINE fromFoldable #-}
+fromFoldable = fromListM . T.toList
+
+
+
+
+----------------------------------------------------------------
+--
+----------------------------------------------------------------
+
+-- | Newtype for deriving instances.
+newtype ViaFixed a v = ViaFixed v
+
+instance (Prod a v) => Prod a (ViaFixed a v) where
+  inspect (ViaFixed v) = inspect v
+  construct = ViaFixed <$> construct
+instance (Prod a v) => Vector a (ViaFixed a v)
+
+type instance Dim (ViaFixed a v) = Dim v
+
+instance (Prod a v, Show a) => Show (ViaFixed a v) where
+  showsPrec _ = shows . toList
+
+instance (Prod a v, Eq a) => Eq (ViaFixed a v) where
+  (==) = eq
+  {-# INLINE (==) #-}
+
+instance (Prod a v, Ord a) => Ord (ViaFixed a v) where
+  compare = ord
+  {-# INLINE compare #-}
+
+instance (Prod a v, NFData a) => NFData (ViaFixed a v) where
+  rnf = foldl (\() a -> rnf a) ()
+  {-# INLINE rnf #-}
+
+instance (Prod a v, Semigroup a) => Semigroup (ViaFixed a v) where
+  (<>) = zipWith (<>)
+  {-# INLINE (<>) #-}
+
+instance (Prod a v, Monoid a) => Monoid (ViaFixed a v) where
+  mempty = replicate mempty
+  {-# INLINE mempty #-}
+
+instance (Prod a v, Storable a) => Storable (ViaFixed a v) where
+  alignment _ = alignment (undefined :: a)
+  sizeOf    _ = sizeOf (undefined :: a) * C.peanoToInt (proxy# @(Dim v))
+  peek p = generateM (peekElemOff (castPtr p))
+  poke p = imapM_    (pokeElemOff (castPtr p))
+  {-# INLINE alignment #-}
+  {-# INLINE sizeOf    #-}
+  {-# INLINE peek      #-}
+  {-# INLINE poke      #-}
+
+instance (Prod a v, Prim a) => Prim (ViaFixed a v) where
+  sizeOf# _ = sizeOf# (undefined :: a) *# dim where
+    dim = case C.peanoToInt (proxy# @(Dim v)) of I# i -> i
+  alignment# _ = alignment# (undefined :: a)
+  {-# INLINE sizeOf#    #-}
+  {-# INLINE alignment# #-}
+  -- Bytearray
+  indexByteArray# ba k
+    = generate $ \(I# i) -> indexByteArray# ba (off +# i)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  readByteArray# ba k
+    = internal
+    $ generateM
+    $ \(I# i) -> ST (\s -> readByteArray# ba (off +# i) s)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  writeByteArray# ba k vec =
+    case loop of
+      ST st -> \s -> case st s of
+                       (# s', () #) -> s'
+    where
+      off  = vectorOff (proxy# @(Dim v))  k
+      loop = flip imapM_ vec $ \(I# i) a -> ST $ \s ->
+        (# writeByteArray# ba (off +# i) a s, () #)
+  {-# INLINE indexByteArray# #-}
+  {-# INLINE readByteArray#  #-}
+  {-# INLINE writeByteArray# #-}
+  -- Addr
+  indexOffAddr# addr k
+    = generate $ \(I# i) -> indexOffAddr# addr (off +# i)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  readOffAddr# ba k
+    = internal
+    $ generateM
+    $ \(I# i) -> ST (\s -> readOffAddr# ba (off +# i) s)
+    where
+      off = vectorOff (proxy# @(Dim v))  k
+  writeOffAddr# addr k vec =
+    case loop of
+      ST st -> \s -> case st s of
+                       (# s', () #) -> s'
+    where
+      off  = vectorOff (proxy# @(Dim v))  k
+      loop = flip imapM_ vec $ \(I# i) a -> ST $ \s ->
+        (# writeOffAddr# addr (off +# i) a s, () #)
+  {-# INLINE indexOffAddr# #-}
+  {-# INLINE readOffAddr#  #-}
+  {-# INLINE writeOffAddr# #-}
+
+
+vectorOff :: (ArityPeano n) => Proxy# n -> Int# -> Int#
+{-# INLINE vectorOff #-}
+vectorOff n k =
+  case C.peanoToInt n of
+    I# dim -> dim *# k
+
+----------------------------------------------------------------
+-- Patterns
+----------------------------------------------------------------
+
+pattern V1 :: (Vector a v, Dim v ~ N1) => a -> v
+pattern V1 x <- (head -> x) where
+  V1 x = mk1 x
+{-# INLINE   V1 #-}
+{-# COMPLETE V1 #-}
+
+pattern V2 :: (Vector a v, Dim v ~ N2) => a -> a -> v
+pattern V2 x y <- (convert -> (x,y)) where
+  V2 x y = mk2 x y
+{-# INLINE   V2 #-}
+{-# COMPLETE V2 #-}
+
+pattern V3 :: (Vector a v, Dim v ~ N3) => a -> a -> a -> v
+pattern V3 x y z <- (convert -> (x,y,z)) where
+  V3 x y z = mk3 x y z
+{-# INLINE   V3 #-}
+{-# COMPLETE V3 #-}
+
+pattern V4 :: (Vector a v, Dim v ~ N4) => a -> a -> a -> a -> v
+pattern V4 t x y z <- (convert -> (t,x,y,z)) where
+  V4 t x y z = mk4 t x y z
+{-# INLINE   V4 #-}
+{-# COMPLETE V4 #-}
+
+----------------------------------------------------------------
+-- Instances
+----------------------------------------------------------------
+
+instance Prod a (Complex a) where
+  inspect (r :+ i) (C.Fun f) = f r i
+  construct = C.Fun (:+)
+  {-# INLINE inspect   #-}
+  {-# INLINE construct #-}
+instance Vector a (Complex a)
+
+instance (a1 ~ a2) => Prod a1 (a1, a2) where
+  inspect (a1, a2) (C.Fun f) = f a1 a2
+  construct = C.Fun (,)
+  {-# INLINE inspect   #-}
+  {-# INLINE construct #-}
+
+instance (a1 ~ a2, a2 ~ a3) => Prod a1 (a1, a2, a3) where
+  inspect (a1, a2, a3) (C.Fun f) = f a1 a2 a3
+  construct = C.Fun (,,)
+  {-# INLINE inspect   #-}
+  {-# INLINE construct #-}
+
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4) => Prod a1 (a1, a2, a3, a4) where
+  inspect (a1, a2, a3, a4) (C.Fun f) = f a1 a2 a3 a4
+  construct = C.Fun (,,,)
+  {-# INLINE inspect   #-}
+  {-# INLINE construct #-}
+
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5) => Prod a1 (a1, a2, a3, a4, a5) where
+  inspect (a1, a2, a3, a4, a5) (C.Fun f) = f a1 a2 a3 a4 a5
+  construct = C.Fun (,,,,)
+  {-# INLINE inspect   #-}
+  {-# INLINE construct #-}
+
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6
+         ) => Prod a1 (a1, a2, a3, a4, a5, a6) where
+  inspect (a1, a2, a3, a4, a5, a6) (C.Fun f) = f a1 a2 a3 a4 a5 a6
+  construct = C.Fun (,,,,,)
+  {-# INLINE inspect   #-}
+  {-# INLINE construct #-}
+
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6, a6 ~ a7
+         ) => Prod a1 (a1, a2, a3, a4, a5, a6, a7) where
+  inspect (a1, a2, a3, a4, a5, a6, a7) (C.Fun f) = f a1 a2 a3 a4 a5 a6 a7
+  construct = C.Fun (,,,,,,)
+  {-# INLINE inspect   #-}
+  {-# INLINE construct #-}
+
+
+
+instance (a1 ~ a2) => Vector a1 (a1, a2)
+instance (a1 ~ a2, a2 ~ a3) => Vector a1 (a1, a2, a3)
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4) => Vector a1 (a1, a2, a3, a4)
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5) => Vector a1 (a1, a2, a3, a4, a5)
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6
+         ) => Vector a1 (a1, a2, a3, a4, a5, a6)
+instance (a1 ~ a2, a2 ~ a3, a3 ~ a4, a4 ~ a5, a5 ~ a6, a6 ~ a7
+         ) => Vector a1 (a1, a2, a3, a4, a5, a6, a7)
+
+
+-- $setup
+--
+-- >>> import Data.Char
+-- >>> import Prelude (Int,Bool(..),Double,IO,(^),String,putStrLn)
+
diff --git a/Data/Vector/Fixed/Primitive.hs b/Data/Vector/Fixed/Primitive.hs
--- a/Data/Vector/Fixed/Primitive.hs
+++ b/Data/Vector/Fixed/Primitive.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE MagicHash            #-}
+{-# LANGUAGE UnboxedTuples        #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- |
 -- Unboxed vectors with fixed length. Vectors from
@@ -34,6 +35,7 @@
 
 
 import Data.Vector.Fixed hiding (index)
+import Data.Vector.Fixed.Mono qualified as FM
 import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index)
 import qualified Data.Vector.Fixed.Cont     as C
 import           Data.Vector.Fixed.Cont     (ArityPeano(..))
@@ -55,9 +57,10 @@
 type Vec4 = Vec 4
 type Vec5 = Vec 5
 
-type instance Mutable (Vec  n) = MVec n
-type instance Dim     (Vec  n) = Peano n
-type instance DimM    (MVec n) = Peano n
+type instance Mutable (Vec  n)   = MVec n
+type instance Dim     (Vec  n)   = Peano n
+type instance Dim     (Vec  n a) = Peano n
+type instance DimM    (MVec n)   = Peano n
 
 
 ----------------------------------------------------------------
@@ -73,6 +76,8 @@
 deriving via ViaFixed (Vec n) a instance (Arity n, Prim a, Semigroup a) => Semigroup (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Arity n, Prim a, Monoid    a) => Monoid    (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Arity n, Prim a, Storable  a) => Storable  (Vec n a)
+-- | @since 2.0.1.0
+deriving via ViaFixed (Vec n) a instance (Arity n, Prim a)              => Prim      (Vec n a)
 
 instance (Arity n, Prim a) => MVector (MVec n) a where
   basicNew = do
@@ -102,6 +107,12 @@
   {-# INLINE construct  #-}
   {-# INLINE inspect    #-}
   {-# INLINE basicIndex #-}
+instance (Arity n, Prim a) => FM.Prod a (Vec n a) where
+  construct  = constructVec
+  inspect    = inspectVec
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+instance (Arity n, Prim a) => FM.Vector a (Vec n a)
 
 instance (Typeable n, Arity n, Prim a, Data a) => Data (Vec n a) where
   gfoldl       = C.gfoldl
diff --git a/Data/Vector/Fixed/Storable.hs b/Data/Vector/Fixed/Storable.hs
--- a/Data/Vector/Fixed/Storable.hs
+++ b/Data/Vector/Fixed/Storable.hs
@@ -1,5 +1,5 @@
-{-# LANGUAGE CPP                  #-}
 {-# LANGUAGE MagicHash            #-}
+{-# LANGUAGE UnboxedTuples        #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- |
 -- Storable-based unboxed vectors.
@@ -26,6 +26,7 @@
 import Data.Monoid           (Monoid(..))
 import Data.Semigroup        (Semigroup(..))
 import Data.Data
+import Data.Primitive.Types  (Prim)
 import Foreign.Ptr           (castPtr)
 import Foreign.Storable
 import Foreign.Marshal.Array ( copyArray, moveArray )
@@ -33,14 +34,13 @@
 import GHC.Ptr               ( Ptr(..) )
 import GHC.Exts              ( proxy# )
 import GHC.TypeLits
-#if MIN_VERSION_base(4,15,0)
 import GHC.ForeignPtr       ( unsafeWithForeignPtr )
-#endif
 import Foreign.ForeignPtr   ( ForeignPtr, withForeignPtr )
 import Prelude ( Show(..),Eq(..),Ord(..),Num(..),Monad(..),IO,Int
                , ($),undefined,seq,pure)
 
 import Data.Vector.Fixed hiding (index)
+import Data.Vector.Fixed.Mono qualified as FM
 import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index, new,unsafeFreeze)
 import qualified Data.Vector.Fixed.Cont     as C
 import           Data.Vector.Fixed.Cont     (ArityPeano(..))
@@ -63,9 +63,10 @@
 type Vec4 = Vec 4
 type Vec5 = Vec 5
 
-type instance Mutable (Vec  n) = MVec n
-type instance Dim     (Vec  n) = Peano n
-type instance DimM    (MVec n) = Peano n
+type instance Mutable (Vec  n)   = MVec n
+type instance Dim     (Vec  n)   = Peano n
+type instance Dim     (Vec  n a) = Peano n
+type instance DimM    (MVec n)   = Peano n
 
 
 ----------------------------------------------------------------
@@ -143,6 +144,12 @@
   {-# INLINE construct  #-}
   {-# INLINE inspect    #-}
   {-# INLINE basicIndex #-}
+instance (Arity n, Storable a) => FM.Prod a (Vec n a) where
+  construct  = constructVec
+  inspect    = inspectVec
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+instance (Arity n, Storable a) => FM.Vector a (Vec n a)
 
 instance (Arity n, Storable a) => Storable (Vec n a) where
   sizeOf    = defaultSizeOf
@@ -156,6 +163,9 @@
     = unsafeWithForeignPtr fp $ \p ->
       moveArray (castPtr ptr) p (peanoToInt (proxy# @(Peano n)))
 
+-- | @since 2.0.1.0
+deriving via ViaFixed (Vec n) a instance (Arity n, Storable a, Prim a) => Prim (Vec n a)
+
 instance (Typeable n, Arity n, Storable a, Data a) => Data (Vec n a) where
   gfoldl       = C.gfoldl
   gunfold      = C.gunfold
@@ -181,13 +191,3 @@
 {-# INLINE mallocVector #-}
 mallocVector size
   = mallocPlainForeignPtrBytes (size * sizeOf (undefined :: a))
-
-#if !MIN_VERSION_base(4,15,0)
--- | A compatibility wrapper for 'GHC.ForeignPtr.unsafeWithForeignPtr' provided
--- by GHC 9.0.1 and later.
---
--- Only to be used when the continuation is known not to
--- unconditionally diverge lest unsoundness can result.
-unsafeWithForeignPtr :: ForeignPtr a -> (Ptr a -> IO b) -> IO b
-unsafeWithForeignPtr = withForeignPtr
-#endif
diff --git a/Data/Vector/Fixed/Strict.hs b/Data/Vector/Fixed/Strict.hs
--- a/Data/Vector/Fixed/Strict.hs
+++ b/Data/Vector/Fixed/Strict.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE MagicHash            #-}
+{-# LANGUAGE UnboxedTuples        #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- |
 -- Strict boxed vector which could hold any value. For lazy variant see
@@ -11,15 +12,19 @@
 import Data.Monoid          (Monoid(..))
 import Data.Semigroup       (Semigroup(..))
 import Data.Data
+import Data.Primitive.Types (Prim)
 import qualified Data.Foldable    as F
+import qualified Data.Foldable1   as F1
 import qualified Data.Traversable as T
-import Foreign.Storable (Storable(..))
+import Foreign.Storable (Storable)
 import GHC.TypeLits
 import GHC.Exts (proxy#)
 import Prelude ( Show(..),Eq(..),Ord(..),Functor(..),Monad(..)
                , ($!),error,(<$>))
-
+      
 import Data.Vector.Fixed hiding (index)
+import Data.Vector.Fixed.Compat
+import Data.Vector.Fixed.Mono qualified as FM
 import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, index)
 import qualified Data.Vector.Fixed.Cont     as C
 import           Data.Vector.Fixed.Cont     (ArityPeano(..))
@@ -42,9 +47,10 @@
 type Vec4 = Vec 4
 type Vec5 = Vec 5
 
-type instance Mutable (Vec  n) = MVec n
-type instance Dim     (Vec  n) = Peano n
-type instance DimM    (MVec n) = Peano n
+type instance Mutable (Vec  n)   = MVec n
+type instance Dim     (Vec  n)   = Peano n
+type instance Dim     (Vec  n a) = Peano n
+type instance DimM    (MVec n)   = Peano n
 
 
 ----------------------------------------------------------------
@@ -54,6 +60,9 @@
 deriving via ViaFixed (Vec n) instance Arity n => Functor     (Vec n)
 deriving via ViaFixed (Vec n) instance Arity n => Applicative (Vec n)
 deriving via ViaFixed (Vec n) instance Arity n => F.Foldable  (Vec n)
+-- | @since @2.0.1.0
+deriving via ViaFixed (Vec n)
+    instance (Arity n, Peano n ~ S k) => F1.Foldable1 (Vec n)
 
 instance Arity n => T.Traversable (Vec n) where
   sequence  = sequence
@@ -72,6 +81,8 @@
 deriving via ViaFixed (Vec n) a instance (Arity n, Semigroup a) => Semigroup (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Arity n, Monoid    a) => Monoid    (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Arity n, Storable  a) => Storable  (Vec n a)
+-- | @since 2.0.1.0
+deriving via ViaFixed (Vec n) a instance (Arity n, Prim      a) => Prim      (Vec n a)
 
 instance (Arity n) => MVector (MVec n) a where
   basicNew =
@@ -107,6 +118,12 @@
   {-# INLINE construct  #-}
   {-# INLINE inspect    #-}
   {-# INLINE basicIndex #-}
+instance (Arity n) => FM.Prod a (Vec n a) where
+  construct  = constructVec
+  inspect    = inspectVec
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
+instance (Arity n) => FM.Vector a (Vec n a)
 
 instance (Typeable n, Arity n, Data a) => Data (Vec n a) where
   gfoldl       = C.gfoldl
diff --git a/Data/Vector/Fixed/Unboxed.hs b/Data/Vector/Fixed/Unboxed.hs
--- a/Data/Vector/Fixed/Unboxed.hs
+++ b/Data/Vector/Fixed/Unboxed.hs
@@ -38,7 +38,8 @@
 import Data.Semigroup        (Semigroup(..))
 import Data.Ord              (Down(..))
 import Data.Word             (Word,Word8,Word16,Word32,Word64)
-import Foreign.Storable      (Storable(..))
+import Data.Primitive.Types  (Prim)
+import Foreign.Storable      (Storable)
 import GHC.TypeLits
 import GHC.Exts              (Proxy#, proxy#)
 import Prelude               ( Show(..),Eq(..),Ord(..),Num(..),Applicative(..)
@@ -46,7 +47,9 @@
 
 import Data.Vector.Fixed           (Dim,Vector(..),ViaFixed(..))
 import Data.Vector.Fixed           qualified as F
+import Data.Vector.Fixed.Compat
 import Data.Vector.Fixed.Cont      qualified as C
+import Data.Vector.Fixed.Mono      qualified as FM
 import Data.Vector.Fixed.Cont      (Peano,Arity,ArityPeano,Fun(..),curryFirst)
 import Data.Vector.Fixed.Primitive qualified as P
 
@@ -85,7 +88,8 @@
   -- | Convert element from its representation
   fromEltRepr :: Proxy# n -> EltRepr a -> a
 
-type instance Dim (Vec n) = Peano n
+type instance Dim (Vec n)   = Peano n
+type instance Dim (Vec n a) = Peano n
 
 instance (Arity n, Unbox n a) => Vector (Vec n) a where
   inspect (Vec v) f
@@ -97,8 +101,16 @@
   {-# INLINE inspect   #-}
   {-# INLINE construct #-}
 
+instance (Arity n, Unbox n a) => FM.Prod a (Vec n a) where
+  construct  = construct
+  inspect    = inspect
+  {-# INLINE construct  #-}
+  {-# INLINE inspect    #-}
 
+instance (Arity n, Unbox n a) => FM.Vector a (Vec n a)
 
+
+
 ----------------------------------------------------------------
 -- Generic instances
 ----------------------------------------------------------------
@@ -110,6 +122,8 @@
 deriving via ViaFixed (Vec n) a instance (Unbox n a, Semigroup a) => Semigroup (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Unbox n a, Monoid    a) => Monoid    (Vec n a)
 deriving via ViaFixed (Vec n) a instance (Unbox n a, Storable  a) => Storable  (Vec n a)
+-- | @since 2.0.1.0
+deriving via ViaFixed (Vec n) a instance (Unbox n a, Prim      a) => Prim      (Vec n a)
 
 instance (Typeable n, Unbox n a, Data a) => Data (Vec n a) where
   gfoldl       = C.gfoldl
@@ -138,7 +152,8 @@
 
 data VecUnit (n :: Nat) a = VecUnit
 
-type instance Dim (VecUnit n) = Peano n
+type instance Dim (VecUnit n)   = Peano n
+type instance Dim (VecUnit n a) = Peano n
 
 instance F.Arity n => Vector (VecUnit n) () where
   inspect _ fun
@@ -159,7 +174,8 @@
 --   GHC quite a bit.
 data BitVec (n :: Nat) a = BitVec Word64
 
-type instance Dim (BitVec n) = Peano n
+type instance Dim (BitVec n)   = Peano n
+type instance Dim (BitVec n a) = Peano n
 
 instance (n <= 64, Arity n, a ~ Bool) => Vector (BitVec n) a where
   inspect (BitVec w) = inspect (C.generate (testBit w))
@@ -235,7 +251,8 @@
 -- | Representation for vector of 2-tuple as two vectors.
 data T2 n a b x = T2 !(Vec n a) !(Vec n b)
 
-type instance Dim (T2 n a b) = Peano n
+type instance Dim (T2 n a b)   = Peano n
+type instance Dim (T2 n a b x) = Peano n
 
 instance (Arity n, Unbox n a, Unbox n b) => Vector (T2 n a b) (a,b) where
   inspect (T2 vA vB)
@@ -265,7 +282,8 @@
 -- | Representation for vector of 2-tuple as two vectors.
 data T3 n a b c x = T3 !(Vec n a) !(Vec n b) !(Vec n c)
 
-type instance Dim (T3 n a b c) = Peano n
+type instance Dim (T3 n a b c)   = Peano n
+type instance Dim (T3 n a b c x) = Peano n
 
 instance (Arity n, Unbox n a, Unbox n b, Unbox n c) => Vector (T3 n a b c) (a,b,c) where
   inspect (T3 vA vB vC)
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/fixed-vector.cabal b/fixed-vector.cabal
--- a/fixed-vector.cabal
+++ b/fixed-vector.cabal
@@ -2,49 +2,53 @@
 Build-Type:     Simple
 
 Name:           fixed-vector
-Version:        2.0.0.0
+Version:        2.1.0.0
 Synopsis:       Generic vectors with statically known size.
 Description:
   Generic library for vectors with statically known
   size. Implementation is based on
   <http://unlines.wordpress.com/2010/11/15/generics-for-small-fixed-size-vectors/>
   Same functions could be used to work with both ADT based vector like
-  .
+
   > data Vec3 a = a a a
-  .
+
   Tuples are vectors too:
-  .
+
   >>> sum (1,2,3)
   6
-  .
+
   Vectors which are represented internally by arrays are provided by
   library. Both boxed and unboxed arrays are supported.
-  .
+
   Library is structured as follows:
-  .
-  * Data.Vector.Fixed
+
+  * __Data.Vector.Fixed__:
   Generic API. It's suitable for both ADT-based vector like Complex
   and array-based ones.
-  .
-  * Data.Vector.Fixed.Cont
+
+  * __Data.Vector.Fixed.Cont__:
   Continuation based vectors. Internally all functions use them.
-  .
-  * Data.Vector.Fixed.Mutable
+
+  * __Data.Vector.Fixed.Unboxed__:
+  Unboxed vectors which select best representation using types.
+
+  * __Data.Vector.Fixed.Strict__:
+  Strict boxed vector which can hold elements of any type.
+
+  * __Data.Vector.Fixed.Boxed__:
+  Lazy boxed vector which can hold elements of any type.
+
+  * __Data.Vector.Fixed.Storable__:
+  Unboxed vectors of Storable  types.
+
+  * __Data.Vector.Fixed.Primitive__:
+  Unboxed vectors backed by single @ByteArray@
+
+  * __Data.Vector.Fixed.Mutable__:
   Type classes for array-based implementation and API for working with
   mutable state.
-  .
-  * Data.Vector.Fixed.Unboxed
-  Unboxed vectors.
-  .
-  * Data.Vector.Fixed.Boxed
-  Boxed vector which can hold elements of any type.
-  .
-  * Data.Vector.Fixed.Storable
-  Unboxed vectors of Storable  types.
-  .
-  * Data.Vector.Fixed.Primitive
-  Unboxed vectors based on pritimive package.
 
+
 License:        BSD-3-Clause
 License-File:   LICENSE
 Author:         Aleksey Khudyakov <alexey.skladnoy@gmail.com>
@@ -55,13 +59,12 @@
   ChangeLog.md
 
 tested-with:
-    GHC ==8.10.7
-     || ==9.0.1
-     || ==9.2.8
-     || ==9.4.7
-     || ==9.6.6
-     || ==9.8.2
-     || ==9.10.1
+    GHC ==9.4.7
+     || ==9.6.7
+     || ==9.8.4
+     || ==9.10.2
+     || ==9.12.2
+     || ==9.14.1
 
 source-repository head
   type:     git
@@ -123,18 +126,22 @@
     PatternSynonyms
     ViewPatterns
     TypeFamilies
+    FunctionalDependencies
 
 
 Library
   import:        language
-  Build-Depends: base      >=4.14 && <5
+  Build-Depends: base      >=4.16 && <5
                , primitive >=0.6.2
                , deepseq
+  if impl(ghc<9.6)
+     Build-Depends: foldable1-classes-compat >=0.1
   Exposed-modules:
     -- API
     Data.Vector.Fixed.Cont
     Data.Vector.Fixed
     Data.Vector.Fixed.Generic
+    Data.Vector.Fixed.Mono
     -- Arrays
     Data.Vector.Fixed.Mutable
     Data.Vector.Fixed.Boxed
@@ -144,6 +151,7 @@
     Data.Vector.Fixed.Storable
   Other-modules:
     Data.Vector.Fixed.Internal
+    Data.Vector.Fixed.Compat
 
 Test-Suite fixed-vector-doctests
   Default-Language: Haskell2010
diff --git a/test/Doctests.hs b/test/Doctests.hs
--- a/test/Doctests.hs
+++ b/test/Doctests.hs
@@ -66,4 +66,5 @@
   , "-XPatternSynonyms"
   , "-XViewPatterns"
   , "-XTypeFamilies"
+  , "-XFunctionalDependencies"
   ]
