diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,14 @@
+Changes in 1.2.1.0
+
+  * Support for GHC7.10 dropped.
+
+  * Pattern synonyms `V2`,`V3`,`V4` added.
+
+  * `replicate{,M}` and `generate{,M}` added.
+
+  * Functions `mk6`, `mk7`, `mk8` added.
+
+
 Changes in 1.2.0.0
 
   * `Show` instance for data type now respect precedence.
diff --git a/Data/Vector/Fixed.hs b/Data/Vector/Fixed.hs
--- a/Data/Vector/Fixed.hs
+++ b/Data/Vector/Fixed.hs
@@ -1,15 +1,21 @@
+{-# LANGUAGE CPP                   #-}
 {-# LANGUAGE DataKinds             #-}
 {-# LANGUAGE DeriveDataTypeable    #-}
+{-# LANGUAGE DeriveFoldable        #-}
+{-# LANGUAGE DeriveFunctor         #-}
+{-# LANGUAGE DeriveTraversable     #-}
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE GADTs                 #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PatternSynonyms       #-}
 {-# LANGUAGE PolyKinds             #-}
 {-# LANGUAGE ScopedTypeVariables   #-}
 {-# LANGUAGE StandaloneDeriving    #-}
 {-# LANGUAGE TypeFamilies          #-}
 {-# LANGUAGE TypeOperators         #-}
 {-# LANGUAGE UndecidableInstances  #-}
+{-# LANGUAGE ViewPatterns          #-}
 -- |
 -- Generic API for vectors with fixed length.
 --
@@ -57,7 +63,14 @@
   , mk3
   , mk4
   , mk5
+  , mk6
+  , mk7
+  , mk8
   , mkN
+    -- ** Pattern for low-dimension vectors
+  , pattern V2
+  , pattern V3
+  , pattern V4
     -- ** Continuation-based vectors
   , ContVec
   , empty
@@ -175,8 +188,6 @@
 import Data.Vector.Fixed.Internal
 
 import Prelude (Show(..),Eq(..),Ord(..),Functor(..),id,(.),($),undefined)
--- Needed for doctest
-import Prelude (Char)
 
 
 -- $construction
@@ -189,7 +200,7 @@
 -- ('a','b','c')
 --
 -- Alternatively one could use 'mkN'. See its documentation for
--- examples
+-- examples.
 --
 -- Another option is to create tuple and 'convert' it to desired
 -- vector type. For example:
@@ -203,6 +214,8 @@
 -- > function :: Vec N3 Double -> ...
 -- > function (convert -> (x,y,z)) = ...
 --
+-- For small vectors pattern synonyms @V2@, @V3$, @V4@ are provided
+-- that use same trick internally.
 
 
 -- $smallDim
@@ -294,15 +307,8 @@
 
 -- | Single-element tuple.
 newtype Only a = Only a
-                 deriving (Show,Eq,Ord,Typeable,Data)
+                 deriving (Show,Eq,Ord,Typeable,Data,Functor,F.Foldable,T.Traversable)
 
-instance Functor Only where
-  fmap f (Only a) = Only (f a)
-instance F.Foldable Only where
-  foldr = foldr
-instance T.Traversable Only where
-  sequenceA  (Only f) = Only <$> f
-  traverse f (Only a) = Only <$> f a
 instance Monoid a => Monoid (Only a) where
   mempty = Only mempty
   Only a `mappend` Only b = Only $ mappend a b
@@ -335,20 +341,7 @@
 
 -- | Empty tuple.
 data Empty a = Empty
-  deriving (Show,Eq,Ord)
--- GHC7.10 wants standalone deriving for some reason:
--- >    No instance for (Typeable a)
--- >      arising from the 'deriving' clause of a data type declaration
-deriving instance Typeable a => Typeable (Empty a)
-deriving instance Data     a => Data     (Empty a)
-
-instance Functor Empty where
-  fmap _ Empty = Empty
-instance F.Foldable Empty where
-  foldr = foldr
-instance T.Traversable Empty where
-  sequenceA Empty = pure Empty
-  traverse _ Empty = pure Empty
+  deriving (Show,Eq,Ord,Typeable,Data,Functor,F.Foldable,T.Traversable)
 
 instance NFData (Empty a) where
   rnf Empty = ()
@@ -365,3 +358,34 @@
 type Tuple3 a = (a,a,a)
 type Tuple4 a = (a,a,a,a)
 type Tuple5 a = (a,a,a,a,a)
+
+
+----------------------------------------------------------------
+-- Patterns
+----------------------------------------------------------------
+
+pattern V2 :: (Vector v a, Dim v ~ 2) => 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 #-}
+#endif
+
+pattern V3 :: (Vector v a, Dim v ~ 3) => 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 #-}
+#endif
+
+pattern V4 :: (Vector v a, Dim v ~ 4) => 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 #-}
+#endif
+
+
+-- $setup
+--
+-- >>> import Data.Char
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
@@ -35,7 +35,7 @@
                , ($),($!),error,seq)
 
 import Data.Vector.Fixed hiding (index)
-import Data.Vector.Fixed.Mutable
+import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, arity, index)
 import qualified Data.Vector.Fixed.Cont     as C
 import qualified Data.Vector.Fixed.Internal as I
 
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
@@ -73,6 +73,9 @@
   , mk3
   , mk4
   , mk5
+  , mk6
+  , mk7
+  , mk8
     -- * Transformations
   , map
   , imap
@@ -125,7 +128,7 @@
   , gunfold
   ) where
 
-import Control.Applicative   ((<|>))
+import Control.Applicative   ((<|>), Const(..))
 import Data.Coerce
 import Data.Complex          (Complex(..))
 import Data.Data             (Data)
@@ -607,8 +610,19 @@
 mk5 a1 a2 a3 a4 a5 = ContVec $ \(Fun f) -> f a1 a2 a3 a4 a5
 {-# INLINE mk5 #-}
 
+mk6 :: a -> a -> a -> a -> a -> a -> ContVec 6 a
+mk6 a1 a2 a3 a4 a5 a6 = ContVec $ \(Fun f) -> f a1 a2 a3 a4 a5 a6
+{-# INLINE mk6 #-}
 
+mk7 :: a -> a -> a -> a -> a -> a -> a -> ContVec 7 a
+mk7 a1 a2 a3 a4 a5 a6 a7 = ContVec $ \(Fun f) -> f a1 a2 a3 a4 a5 a6 a7
+{-# INLINE mk7 #-}
 
+mk8 :: a -> a -> a -> a -> a -> a -> a -> a -> ContVec 8 a
+mk8 a1 a2 a3 a4 a5 a6 a7 a8 = ContVec $ \(Fun f) -> f a1 a2 a3 a4 a5 a6 a7 a8
+{-# INLINE mk8 #-}
+
+
 ----------------------------------------------------------------
 -- Transforming vectors
 ----------------------------------------------------------------
@@ -1053,9 +1067,6 @@
 
 newtype T_gfoldl c r a n = T_gfoldl (c (Fn n a r))
 
-
--- Const in GHC7.10 is not polykinded
-newtype Const a n = Const a
 
 ----------------------------------------------------------------
 -- Deforestation
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
@@ -57,6 +57,18 @@
 mk5 a1 a2 a3 a4 a5 = vector $ C.mk5 a1 a2 a3 a4 a5
 {-# INLINE mk5 #-}
 
+mk6 :: (Vector v a, Dim v ~ 6) => a -> a -> a -> a -> a -> a -> v a
+mk6 a1 a2 a3 a4 a5 a6 = vector $ C.mk6 a1 a2 a3 a4 a5 a6
+{-# INLINE mk6 #-}
+
+mk7 :: (Vector v a, Dim v ~ 7) => a -> a -> a -> a -> a -> a -> a -> v a
+mk7 a1 a2 a3 a4 a5 a6 a7 = vector $ C.mk7 a1 a2 a3 a4 a5 a6 a7
+{-# INLINE mk7 #-}
+
+mk8 :: (Vector v a, Dim v ~ 8) => a -> a -> a -> a -> a -> a -> a -> a -> v a
+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:
diff --git a/Data/Vector/Fixed/Mutable.hs b/Data/Vector/Fixed/Mutable.hs
--- a/Data/Vector/Fixed/Mutable.hs
+++ b/Data/Vector/Fixed/Mutable.hs
@@ -20,6 +20,13 @@
   , read
   , write
   , clone
+    -- * Creation
+  , replicate
+  , replicateM
+  , generate
+  , generateM
+    -- * Loops
+  , forI
     -- * Immutable vectors
   , IVector(..)
   , index
@@ -30,12 +37,13 @@
   , inspectVec
   ) where
 
+import Control.Applicative  (Const(..))
 import Control.Monad.ST
 import Control.Monad.Primitive
 import Data.Typeable  (Proxy(..))
 import GHC.TypeLits
 import Data.Vector.Fixed.Cont (Dim,PeanoNum(..),Peano,Arity,Fun(..),Vector(..),ContVec,arity,apply,accum,length)
-import Prelude hiding (read,length)
+import Prelude hiding (read,length,replicate)
 
 
 ----------------------------------------------------------------
@@ -75,11 +83,21 @@
 lengthM _ = arity (Proxy :: Proxy (DimM v))
 
 -- | Create copy of vector.
+--
+--   Examples:
+--
+--   >>> import Control.Monad.ST (runST)
+--   >>> import Data.Vector.Fixed (mk3)
+--   >>> import Data.Vector.Fixed.Boxed (Vec3)
+--   >>> import qualified Data.Vector.Fixed.Mutable as M
+--   >>> let x = runST (do { v <- M.replicate 100; v' <- clone v; M.write v' 0 2; M.unsafeFreeze v' }) :: Vec3 Int
+--   >>> x
+--   fromList [2,100,100]
 clone :: (PrimMonad m, MVector v a) => v (PrimState m) a -> m (v (PrimState m) a)
 {-# INLINE clone #-}
 clone v = do
   u <- new
-  move v u
+  move u v
   return u
 
 -- | Read value at index with bound checks.
@@ -97,13 +115,84 @@
   | otherwise               = unsafeWrite v i x
 
 
+-- | Create new vector with all elements set to given value.
+replicate :: (PrimMonad m, MVector v a) => a -> m (v (PrimState m) a)
+{-# INLINE replicate #-}
+replicate a = do
+  v <- new
+  forI v $ \i -> unsafeWrite v i a
+  pure v
+
+-- | Create new vector with all elements are generated by provided
+--   monadic action.
+replicateM :: (PrimMonad m, MVector v a) => m a -> m (v (PrimState m) a)
+{-# INLINE replicateM #-}
+replicateM m = do
+  v <- new
+  forI v $ \i -> unsafeWrite v i =<< m
+  pure v
+
+-- | Create new vector with using function from index to value.
+generate :: (PrimMonad m, MVector v a) => (Int -> a) -> m (v (PrimState m) a)
+{-# INLINE generate #-}
+generate f = do
+  v <- new
+  forI v $ \i -> unsafeWrite v i $ f i
+  pure v
+
+-- | Create new vector with using monadic function from index to value.
+generateM :: (PrimMonad m, MVector v a) => (Int -> m a) -> m (v (PrimState m) a)
+{-# INLINE generateM #-}
+generateM f = do
+  v <- new
+  forI v $ \i -> unsafeWrite v i =<< f i
+  pure v
+
+-- | Loop which calls function for each index
+forI :: (PrimMonad m, MVector v a) => v (PrimState m) a -> (Int -> m ()) -> m ()
+{-# INLINE forI #-}
+forI v f = go 0
+  where
+    go i | i >= n    = pure ()
+         | otherwise = f i >> go (i+1)
+    n = lengthM v
+
+
+----------------------------------------------------------------
+-- Immutable
+----------------------------------------------------------------
+
 -- | Type class for immutable vectors
 class (Dim v ~ DimM (Mutable v), MVector (Mutable v) a) => IVector v a where
   -- | Convert vector to immutable state. Mutable vector must not be
   --   modified afterwards.
   unsafeFreeze :: PrimMonad m => Mutable v (PrimState m) a -> m (v a)
-  -- | Convert immutable vector to mutable. Immutable vector must not
-  --   be used afterwards.
+  -- | /O(1)/ Unsafely convert immutable vector to mutable without
+  --   copying.  Note that this is a very dangerous function and
+  --   generally it's only safe to read from the resulting vector. In
+  --   this case, the immutable vector could be used safely as well.
+  --
+  -- Problems with mutation happen because GHC has a lot of freedom to
+  -- introduce sharing. As a result mutable vectors produced by
+  -- @unsafeThaw@ may or may not share the same underlying buffer. For
+  -- example:
+  --
+  -- > foo = do
+  -- >   let vec = F.generate 10 id
+  -- >   mvec <- M.unsafeThaw vec
+  -- >   do_something mvec
+  --
+  -- Here GHC could lift @vec@ outside of foo which means that all calls to
+  -- @do_something@ will use same buffer with possibly disastrous
+  -- results. Whether such aliasing happens or not depends on the program in
+  -- question, optimization levels, and GHC flags.
+  --
+  -- All in all, attempts to modify a vector produced by @unsafeThaw@
+  -- fall out of domain of software engineering and into realm of
+  -- black magic, dark rituals, and unspeakable horrors. The only
+  -- advice that could be given is: "Don't attempt to mutate a vector
+  -- produced by @unsafeThaw@ unless you know how to prevent GHC from
+  -- aliasing buffers accidentally. We don't."
   unsafeThaw   :: PrimMonad m => v a -> m (Mutable v (PrimState m) a)
   -- | Get element at specified index without bounds check.
   unsafeIndex :: v a -> Int -> a
@@ -139,9 +228,6 @@
     cv :: ContVec (Dim v) a
     cv = apply (\(Const i) -> (unsafeIndex v i, Const (i+1)))
                (Const 0 :: Const Int (Peano (Dim v)))
-
--- Const in GHC7.10 is not polykinded
-newtype Const a n = Const a
 
 -- | Generic construct implementation for array-based vectors.
 constructVec :: forall v a. (Arity (Dim v), IVector v a) => Fun (Peano (Dim v)) a (v a)
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
@@ -39,7 +39,7 @@
 
 
 import Data.Vector.Fixed hiding (index)
-import Data.Vector.Fixed.Mutable
+import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, arity, index)
 import qualified Data.Vector.Fixed.Cont     as C
 import qualified Data.Vector.Fixed.Internal as I
 
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
@@ -43,7 +43,7 @@
                , ($),undefined,seq)
 
 import Data.Vector.Fixed hiding (index)
-import Data.Vector.Fixed.Mutable
+import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, arity, index)
 import qualified Data.Vector.Fixed.Cont     as C
 import qualified Data.Vector.Fixed.Internal as I
 
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
@@ -44,7 +44,7 @@
 import Data.Vector.Fixed (Dim,Vector(..),VectorN,eq,ord,replicate,zipWith,foldl,
                           defaultSizeOf,defaultAlignemnt,defaultPeek,defaultPoke
                          )
-import Data.Vector.Fixed.Mutable
+import Data.Vector.Fixed.Mutable (Mutable, MVector(..), IVector(..), DimM, constructVec, inspectVec, Arity, index)
 import qualified Data.Vector.Fixed.Cont      as C
 import qualified Data.Vector.Fixed.Primitive as P
 import qualified Data.Vector.Fixed.Internal  as I
diff --git a/fixed-vector.cabal b/fixed-vector.cabal
--- a/fixed-vector.cabal
+++ b/fixed-vector.cabal
@@ -1,5 +1,5 @@
 Name:           fixed-vector
-Version:        1.2.0.0
+Version:        1.2.1.0
 Synopsis:       Generic vectors with statically known size.
 Description:
   Generic library for vectors with statically known
@@ -42,7 +42,7 @@
   * Data.Vector.Fixed.Primitive
   Unboxed vectors based on pritimive package.
 
-Cabal-Version:  >= 1.8
+Cabal-Version:  >= 1.10
 License:        BSD3
 License-File:   LICENSE
 Author:         Aleksey Khudyakov <alexey.skladnoy@gmail.com>
@@ -53,17 +53,26 @@
 extra-source-files:
   ChangeLog.md
 
+tested-with:
+    GHC ==8.0.2
+     || ==8.2.2
+     || ==8.4.4
+     || ==8.6.5
+     || ==8.8.4
+     || ==8.10.7
+     || ==9.0.1
+     || ==9.2.1
+
 source-repository head
   type:     git
   location: http://github.com/Shimuuar/fixed-vector
 
 Library
   Ghc-options:          -Wall
-  Build-Depends: base      >=4.8 && <5
+  Default-Language:     Haskell2010
+  Build-Depends: base      >=4.9 && <5
                , primitive >=0.6.2
                , deepseq
-  if impl(ghc < 8.0)
-    Build-Depends: semigroups >= 0.18
   Exposed-modules:
     -- API
     Data.Vector.Fixed.Cont
@@ -78,12 +87,15 @@
   Other-modules:
     Data.Vector.Fixed.Internal
 
-Test-Suite doctests
+Test-Suite fixed-vector-doctests
+  Default-Language: Haskell2010
+  if impl(ghc < 8.0.1 )
+    buildable: False
   Type:           exitcode-stdio-1.0
   Hs-source-dirs: test
   Main-is:        Doctests.hs
   Build-Depends: base >=4.8 && <5
                , primitive >=0.6.2
                  -- Additional test dependencies.
-               , doctest   >= 0.9
+               , doctest   >= 0.18
                , filemanip == 0.3.6.*
