diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -14,3 +14,7 @@
 ## V0.12.0
 - Add `defaultSpecs`
 - Remove `FormatTime` instance
+
+## V0.13.0
+- Add `FromArgKey` typeclass
+- Fix `OVERLAPPABLE` issue
diff --git a/src/Text/Format.hs b/src/Text/Format.hs
--- a/src/Text/Format.hs
+++ b/src/Text/Format.hs
@@ -17,6 +17,7 @@
   , format1
     -- * Classes
   , FormatArg(formatArg)
+  , FromArgKey(..)
   , FormatType(..)
   -- * Generic format arg and options
   , Options
diff --git a/src/Text/Format/Class.hs b/src/Text/Format/Class.hs
--- a/src/Text/Format/Class.hs
+++ b/src/Text/Format/Class.hs
@@ -8,6 +8,7 @@
 module Text.Format.Class
   ( Formatter
   , FormatArg(..)
+  , FromArgKey(..)
   , FormatType(..)
   , Options(..)
   , defaultOptions
@@ -27,8 +28,7 @@
 import           Data.Char
 import           Data.Either
 import           Data.Int
-import           Data.List           ((!!))
-import           Data.Map            hiding (map)
+import           Data.Map            as M hiding (drop, map)
 import           Data.Maybe
 import           Data.Word
 import           GHC.Generics
@@ -137,9 +137,10 @@
   formatArg = genericFormatArg defaultOptions
 
   formatArgList :: [a] -> Formatter
-  formatArgList xs (Index i)          = formatArg (xs !! i) mempty
-  formatArgList xs (Nest (Index i) k) = formatArg (xs !! i) k
-  formatArgList  _ _                  = const $ throwM ArgKeyError
+  formatArgList xs k | k == mempty = const $ throwM ArgKeyError
+  formatArgList xs k | Just i <- fromArgKey (topKey k) =
+    case drop (i - 1) xs of (x:_) -> formatArg x (popKey k)
+  formatArgList  _ _ = const $ throwM ArgKeyError
 
   -- | This method is used to get the key of a top-level argument.
   -- Top-level argument means argument that directly passed to format
@@ -195,21 +196,39 @@
 instance FormatArg Word64 where
   formatArg = formatWord
 
-instance {-# OVERLAPPABLE #-} FormatArg a => FormatArg [a] where
+instance FormatArg a => FormatArg [a] where
   {-# SPECIALIZE instance FormatArg [Char] #-}
   formatArg = formatArgList
 
-instance FormatArg a => FormatArg (Map String a) where
-  formatArg x (Name n)          = formatArg (x ! n) mempty
-  formatArg x (Nest (Name n) k) = formatArg (x ! n) k
-  formatArg _ _                 = const $ throwM ArgKeyError
+instance (Ord k, FromArgKey k, FormatArg v) => FormatArg (Map k v) where
+  formatArg _ k | k == mempty = const $ throwM ArgKeyError
+  formatArg x k | (Just k') <- fromArgKey (topKey k) =
+    case (M.lookup k' x) of (Just x') -> formatArg x' (popKey k)
+  formatArg _ _ = const $ throwM ArgKeyError
 
-instance FormatArg a => FormatArg (Map Int a) where
-  formatArg x (Index i)          = formatArg (x ! i) mempty
-  formatArg x (Nest (Index i) k) = formatArg (x ! i) k
-  formatArg _ _                  = const $ throwM ArgKeyError
 
+--------------------------------------------------------------------------------
+{-| Typeclass for types that can be used as the key of a map-like or list-like
+ container.
 
+For example, since 'String' and 'Integral' datatypes are instance of
+ 'FromArgKey' and 'Double' is an instance of 'FormatArg', we can format a value
+of type 'Map' 'String' 'Double'.
+
+@since 0.13.0
+-}
+class FromArgKey a where
+  fromArgKey :: ArgKey -> Maybe a
+
+instance FromArgKey String where
+  fromArgKey (Name k) = Just k
+  fromArgKey _        = Nothing
+
+instance Integral k => FromArgKey k where
+  fromArgKey (Index i) = Just $ toEnum i
+  fromArgKey _         = Nothing
+
+
 --------------------------------------------------------------------------------
 {-| Options that specify how to format your datatype
 
@@ -460,7 +479,10 @@
     showx _ _ _     = throwM ArgFmtError
 
 
-{-| Use a default specs for the given formatter -}
+{-| Use a default specs for the given formatter
+
+@since 0.12.0
+-}
 defaultSpecs :: String -> (a -> Formatter) -> a -> Formatter
 defaultSpecs specs f x k fmt
   | fmtSpecs fmt == "" = f x k $ fmt {fmtSpecs = specs}
diff --git a/vformat.cabal b/vformat.cabal
--- a/vformat.cabal
+++ b/vformat.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 432cce1b2c70136bddd87b0256f57f890212a55aaa4f38b8b1ddb4fb4eb1d3dc
+-- hash: f705e4890246248ac73f5ee9489edc8b4f36b6938729787e055dcb2f2973386b
 
 name:           vformat
-version:        0.12.0.0
+version:        0.13.0.0
 synopsis:       A Python str.format() like formatter
 description:    Please see the http://hackage.haskell.org/package/vformat
 category:       Text, Format
