diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.2.0.0
+
+- Added more generic `ArrayNestedList` class with methods `arrayNestedList`
+and `toNestedList` to convert between nested lists and
+multi-dimensional Arrays with any indices.
+
 ## 0.1.0.0
 
 - Initial release
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
 # array-list
 
-[IsList](https://hackage.haskell.org/package/base/docs/GHC-Exts.html#t:IsList) instances of [Array](https://hackage.haskell.org/package/array/docs/Data-Array.html#t:Array) for [OverloadedLists](https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#overloaded-lists) extension
+[IsList](https://hackage.haskell.org/package/base/docs/GHC-Exts.html#t:IsList) instances of [Array](https://hackage.haskell.org/package/array/docs/Data-Array.html#t:Array) for [OverloadedLists](https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#overloaded-lists) extension.
+
+Converting between \[nested\] lists and multi-dimensional Arrays.
 
 See [docs and usage examples on hackage](http://hackage.haskell.org/package/array-list/docs/Data-Array-IsList.html).
diff --git a/array-list.cabal b/array-list.cabal
--- a/array-list.cabal
+++ b/array-list.cabal
@@ -4,14 +4,17 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: ed946011242c8c41f9762a9ddaadd8ee8ab793a2361e2cba2c0bcc0d11f18c9d
+-- hash: 0dfaca7090560c3bcf961025267c1e7ca59942261400502331a0a3747c130de9
 
 name:           array-list
-version:        0.1.0.0
+version:        0.2.0.0
 synopsis:       IsList instances of Array for OverloadedLists extension
-description:    This package provides "orphan" instances 'IsList' for 'Array' data types
+description:    This package provides "orphan" 'IsList' instances for 'Array' data types
                 with `Integral` indices up to 5 dimensions to allow initializing
                 'Array's from [nested] lists using 'OverloadedLists' GHC extension.
+                .
+                It also includes more generic 'arrayNestedList' and 'toNestedList'
+                functions to convert between nested lists and 'Array's with any indices.
 category:       Data, Array, List
 homepage:       https://github.com/epoberezkin/array-list#readme
 bug-reports:    https://github.com/epoberezkin/array-list/issues
@@ -54,7 +57,7 @@
   build-depends:
       array ==0.5.*
     , base >=4.7 && <5
-    , doctest ==0.17.*
+    , doctest >=0.16 && <0.18
     , doctest-driver-gen ==0.3.*
   default-language: Haskell2010
 
diff --git a/src/Data/Array/IsList.hs b/src/Data/Array/IsList.hs
--- a/src/Data/Array/IsList.hs
+++ b/src/Data/Array/IsList.hs
@@ -1,5 +1,7 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE InstanceSigs #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ParallelListComp #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
@@ -16,6 +18,9 @@
 -- with `Integral` indices up to 5 dimensions to allow initializing
 -- 'Array's from [nested] lists using 'OverloadedLists' GHC extension.
 --
+-- It also includes more generic 'arrayNestedList' and 'toNestedList'
+-- functions to convert between nested lists and 'Array's with any indices.
+--
 -- __Examples__:
 --
 -- >>> ["one","two","three"] :: Array Int String
@@ -24,15 +29,24 @@
 -- >>> [[0,1,2], [10,11,12]] :: Array (Int, Int) Int
 -- array ((0,0),(1,2)) [((0,0),0),((0,1),1),((0,2),2),((1,0),10),((1,1),11),((1,2),12)]
 --
--- If any of the nested lists contains different number of elements
--- for the same dimension, the array creation will fail.
+-- If any of the nested lists contains smaller number of elements
+-- than the first nested list in the same dimension,
+-- the array creation will fail.
 --
--- >>> [[1],[2,3]] :: Array (Int, Int) Int
--- array *** Exception: Error in array index
+-- >>> [[1,2],[3]] :: Array (Int, Int) Int
+-- ... Exception: (Array.!): undefined array element
+--
+-- Nested lists with larger number of elements will be truncated.
 module Data.Array.IsList
-  ( IsList,
+  ( -- * IsList
+    IsList,
     fromList,
     toList,
+
+    -- * ArrayNestedList
+    ArrayNestedList,
+    arrayNestedList,
+    toNestedList,
   )
 where
 
@@ -106,47 +120,20 @@
 genericFromList :: (Integral i, Ix i) => [e] -> Array i e
 genericFromList xs = listArray (0, top xs) xs
 
-splitList :: Integral i => i -> i -> [e] -> [[e]]
-splitList _ _ [] = []
-splitList l r xs =
-  let (part, rest) = genericSplitAt (r - l + 1) xs
-   in part : splitList l r rest
-
 top :: Integral i => [e] -> i
 top l = genericLength l - 1
 
-h1 :: [e] -> e
-h1 = head
-
-h2 :: [[e]] -> e
-h2 = head . head
-
-h3 :: [[[e]]] -> e
-h3 = head . h2
-
-h4 :: [[[[e]]]] -> e
-h4 = head . h3
-
-inxd :: Integral i => [e] -> [(i, e)]
-inxd = zip [0 ..]
-
 instance
   (Integral i, Integral j, Ix i, Ix j) =>
   IsList (Array (i, j) e)
   where
   type Item (Array (i, j) e) = [e]
   fromList :: [[e]] -> Array (i, j) e
-  fromList l =
-    array
-      ((0, 0), (top l, top $ h1 l))
-      [ ((i, j), x)
-        | (i, xs) <- inxd l,
-          (j, x) <- inxd xs
-      ]
+  fromList l = arrayNestedList bnds l
+    where
+      bnds = ((0, 0), (top l, top $ head l))
   toList :: Array (i, j) e -> [[e]]
-  toList arr =
-    let ((_, l), (_, r)) = bounds arr
-     in splitList l r $ elems arr
+  toList = toNestedList
 
 instance
   (Integral i, Integral j, Integral k, Ix i, Ix j, Ix k) =>
@@ -154,87 +141,154 @@
   where
   type Item (Array (i, j, k) e) = [[e]]
   fromList :: [[[e]]] -> Array (i, j, k) e
-  fromList l =
-    array
-      ((0, 0, 0), (top l, top $ h1 l, top $ h2 l))
-      [ ((i, j, k), x)
-        | (i, xss) <- inxd l,
-          (j, xs) <- inxd xss,
-          (k, x) <- inxd xs
-      ]
+  fromList l = arrayNestedList bnds l
+    where
+      (h1, h2) = (head l, head h1)
+      bnds = ((0, 0, 0), (top l, top h1, top h2))
   toList :: Array (i, j, k) e -> [[[e]]]
-  toList arr =
-    let ((_, l1, l2), (_, r1, r2)) = bounds arr
-     in splitList l1 r1
-          $ splitList l2 r2
-          $ elems arr
+  toList = toNestedList
 
 instance
-  ( Integral i,
-    Integral j,
-    Integral k,
-    Integral m,
-    Ix i,
-    Ix j,
-    Ix k,
-    Ix m
-  ) =>
+  (Integral i, Integral j, Integral k, Integral m, Ix i, Ix j, Ix k, Ix m) =>
   IsList (Array (i, j, k, m) e)
   where
   type Item (Array (i, j, k, m) e) = [[[e]]]
   fromList :: [[[[e]]]] -> Array (i, j, k, m) e
-  fromList l =
-    array
-      ( (0, 0, 0, 0),
-        (top l, top $ h1 l, top $ h2 l, top $ h3 l)
-      )
-      [ ((i, j, k, m), x)
-        | (i, xsss) <- inxd l,
-          (j, xss) <- inxd xsss,
-          (k, xs) <- inxd xss,
-          (m, x) <- inxd xs
-      ]
+  fromList l = arrayNestedList bnds l
+    where
+      (h1, h2, h3) = (head l, head h1, head h2)
+      bnds = ((0, 0, 0, 0), (top l, top h1, top h2, top h3))
   toList :: Array (i, j, k, m) e -> [[[[e]]]]
-  toList arr =
-    let ((_, l1, l2, l3), (_, r1, r2, r3)) = bounds arr
-     in splitList l1 r1
-          $ splitList l2 r2
-          $ splitList l3 r3
-          $ elems arr
+  toList = toNestedList
 
 instance
-  ( Integral i,
-    Integral j,
-    Integral k,
-    Integral m,
-    Integral n,
-    Ix i,
-    Ix j,
-    Ix k,
-    Ix m,
-    Ix n
-  ) =>
+  (Integral i, Integral j, Integral k, Integral m, Integral n, Ix i, Ix j, Ix k, Ix m, Ix n) =>
   IsList (Array (i, j, k, m, n) e)
   where
   type Item (Array (i, j, k, m, n) e) = [[[[e]]]]
   fromList :: [[[[[e]]]]] -> Array (i, j, k, m, n) e
-  fromList l =
+  fromList l = arrayNestedList bnds l
+    where
+      (h1, h2, h3, h4) = (head l, head h1, head h2, head h3)
+      bnds = ((0, 0, 0, 0, 0), (top l, top h1, top h2, top h3, top h4))
+  toList :: Array (i, j, k, m, n) e -> [[[[[e]]]]]
+  toList = toNestedList
+
+-- | 'ArrayNestedList' class defines methods to convert between
+-- nested lists and multi-dimensional (up to 5) 'Array's with any indices,
+-- not only 'Integral', using provided range of indices.
+class Ix i => ArrayNestedList i e where
+  type NestedList i e
+
+  -- | Converts nested list to multi-dimensional 'Array'
+  -- Similarly to 'arrayList' function, it does not require to pass index
+  -- for each element, only the range of indices.
+  arrayNestedList :: (i, i) -> NestedList i e -> Array i e
+
+  -- | Converts multi-dimensional 'Array' to nested list.
+  toNestedList :: Array i e -> NestedList i e
+
+instance (Ix i, Ix j) => ArrayNestedList (i, j) e where
+  type NestedList (i, j) e = [[e]]
+  arrayNestedList ::
+    ((i, j), (i, j)) -> [[e]] -> Array (i, j) e
+  arrayNestedList bnds@((l1, l2), (r1, r2)) l =
     array
-      ( (0, 0, 0, 0, 0),
-        (top l, top $ h1 l, top $ h2 l, top $ h3 l, top $ h4 l)
-      )
+      bnds
+      [ ((i, j), x)
+        | xs <- l,
+          x <- xs
+        | i <- range (l1, r1),
+          j <- range (l2, r2)
+      ]
+  toNestedList :: Array (i, j) e -> [[e]]
+  toNestedList arr =
+    let ((_, l2), (_, r2)) = bounds arr
+     in splitList (l2, r2) $ elems arr
+
+splitList :: Ix i => (i, i) -> [e] -> [[e]]
+splitList = split' . rangeSize
+  where
+    split' _ [] = []
+    split' n xs =
+      let (part, rest) = splitAt n xs
+       in part : split' n rest
+
+instance (Ix i, Ix j, Ix k) => ArrayNestedList (i, j, k) e where
+  type NestedList (i, j, k) e = [[[e]]]
+  arrayNestedList ::
+    ((i, j, k), (i, j, k)) -> [[[e]]] -> Array (i, j, k) e
+  arrayNestedList bnds@((l1, l2, l3), (r1, r2, r3)) l =
+    array
+      bnds
+      [ ((i, j, k), x)
+        | xss <- l,
+          xs <- xss,
+          x <- xs
+        | i <- range (l1, r1),
+          j <- range (l2, r2),
+          k <- range (l3, r3)
+      ]
+  toNestedList :: Array (i, j, k) e -> [[[e]]]
+  toNestedList arr =
+    let ((_, l2, l3), (_, r2, r3)) = bounds arr
+     in splitList (l2, r2)
+          $ splitList (l3, r3)
+          $ elems arr
+
+instance (Ix i, Ix j, Ix k, Ix m) => ArrayNestedList (i, j, k, m) e where
+  type NestedList (i, j, k, m) e = [[[[e]]]]
+  arrayNestedList ::
+    ((i, j, k, m), (i, j, k, m)) ->
+    [[[[e]]]] ->
+    Array (i, j, k, m) e
+  arrayNestedList bnds@((l1, l2, l3, l4), (r1, r2, r3, r4)) l =
+    array
+      bnds
+      [ ((i, j, k, m), x)
+        | xsss <- l,
+          xss <- xsss,
+          xs <- xss,
+          x <- xs
+        | i <- range (l1, r1),
+          j <- range (l2, r2),
+          k <- range (l3, r3),
+          m <- range (l4, r4)
+      ]
+  toNestedList :: Array (i, j, k, m) e -> [[[[e]]]]
+  toNestedList arr =
+    let ((_, l2, l3, l4), (_, r2, r3, r4)) = bounds arr
+     in splitList (l2, r2)
+          $ splitList (l3, r3)
+          $ splitList (l4, r4)
+          $ elems arr
+
+instance (Ix i, Ix j, Ix k, Ix m, Ix n) => ArrayNestedList (i, j, k, m, n) e where
+  type NestedList (i, j, k, m, n) e = [[[[[e]]]]]
+  arrayNestedList ::
+    ((i, j, k, m, n), (i, j, k, m, n)) ->
+    [[[[[e]]]]] ->
+    Array (i, j, k, m, n) e
+  arrayNestedList bnds@((l1, l2, l3, l4, l5), (r1, r2, r3, r4, r5)) l =
+    array
+      bnds
       [ ((i, j, k, m, n), x)
-        | (i, xssss) <- inxd l,
-          (j, xsss) <- inxd xssss,
-          (k, xss) <- inxd xsss,
-          (m, xs) <- inxd xss,
-          (n, x) <- inxd xs
+        | xssss <- l,
+          xsss <- xssss,
+          xss <- xsss,
+          xs <- xss,
+          x <- xs
+        | i <- range (l1, r1),
+          j <- range (l2, r2),
+          k <- range (l3, r3),
+          m <- range (l4, r4),
+          n <- range (l5, r5)
       ]
-  toList :: Array (i, j, k, m, n) e -> [[[[[e]]]]]
-  toList arr =
-    let ((_, l1, l2, l3, l4), (_, r1, r2, r3, r4)) = bounds arr
-     in splitList l1 r1
-          $ splitList l2 r2
-          $ splitList l3 r3
-          $ splitList l4 r4
+  toNestedList :: Array (i, j, k, m, n) e -> [[[[[e]]]]]
+  toNestedList arr =
+    let ((_, l2, l3, l4, l5), (_, r2, r3, r4, r5)) = bounds arr
+     in splitList (l2, r2)
+          $ splitList (l3, r3)
+          $ splitList (l4, r4)
+          $ splitList (l5, r5)
           $ elems arr
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -7,6 +7,12 @@
 
 main :: IO ()
 main = hspec do
+  describe "array-list" do
+    isListTest
+    arrayNestedListTest
+
+isListTest :: SpecWith ()
+isListTest = describe "IsList" do
   describe "IsList (Array Int e)" do
     it "[1,2,3]" $
       ([1, 2, 3] :: Array Int Int)
@@ -191,6 +197,183 @@
             ]
           ] ::
             Array (Int, Int, Int, Int, Int) Int
+        )
+        `shouldBe` [ [ [[[0, 1], [2, 3]], [[4, 5], [6, 7]]],
+                       [[[8, 9], [10, 11]], [[12, 13], [14, 15]]]
+                     ],
+                     [ [[[16, 17], [18, 19]], [[20, 21], [22, 23]]],
+                       [[[24, 25], [26, 27]], [[28, 29], [30, 31]]]
+                     ]
+                   ]
+
+arrayNestedListTest :: SpecWith ()
+arrayNestedListTest = describe "ArrayNestedList" do
+  describe "ArrayNestedList (Bool,Bool) e" do
+    it "[[1, 2], [3, 4]]" $
+      ( arrayNestedList
+          ((False, False), (True, True))
+          [[1, 2], [3, 4]] ::
+          Array (Bool, Bool) Int
+      )
+        `shouldBe` array
+          ((False, False), (True, True))
+          [ ((False, False), 1),
+            ((False, True), 2),
+            ((True, False), 3),
+            ((True, True), 4)
+          ]
+    it "toNestedList . arrayNestedList == id" $
+      toNestedList
+        ( arrayNestedList
+            ((False, False), (True, True))
+            [[1, 2], [3, 4]] ::
+            Array (Bool, Bool) Int
+        )
+        `shouldBe` [[1, 2], [3, 4]]
+  describe "ArrayNestedList (Bool,Bool,Bool) e" do
+    it "3D-array" $
+      ( arrayNestedList
+          ((False, False, False), (True, True, True))
+          [ [[1, 2], [3, 4]],
+            [[5, 6], [7, 8]]
+          ] ::
+          Array (Bool, Bool, Bool) Int
+      )
+        `shouldBe` array
+          ((False, False, False), (True, True, True))
+          [ ((False, False, False), 1),
+            ((False, False, True), 2),
+            ((False, True, False), 3),
+            ((False, True, True), 4),
+            ((True, False, False), 5),
+            ((True, False, True), 6),
+            ((True, True, False), 7),
+            ((True, True, True), 8)
+          ]
+    it "toNestedList . arrayNestedList == id" $
+      toNestedList
+        ( arrayNestedList
+            ((False, False, False), (True, True, True))
+            [ [[1, 2], [3, 4]],
+              [[5, 6], [7, 8]]
+            ] ::
+            Array (Bool, Bool, Bool) Int
+        )
+        `shouldBe` [ [[1, 2], [3, 4]],
+                     [[5, 6], [7, 8]]
+                   ]
+  describe "ArrayNestedList (Bool,Bool,Bool,Bool) e" do
+    it "4D-array" $
+      ( arrayNestedList
+          ((False, False, False, False), (True, True, True, True))
+          [ [ [[0, 1], [2, 3]],
+              [[4, 5], [6, 7]]
+            ],
+            [ [[8, 9], [10, 11]],
+              [[12, 13], [14, 15]]
+            ]
+          ] ::
+          Array (Bool, Bool, Bool, Bool) Int
+      )
+        `shouldBe` array
+          ((False, False, False, False), (True, True, True, True))
+          [ ((False, False, False, False), 0),
+            ((False, False, False, True), 1),
+            ((False, False, True, False), 2),
+            ((False, False, True, True), 3),
+            ((False, True, False, False), 4),
+            ((False, True, False, True), 5),
+            ((False, True, True, False), 6),
+            ((False, True, True, True), 7),
+            ((True, False, False, False), 8),
+            ((True, False, False, True), 9),
+            ((True, False, True, False), 10),
+            ((True, False, True, True), 11),
+            ((True, True, False, False), 12),
+            ((True, True, False, True), 13),
+            ((True, True, True, False), 14),
+            ((True, True, True, True), 15)
+          ]
+    it "toNestedList . arrayNestedList == id" $
+      toNestedList
+        ( arrayNestedList
+            ((False, False, False, False), (True, True, True, True))
+            [ [ [[0, 1], [2, 3]],
+                [[4, 5], [6, 7]]
+              ],
+              [ [[8, 9], [10, 11]],
+                [[12, 13], [14, 15]]
+              ]
+            ] ::
+            Array (Bool, Bool, Bool, Bool) Int
+        )
+        `shouldBe` [ [ [[0, 1], [2, 3]],
+                       [[4, 5], [6, 7]]
+                     ],
+                     [ [[8, 9], [10, 11]],
+                       [[12, 13], [14, 15]]
+                     ]
+                   ]
+  describe "ArrayNestedList (Bool,Bool,Bool,Bool,Bool) e" do
+    it "5D-array" $
+      ( arrayNestedList
+          ((False, False, False, False, False), (True, True, True, True, True))
+          [ [ [[[0, 1], [2, 3]], [[4, 5], [6, 7]]],
+              [[[8, 9], [10, 11]], [[12, 13], [14, 15]]]
+            ],
+            [ [[[16, 17], [18, 19]], [[20, 21], [22, 23]]],
+              [[[24, 25], [26, 27]], [[28, 29], [30, 31]]]
+            ]
+          ] ::
+          Array (Bool, Bool, Bool, Bool, Bool) Int
+      )
+        `shouldBe` array
+          ((False, False, False, False, False), (True, True, True, True, True))
+          [ ((False, False, False, False, False), 0),
+            ((False, False, False, False, True), 1),
+            ((False, False, False, True, False), 2),
+            ((False, False, False, True, True), 3),
+            ((False, False, True, False, False), 4),
+            ((False, False, True, False, True), 5),
+            ((False, False, True, True, False), 6),
+            ((False, False, True, True, True), 7),
+            ((False, True, False, False, False), 8),
+            ((False, True, False, False, True), 9),
+            ((False, True, False, True, False), 10),
+            ((False, True, False, True, True), 11),
+            ((False, True, True, False, False), 12),
+            ((False, True, True, False, True), 13),
+            ((False, True, True, True, False), 14),
+            ((False, True, True, True, True), 15),
+            ((True, False, False, False, False), 16),
+            ((True, False, False, False, True), 17),
+            ((True, False, False, True, False), 18),
+            ((True, False, False, True, True), 19),
+            ((True, False, True, False, False), 20),
+            ((True, False, True, False, True), 21),
+            ((True, False, True, True, False), 22),
+            ((True, False, True, True, True), 23),
+            ((True, True, False, False, False), 24),
+            ((True, True, False, False, True), 25),
+            ((True, True, False, True, False), 26),
+            ((True, True, False, True, True), 27),
+            ((True, True, True, False, False), 28),
+            ((True, True, True, False, True), 29),
+            ((True, True, True, True, False), 30),
+            ((True, True, True, True, True), 31)
+          ]
+    it "toNestedList . arrayNestedList == id" $
+      toNestedList
+        ( arrayNestedList
+            ((False, False, False, False, False), (True, True, True, True, True))
+            [ [ [[[0, 1], [2, 3]], [[4, 5], [6, 7]]],
+                [[[8, 9], [10, 11]], [[12, 13], [14, 15]]]
+              ],
+              [ [[[16, 17], [18, 19]], [[20, 21], [22, 23]]],
+                [[[24, 25], [26, 27]], [[28, 29], [30, 31]]]
+              ]
+            ] ::
+            Array (Bool, Bool, Bool, Bool, Bool) Int
         )
         `shouldBe` [ [ [[[0, 1], [2, 3]], [[4, 5], [6, 7]]],
                        [[[8, 9], [10, 11]], [[12, 13], [14, 15]]]
