array-list (empty) → 0.1.0.0
raw patch · 8 files changed
+549/−0 lines, 8 filesdep +arraydep +array-listdep +basesetup-changed
Dependencies added: array, array-list, base, doctest, doctest-driver-gen, hspec
Files
- CHANGELOG.md +5/−0
- LICENSE +21/−0
- README.md +5/−0
- Setup.hs +2/−0
- array-list.cabal +74/−0
- src/Data/Array/IsList.hs +240/−0
- tests/Main.hs +201/−0
- tests/doctest-driver.hs +1/−0
+ CHANGELOG.md view
@@ -0,0 +1,5 @@+## 0.1.0.0++- Initial release+- Includes `IsList` instances for `Array`s with `Integral` indices,+up to 5 dimensions
+ LICENSE view
@@ -0,0 +1,21 @@+The MIT License (MIT)++Copyright (c) 2020 Evgeny Poberezkin++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,5 @@+# 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++See [docs and usage examples on hackage](http://hackage.haskell.org/package/array-list/docs/Data-Array-IsList.html).
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ array-list.cabal view
@@ -0,0 +1,74 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.33.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: ed946011242c8c41f9762a9ddaadd8ee8ab793a2361e2cba2c0bcc0d11f18c9d++name: array-list+version: 0.1.0.0+synopsis: IsList instances of Array for OverloadedLists extension+description: This package provides "orphan" instances 'IsList' for 'Array' data types+ with `Integral` indices up to 5 dimensions to allow initializing+ 'Array's from [nested] lists using 'OverloadedLists' GHC extension.+category: Data, Array, List+homepage: https://github.com/epoberezkin/array-list#readme+bug-reports: https://github.com/epoberezkin/array-list/issues+author: Evgeny Poberezkin+maintainer: evgeny@poberezkin.com+copyright: 2020 Evgeny Poberezkin+license: MIT+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ CHANGELOG.md++source-repository head+ type: git+ location: https://github.com/epoberezkin/array-list++library+ exposed-modules:+ Data.Array.IsList+ other-modules:+ Paths_array_list+ hs-source-dirs:+ src+ ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns+ build-depends:+ array ==0.5.*+ , base >=4.7 && <5+ default-language: Haskell2010++test-suite array-list-doctest+ type: exitcode-stdio-1.0+ main-is: doctest-driver.hs+ other-modules:+ Main+ Paths_array_list+ hs-source-dirs:+ tests+ ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns+ build-depends:+ array ==0.5.*+ , base >=4.7 && <5+ , doctest ==0.17.*+ , doctest-driver-gen ==0.3.*+ default-language: Haskell2010++test-suite array-list-test+ type: exitcode-stdio-1.0+ main-is: Main.hs+ other-modules:+ Paths_array_list+ hs-source-dirs:+ tests+ ghc-options: -Wall -Wcompat -Werror=incomplete-patterns -Wredundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns+ build-depends:+ array ==0.5.*+ , array-list+ , base >=4.7 && <5+ , hspec ==2.7.*+ default-language: Haskell2010
+ src/Data/Array/IsList.hs view
@@ -0,0 +1,240 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE TypeFamilies #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}++-- |+-- Module : Data.Array.IsList+-- Copyright : (c) Evgeny Poberezkin+-- License : MIT+--+-- Maintainer : evgeny@poberezkin.com+-- Stability : experimental+-- Portability : non-portable+--+-- This package provides "orphan" 'IsList' instances for 'Array's+-- with `Integral` indices up to 5 dimensions to allow initializing+-- 'Array's from [nested] lists using 'OverloadedLists' GHC extension.+--+-- __Examples__:+--+-- >>> ["one","two","three"] :: Array Int String+-- array (0,2) [(0,"one"),(1,"two"),(2,"three")]+--+-- >>> [[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.+--+-- >>> [[1],[2,3]] :: Array (Int, Int) Int+-- array *** Exception: Error in array index+module Data.Array.IsList+ ( IsList,+ fromList,+ toList,+ )+where++import Data.Array+import Data.Int+import Data.List+import Data.Word+import GHC.Exts+import Numeric.Natural++instance IsList (Array Int e) where+ type Item (Array Int e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Int8 e) where+ type Item (Array Int8 e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Int16 e) where+ type Item (Array Int16 e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Int32 e) where+ type Item (Array Int32 e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Int64 e) where+ type Item (Array Int64 e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Integer e) where+ type Item (Array Integer e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Natural e) where+ type Item (Array Natural e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Word e) where+ type Item (Array Word e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Word8 e) where+ type Item (Array Word8 e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Word16 e) where+ type Item (Array Word16 e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Word32 e) where+ type Item (Array Word32 e) = e+ fromList = genericFromList+ toList = elems++instance IsList (Array Word64 e) where+ type Item (Array Word64 e) = e+ fromList = genericFromList+ toList = elems++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+ ]+ toList :: Array (i, j) e -> [[e]]+ toList arr =+ let ((_, l), (_, r)) = bounds arr+ in splitList l r $ elems arr++instance+ (Integral i, Integral j, Integral k, Ix i, Ix j, Ix k) =>+ IsList (Array (i, j, k) e)+ 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+ ]+ 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++instance+ ( 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+ ]+ 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++instance+ ( 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 =+ array+ ( (0, 0, 0, 0, 0),+ (top l, top $ h1 l, top $ h2 l, top $ h3 l, top $ h4 l)+ )+ [ ((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+ ]+ 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+ $ elems arr
+ tests/Main.hs view
@@ -0,0 +1,201 @@+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE OverloadedLists #-}++import Data.Array+import Data.Array.IsList+import Test.Hspec++main :: IO ()+main = hspec do+ describe "IsList (Array Int e)" do+ it "[1,2,3]" $+ ([1, 2, 3] :: Array Int Int)+ `shouldBe` array (0, 2) [(0, 1), (1, 2), (2, 3)]+ it "[\"one\",\"two\",\"three\"]" $+ (["one", "two", "three"] :: Array Int String)+ `shouldBe` array (0, 2) [(0, "one"), (1, "two"), (2, "three")]+ it "toList $ fromList [1,2,3]" $+ toList ([1, 2, 3] :: Array Int Int)+ `shouldBe` [1, 2, 3]+ it "toList $ fromList [\"one\",\"two\",\"three\"]" $+ toList (["one", "two", "three"] :: Array Int String)+ `shouldBe` ["one", "two", "three"]+ describe "IsList (Array (Int,Int) e)" do+ it "[[1, 2], [3, 4], [5, 6]]" $+ ( [ [1, 2],+ [3, 4],+ [5, 6]+ ] ::+ Array (Int, Int) Int+ )+ `shouldBe` array+ ((0, 0), (2, 1))+ [ ((0, 0), 1),+ ((0, 1), 2),+ ((1, 0), 3),+ ((1, 1), 4),+ ((2, 0), 5),+ ((2, 1), 6)+ ]+ it "toList . fromList == id" $+ toList+ ( [ [1, 2],+ [3, 4],+ [5, 6]+ ] ::+ Array (Int, Int) Int+ )+ `shouldBe` [[1, 2], [3, 4], [5, 6]]+ describe "IsList (Array (Int,Int,Int) e)" do+ it "3D-array" $+ ( [ [[1, 2, 3], [4, 5, 6]],+ [[7, 8, 9], [10, 11, 12]],+ [[13, 14, 15], [16, 17, 18]]+ ] ::+ Array (Int, Int, Int) Int+ )+ `shouldBe` array+ ((0, 0, 0), (2, 1, 2))+ [ ((0, 0, 0), 1),+ ((0, 0, 1), 2),+ ((0, 0, 2), 3),+ ((0, 1, 0), 4),+ ((0, 1, 1), 5),+ ((0, 1, 2), 6),+ ((1, 0, 0), 7),+ ((1, 0, 1), 8),+ ((1, 0, 2), 9),+ ((1, 1, 0), 10),+ ((1, 1, 1), 11),+ ((1, 1, 2), 12),+ ((2, 0, 0), 13),+ ((2, 0, 1), 14),+ ((2, 0, 2), 15),+ ((2, 1, 0), 16),+ ((2, 1, 1), 17),+ ((2, 1, 2), 18)+ ]+ it "toList . fromList == id" $+ toList+ ( [ [[1, 2, 3], [4, 5, 6]],+ [[7, 8, 9], [10, 11, 12]],+ [[13, 14, 15], [16, 17, 18]]+ ] ::+ Array (Int, Int, Int) Int+ )+ `shouldBe` [ [[1, 2, 3], [4, 5, 6]],+ [[7, 8, 9], [10, 11, 12]],+ [[13, 14, 15], [16, 17, 18]]+ ]+ describe "IsList (Array (Int,Int,Int,Int) e)" do+ it "4D-array" $+ ( [ [ [[0, 1], [2, 3]],+ [[4, 5], [6, 7]]+ ],+ [ [[8, 9], [10, 11]],+ [[12, 13], [14, 15]]+ ]+ ] ::+ Array (Int, Int, Int, Int) Int+ )+ `shouldBe` array+ ((0, 0, 0, 0), (1, 1, 1, 1))+ [ ((0, 0, 0, 0), 0),+ ((0, 0, 0, 1), 1),+ ((0, 0, 1, 0), 2),+ ((0, 0, 1, 1), 3),+ ((0, 1, 0, 0), 4),+ ((0, 1, 0, 1), 5),+ ((0, 1, 1, 0), 6),+ ((0, 1, 1, 1), 7),+ ((1, 0, 0, 0), 8),+ ((1, 0, 0, 1), 9),+ ((1, 0, 1, 0), 10),+ ((1, 0, 1, 1), 11),+ ((1, 1, 0, 0), 12),+ ((1, 1, 0, 1), 13),+ ((1, 1, 1, 0), 14),+ ((1, 1, 1, 1), 15)+ ]+ it "toList . fromList == id" $+ toList+ ( [ [ [[0, 1], [2, 3]],+ [[4, 5], [6, 7]]+ ],+ [ [[8, 9], [10, 11]],+ [[12, 13], [14, 15]]+ ]+ ] ::+ Array (Int, Int, Int, Int) Int+ )+ `shouldBe` [ [ [[0, 1], [2, 3]],+ [[4, 5], [6, 7]]+ ],+ [ [[8, 9], [10, 11]],+ [[12, 13], [14, 15]]+ ]+ ]+ describe "IsList (Array (Int,Int,Int,Int,Int) e)" do+ it "5D-array" $+ ( [ [ [[[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 (Int, Int, Int, Int, Int) Int+ )+ `shouldBe` array+ ((0, 0, 0, 0, 0), (1, 1, 1, 1, 1))+ [ ((0, 0, 0, 0, 0), 0),+ ((0, 0, 0, 0, 1), 1),+ ((0, 0, 0, 1, 0), 2),+ ((0, 0, 0, 1, 1), 3),+ ((0, 0, 1, 0, 0), 4),+ ((0, 0, 1, 0, 1), 5),+ ((0, 0, 1, 1, 0), 6),+ ((0, 0, 1, 1, 1), 7),+ ((0, 1, 0, 0, 0), 8),+ ((0, 1, 0, 0, 1), 9),+ ((0, 1, 0, 1, 0), 10),+ ((0, 1, 0, 1, 1), 11),+ ((0, 1, 1, 0, 0), 12),+ ((0, 1, 1, 0, 1), 13),+ ((0, 1, 1, 1, 0), 14),+ ((0, 1, 1, 1, 1), 15),+ ((1, 0, 0, 0, 0), 16),+ ((1, 0, 0, 0, 1), 17),+ ((1, 0, 0, 1, 0), 18),+ ((1, 0, 0, 1, 1), 19),+ ((1, 0, 1, 0, 0), 20),+ ((1, 0, 1, 0, 1), 21),+ ((1, 0, 1, 1, 0), 22),+ ((1, 0, 1, 1, 1), 23),+ ((1, 1, 0, 0, 0), 24),+ ((1, 1, 0, 0, 1), 25),+ ((1, 1, 0, 1, 0), 26),+ ((1, 1, 0, 1, 1), 27),+ ((1, 1, 1, 0, 0), 28),+ ((1, 1, 1, 0, 1), 29),+ ((1, 1, 1, 1, 0), 30),+ ((1, 1, 1, 1, 1), 31)+ ]+ it "toList . fromList == id" $+ toList+ ( [ [ [[[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 (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]]]+ ]+ ]
+ tests/doctest-driver.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF doctest-driver-gen -optF src -optF -XOverloadedLists #-}