packages feed

array-list 0.1.0.0 → 0.2.0.0

raw patch · 5 files changed

+355/−107 lines, 5 filesdep ~doctestPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: doctest

API changes (from Hackage documentation)

+ Data.Array.IsList: arrayNestedList :: ArrayNestedList i e => (i, i) -> NestedList i e -> Array i e
+ Data.Array.IsList: class Ix i => ArrayNestedList i e
+ Data.Array.IsList: instance (GHC.Arr.Ix i, GHC.Arr.Ix j) => Data.Array.IsList.ArrayNestedList (i, j) e
+ Data.Array.IsList: instance (GHC.Arr.Ix i, GHC.Arr.Ix j, GHC.Arr.Ix k) => Data.Array.IsList.ArrayNestedList (i, j, k) e
+ Data.Array.IsList: instance (GHC.Arr.Ix i, GHC.Arr.Ix j, GHC.Arr.Ix k, GHC.Arr.Ix m) => Data.Array.IsList.ArrayNestedList (i, j, k, m) e
+ Data.Array.IsList: instance (GHC.Arr.Ix i, GHC.Arr.Ix j, GHC.Arr.Ix k, GHC.Arr.Ix m, GHC.Arr.Ix n) => Data.Array.IsList.ArrayNestedList (i, j, k, m, n) e
+ Data.Array.IsList: toNestedList :: ArrayNestedList i e => Array i e -> NestedList i e

Files

CHANGELOG.md view
@@ -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
README.md view
@@ -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).
array-list.cabal view
@@ -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 
src/Data/Array/IsList.hs view
@@ -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
tests/Main.hs view
@@ -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]]]