packages feed

orthotope 0.1.5.0 → 0.1.6.0

raw patch · 6 files changed

+1077/−78 lines, 6 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Array.Internal: type N = Int
+ Data.Array.Internal: Rect :: [String] -> Rect
+ Data.Array.Internal: [unRect] :: Rect -> [String]
+ Data.Array.Internal: fromRect :: Rect -> String
+ Data.Array.Internal: hcatRect :: Rect -> Rect -> Rect
+ Data.Array.Internal: newtype Rect
+ Data.Array.Internal: rectHeight :: Rect -> Int
+ Data.Array.Internal: rectPad :: Int -> Int -> Rect -> Rect
+ Data.Array.Internal: rectWidth :: Rect -> Int
+ Data.Array.Internal: toRect :: String -> Rect
+ Data.Array.Internal: vcatRect :: Rect -> Rect -> Rect
- Data.Array.Internal: T :: [N] -> !N -> !v a -> T v a
+ Data.Array.Internal: T :: ![Int] -> !Int -> !v a -> T v a
- Data.Array.Internal: [offset] :: T v a -> !N
+ Data.Array.Internal: [offset] :: T v a -> !Int
- Data.Array.Internal: [strides] :: T v a -> [N]
+ Data.Array.Internal: [strides] :: T v a -> ![Int]
- Data.Array.Internal: box :: BoxMode -> String -> [String]
+ Data.Array.Internal: box :: BoxMode -> Rect -> Rect
- Data.Array.Internal: fromListT :: (Vector v, VecElem v a) => [N] -> [a] -> T v a
+ Data.Array.Internal: fromListT :: (Vector v, VecElem v a) => [Int] -> [a] -> T v a
- Data.Array.Internal: getStridesT :: ShapeL -> [N]
+ Data.Array.Internal: getStridesT :: ShapeL -> [Int]
- Data.Array.Internal: indexT :: T v a -> N -> T v a
+ Data.Array.Internal: indexT :: T v a -> Int -> T v a
- Data.Array.Internal: isCanonicalT :: (Vector v, VecElem v a) => [N] -> T v a -> Bool
+ Data.Array.Internal: isCanonicalT :: (Vector v, VecElem v a) => [Int] -> T v a -> Bool
- Data.Array.Internal: ppT_ :: (Vector v, VecElem v a) => (a -> String) -> ShapeL -> T v a -> String
+ Data.Array.Internal: ppT_ :: (Vector v, VecElem v a) => (a -> String) -> ShapeL -> T v a -> Rect
- Data.Array.Internal: reverseT :: [N] -> ShapeL -> T v a -> T v a
+ Data.Array.Internal: reverseT :: [Int] -> ShapeL -> T v a -> T v a
- Data.Array.Internal: showsT :: [N] -> T [] String -> ShowS
+ Data.Array.Internal: showsT :: [Int] -> T [] Rect -> Rect
- Data.Array.Internal: simpleReshape :: [N] -> ShapeL -> ShapeL -> Maybe [N]
+ Data.Array.Internal: simpleReshape :: [Int] -> ShapeL -> ShapeL -> Maybe [Int]

Files

Data/Array/Internal.hs view
@@ -30,7 +30,7 @@ import Data.Data(Data) import qualified Data.DList as DL import Data.Kind (Type)-import Data.List(foldl', zipWith4, zipWith5, sortBy, sortOn)+import Data.List(foldl', zipWith4, zipWith5, sortBy, sortOn, foldl1') import Data.Proxy import GHC.Exts(Constraint, build) import GHC.Generics(Generic)@@ -115,9 +115,6 @@ prettyShowL :: (Pretty a) => PrettyLevel -> a -> String prettyShowL l = render . pPrintPrec l 0 --- We expect all N to be non-negative, but we use Int for convenience.-type N = Int- -- | The type /T/ is the internal type of arrays.  In general, -- operations on /T/ do no sanity checking as that should be done -- at the point of call.@@ -128,8 +125,8 @@ -- To find where item /i,j/ of the two outermost dimensions is you -- calculate vector index @offset + i*strides[0] + j*strides[1]@, etc. data T v a = T-    { strides :: [N]      -- length is tensor rank-    , offset  :: !N       -- offset into vector of values+    { strides :: ![Int]   -- length is tensor rank+    , offset  :: !Int     -- offset into vector of values     , values  :: !(v a)   -- actual values     }     deriving (Show, Generic, Data)@@ -143,7 +140,9 @@ badShape = any (< 0)  -- When shapes match, we can be efficient and use loop-fused comparisons instead--- of materializing a list.+-- of materializing a vector.+-- Note this assumes the shape is the same for both Vectors.+-- TODO(augustss): if the array is a small fraction of the vector this can be inefficient. {-# INLINABLE equalT #-} equalT :: (Vector v, VecElem v a, Eq a, Eq (v a))                   => ShapeL -> T v a -> T v a -> Bool@@ -161,7 +160,7 @@ -- Given the dimensions, return the stride in the underlying vector -- for each dimension.  The first element of the list is the total length. {-# INLINE getStridesT #-}-getStridesT :: ShapeL -> [N]+getStridesT :: ShapeL -> [Int] getStridesT = scanr (*) 1  -- Convert an array to a list by indexing through all the elements.@@ -186,7 +185,7 @@ -- | Check if the strides are canonical, i.e., if the vector have the natural layout. -- XXX Copy special cases from Tensor. {-# INLINE isCanonicalT #-}-isCanonicalT :: (Vector v, VecElem v a) => [N] -> T v a -> Bool+isCanonicalT :: (Vector v, VecElem v a) => [Int] -> T v a -> Bool isCanonicalT (n:ss') (T ss o v) =     o == 0 &&         -- Vector offset is 0     ss == ss' &&      -- All strides are normal@@ -239,13 +238,14 @@  -- Convert to a vector containing the right elements, -- but not necessarily in the right order.+-- This is used for reduction with commutative&associative operations. {-# INLINE toUnorderedVectorT #-} toUnorderedVectorT :: (Vector v, VecElem v a) => ShapeL -> T v a -> v a toUnorderedVectorT sh a@(T ats ao v) =   -- Figure out if the array maps onto some contiguous slice of the vector.   -- Do this by checking if a transposition of the array corresponds to   -- normal strides.-  -- First sort the strides in descending order, amnd rearrange the shape the same way.+  -- First sort the strides in descending order, and rearrange the shape the same way.   -- Then compute the strides from this rearranged shape; these will be the normal   -- strides for this shape.  If these strides agree with the sorted actual strides   -- it is a transposition, and we can just slice out the relevant piece of the vector.@@ -265,12 +265,12 @@  -- Convert from a list {-# INLINE fromListT #-}-fromListT :: (Vector v, VecElem v a) => [N] -> [a] -> T v a+fromListT :: (Vector v, VecElem v a) => [Int] -> [a] -> T v a fromListT sh = fromVectorT sh . vFromList  -- Index into the outermost dimension of an array. {-# INLINE indexT #-}-indexT :: T v a -> N -> T v a+indexT :: T v a -> Int -> T v a indexT (T (s : ss) o v) i = T ss (o + i * s) v indexT _ _ = error "impossible" @@ -358,7 +358,7 @@  -- Reverse the given dimensions. {-# INLINE reverseT #-}-reverseT :: [N] -> ShapeL -> T v a -> T v a+reverseT :: [Int] -> ShapeL -> T v a -> T v a reverseT rs sh (T ats ao v) = T rts ro v   where (ro, rts) = rev 0 sh ats         rev !_ [] [] = (ao, [])@@ -395,45 +395,86 @@         !x = vIndex v' 0     in  vAll (x ==) v' +newtype Rect = Rect { unRect :: [String] }  -- A rectangle of text++toRect :: String -> Rect+toRect = Rect . lines++fromRect :: Rect -> String+fromRect (Rect ls) = unlines ls++-- Make each Rect be of size h * w+rectPad :: Int -> Int -> Rect -> Rect+rectPad h w (Rect ls) = Rect $ map padL ls ++ replicate (h - length ls) mt+  where mt = replicate w ' '+        padL s = replicate (w - length s) ' ' ++ s++-- Horizontal catenation.  Assumes input rectangle are padded.+-- Adds empty space between Rects.+hcatRect :: Rect -> Rect -> Rect+hcatRect (Rect xs) (Rect ys) = Rect $ zipWith (\ x y -> x ++ " " ++ y) xs ys++-- Vertical catenation.  Assumes input rectangle are padded.+-- Adds no space between Rects.+vcatRect :: Rect -> Rect -> Rect+vcatRect (Rect xs) (Rect ys) = Rect $ xs ++ ys++rectHeight :: Rect -> Int+rectHeight = length . unRect++-- Widest line+rectWidth :: Rect -> Int+rectWidth = maximum . (0:) . map length . unRect+ ppT   :: (Vector v, VecElem v a, Pretty a)   => PrettyLevel -> Rational -> ShapeL -> T v a -> Doc-ppT l p sh = maybeParens (p > 10) . vcat . map text .  box prettyBoxMode . ppT_ (prettyShowL l) sh+ppT l p sh = maybeParens (p > 10) . vcat' . map text . unRect . box boxMode . ppT_ (prettyShowL l) sh+  where boxMode | l >= prettyNormal = BoxMode True True True+                | otherwise = BoxMode False False False+        vcat' = foldl' ($+$) empty  ppT_   :: (Vector v, VecElem v a)-  => (a -> String) -> ShapeL -> T v a -> String-ppT_ show_ sh t = revDropWhile (== '\n') $ showsT sh t' ""-  where ss = map show_ $ toListT sh t-        n = maximum $ map length ss-        ss' = map padSP ss-        padSP s = replicate (n - length s) ' ' ++ s-        t' :: T [] String+  => (a -> String) -> ShapeL -> T v a -> Rect+ppT_ show_ sh t = showsT sh t'+  where ss = map (toRect . show_) $ toListT sh t+        maxH = maximum $ map rectHeight ss+        maxW = maximum $ map rectWidth ss+        ss' = map (rectPad maxH maxW) ss+        t' :: T [] Rect         t' = T (tail (getStridesT sh)) 0 ss' -showsT :: [N] -> T [] String -> ShowS-showsT (0:_)  _ = showString "EMPTY"-showsT []     t = showString $ unScalarT t-showsT s@[_]  t = showString $ unwords $ toListT s t-showsT (n:ns) t =-    foldr (.) id [ showsT ns (indexT t i) . showString "\n" | i <- [0..n-1] ]+showsT :: [Int] -> T [] Rect -> Rect+showsT []     t = unScalarT t+showsT s@[_]  t = foldl1' hcatRect $ toListT s t+showsT (n:ns) t = foldl1' vcat' rs+  where vcat' x y = vcatRect x (vcatRect spc y)+        spc = Rect $ replicate (length ns - 1) (replicate (rectWidth (head rs)) ' ')+        rs = [ showsT ns (indexT t i) | i <- [0..n-1] ]  data BoxMode = BoxMode { _bmBars, _bmUnicode, _bmHeader :: Bool }  prettyBoxMode :: BoxMode prettyBoxMode = BoxMode False False False -box :: BoxMode -> String -> [String]-box BoxMode{..} s =+-- Possibly draw a box around a (padded) rectangle.+box :: BoxMode -> Rect -> Rect+box BoxMode{..} (Rect ls) =   let bar | _bmUnicode = '\x2502'           | otherwise = '|'-      ls = lines s+      dash | _bmUnicode = '\x2500'+           | otherwise = '-'       ls' | _bmBars = map (\ l -> if null l then l else [bar] ++ l ++ [bar]) ls           | otherwise = ls-      h = "+" ++ replicate (length (head ls)) '-' ++ "+"-      ls'' | _bmHeader = [h] ++ ls' ++ [h]+      h = replicate (length (head ls)) dash+      t | _bmUnicode = "\x250c" ++ h ++ "\x2510"+        | otherwise = "+" ++ h ++ "+"+      b | _bmUnicode = "\x2514" ++ h ++ "\x2518"+        | otherwise = t+      ls'' | _bmHeader = [t] ++ ls' ++ [b]            | otherwise = ls'-  in  ls''+  in  Rect ls''  zipWithLong2 :: (a -> b -> b) -> [a] -> [b] -> [b] zipWithLong2 f (a:as) (b:bs) = f a b : zipWithLong2 f as bs@@ -453,7 +494,7 @@ -- size 1, in which case it can be done by just manipulating -- the strides.  Given the old strides, the old shapes, and the -- new shape it will return the possible new strides.-simpleReshape :: [N] -> ShapeL -> ShapeL -> Maybe [N]+simpleReshape :: [Int] -> ShapeL -> ShapeL -> Maybe [Int] simpleReshape osts os ns   | filter (1 /=) os == filter (1 /=) ns = Just $ loop ns sts'     -- Old and new dimensions agree where they are not 1.@@ -467,18 +508,22 @@       loop _ _ = error $ "simpleReshape: shouldn't happen: " ++ show (osts, os, ns) simpleReshape _ _ _ = Nothing +-- Note: assumes + is commutative&associative. {-# INLINE sumT #-} sumT :: (Vector v, VecElem v a, Num a) => ShapeL -> T v a -> a sumT sh = vSum . toUnorderedVectorT sh +-- Note: assumes * is commutative&associative. {-# INLINE productT #-} productT :: (Vector v, VecElem v a, Num a) => ShapeL -> T v a -> a productT sh = vProduct . toUnorderedVectorT sh +-- Note: assumes max is commutative&associative. {-# INLINE maximumT #-} maximumT :: (Vector v, VecElem v a, Ord a) => ShapeL -> T v a -> a maximumT sh = vMaximum . toUnorderedVectorT sh +-- Note: assumes min is commutative&associative. {-# INLINE minimumT #-} minimumT :: (Vector v, VecElem v a, Ord a) => ShapeL -> T v a -> a minimumT sh = vMinimum . toUnorderedVectorT sh
README.md view
@@ -93,11 +93,15 @@ Arrays can be pretty printed.  They are shown in the APL way: The innermost dimension on a line, the next dimension vertically, the next dimension vertically with an empty line in between, and so on.+Normally there is a box drawn around the array, but this can be changed by lowering+pretty printing level to `pPrintPrec`.  ``` > pp m-1 2 3-4 5 6+┌─────┐+│1 2 3│+│4 5 6│+└─────┘ ```  We can have an arbitrary number of dimensions.@@ -107,32 +111,44 @@ > v = fromList [3] [7,8,9] > a = fromList [2,3,4] [1..24] > pp s-42+┌──┐+│42│+└──┘ > pp v-7 8 9+┌─────┐+│7 8 9│+└─────┘ > pp a- 1  2  3  4- 5  6  7  8- 9 10 11 12--13 14 15 16-17 18 19 20-21 22 23 24+┌───────────┐+│ 1  2  3  4│+│ 5  6  7  8│+│ 9 10 11 12│+│           │+│13 14 15 16│+│17 18 19 20│+│21 22 23 24│+└───────────┘ ```  Indexing into an array removes the outermost dimension of it by selecting a subarray with the given index.  ``` > pp $ index v 1-8+┌─┐+│8│+└─┘ > shapeL $ index v 1 [] > pp $ index a 1-13 14 15 16-17 18 19 20-21 22 23 24+┌───────────┐+│13 14 15 16│+│17 18 19 20│+│21 22 23 24│+└───────────┘ > pp $ a `index` 1 `index` 2 `index` 0-21+┌──┐+│21│+└──┘ ```  The `scalar` and `unScalar` functions can be used to convert an element to/from and array.@@ -149,16 +165,20 @@  ``` > pp $ constant [2,3] 8-8 8 8-8 8 8+┌─────┐+│8 8 8│+│8 8 8│+└─────┘ ```  Arrays are also instances of `Functor`, `Foldable`, and `Traversable`.  ``` > pp $ fmap succ v- 8  9 10-foldr (+) 0 a+┌────────┐+│ 8  9 10│+└────────┘+> foldr (+) 0 a 300 ``` @@ -171,14 +191,16 @@ > shapeL (transpose [1,0,2] a) [3,2,4] > pp $ transpose [1,0,2] a- 1  2  3  4-13 14 15 16-- 5  6  7  8-17 18 19 20-- 9 10 11 12-21 22 23 24+┌───────────┐+│ 1  2  3  4│+│13 14 15 16│+│           │+│ 5  6  7  8│+│17 18 19 20│+│           │+│ 9 10 11 12│+│21 22 23 24│+└───────────┘ ```  The `reshape` operation keeps the elements of an array,@@ -186,13 +208,70 @@  ``` > pp $ reshape [3,8] a- 1  2  3  4  5  6  7  8- 9 10 11 12 13 14 15 16-17 18 19 20 21 22 23 24+┌───────────────────────┐+│ 1  2  3  4  5  6  7  8│+│ 9 10 11 12 13 14 15 16│+│17 18 19 20 21 22 23 24│+└───────────────────────┘ ``` +An array can be turned into an array of arrays, where the outermost+array will have rank 1.+```+> pp $ unravel a+┌───────────────────────────┐+│┌───────────┐ ┌───────────┐│+││ 1  2  3  4│ │13 14 15 16││+││ 5  6  7  8│ │17 18 19 20││+││ 9 10 11 12│ │21 22 23 24││+│└───────────┘ └───────────┘│+└───────────────────────────┘+``` +The `foldr` operation reduces an array to something of the element type.+Using `reduce` you will instead get an array result.+```+> pp $ reduce (+) 0 a+┌───┐+│300│+└───┘+``` +Note how this operated on the entire array.  Using `rerank` it is possible+to use a function "deeper down".+```+> pp $ rerank 1 (reduce (+) 0) a+┌───────┐+│ 78 222│+└───────┘+> pp $ rerank 2 (reduce (+) 0) a+┌────────┐+│10 26 42│+│58 74 90│+└────────┘+> pp $ rerank 3 (reduce (+) 0) a+┌───────────┐+│ 1  2  3  4│+│ 5  6  7  8│+│ 9 10 11 12│+│           │+│13 14 15 16│+│17 18 19 20│+│21 22 23 24│+└───────────┘+```++To reduce along some dimension(s) that are not the innermost we can make them innermost by transpostion.+So to sum the columns:+```+> pp $ rerank 2 (reduce (+) 0) $ transpose [0,2,1] a+┌───────────┐+│15 18 21 24│+│51 54 57 60│+└───────────┘+```++ ### Similar examples using `Shaped`  ```@@ -230,15 +309,19 @@ ``` > import Data.Array.Shaped.Instances > pp $ v * 2-14 16 18+┌────────┐+│14 16 18│+└────────┘ > pp $ a + a- 2  4  6  8-10 12 14 16-18 20 22 24--26 28 30 32-34 36 38 40-42 44 46 48+┌───────────┐+│ 2  4  6  8│+│10 12 14 16│+│18 20 22 24│+│           │+│26 28 30 32│+│34 36 38 40│+│42 44 46 48│+└───────────┘ ```  What is value arguments for `Dynamic` arrays sometimes turn into type arguments@@ -246,8 +329,10 @@  ``` > pp $ reshape @[3,8] a- 1  2  3  4  5  6  7  8- 9 10 11 12 13 14 15 16-17 18 19 20 21 22 23 24+┌───────────────────────┐+│ 1  2  3  4  5  6  7  8│+│ 9 10 11 12 13 14 15 16│+│17 18 19 20 21 22 23 24│+└───────────────────────┘ ``` 
orthotope.cabal view
@@ -1,5 +1,5 @@ name:                orthotope-version:             0.1.5.0+version:             0.1.6.0 synopsis:            Multidimensional arrays inspired by APL license:             Apache license-file:        LICENSE@@ -18,7 +18,7 @@       LICENSE       README.md -tested-with:         GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.5 || ==9.6.2+tested-with:         GHC ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.5 || ==9.6.1 || ==9.6.2  source-repository head     type:     git@@ -76,10 +76,13 @@    other-modules:       DynamicTest                      , DynamicUTest+                     , DynamicSTest                      , RankedTest                      , RankedUTest+                     , RankedSTest                      , ShapedTest                      , ShapedUTest+                     , ShapedSTest    ghc-options:     -Wall -rtsopts
+ tests/DynamicSTest.hs view
@@ -0,0 +1,298 @@+-- Copyright 2020 Google LLC+--+-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+--+--      http://www.apache.org/licenses/LICENSE-2.0+--+-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++{-# LANGUAGE ScopedTypeVariables #-}+module DynamicSTest(test) where++import Control.DeepSeq+import Control.Exception+import Data.Array.DynamicS+import qualified Data.Vector.Storable as V+import Test.Framework (Test, testGroup)+import Test.Framework.Providers.HUnit (testCase)+import Test.HUnit (assertEqual, assertFailure, Assertion)++assertThrows :: (NFData a) => String -> a -> Assertion+assertThrows s a = catch (deepseq a $ assertFailure s) (\ (_ :: ErrorCall) -> return ())++test :: Test+test = testGroup "DynamicS" $+  let a1, a2 :: Array Int+      a1 = fromList [2,3] [1..6]+      a2 = transpose [1,0] a1+      show_1 = assertEqual "1" "fromList [2,3] [1,2,3,4,5,6]" (show a1)+      show_2 = assertEqual "2" "fromList [3,2] [1,4,2,5,3,6]" (show a2)+      eq_1 = assertEqual "1" True (a1 == a1)+      eq_2 = assertEqual "2" False (a1 == a2)+      ord_1 = assertEqual "1" EQ (a1 `compare` a1)+      ord_2 = assertEqual "2" LT (a1 `compare` a2)+      shapeL_1 = assertEqual "1" [2,3] (shapeL a1)+      shapeL_2 = assertEqual "2" [3,2] (shapeL a2)+      rank_1 = assertEqual "1" 2 (rank a1)+      rank_2 = assertEqual "2" 2 (rank a2)+      index_1 = assertEqual "1" (fromList [3] [1,2,3]) (index a1 0)+      index_2 = assertEqual "2" (fromList [2] [1,4]) (index a2 0)+      index_3 = assertEqual "3" (fromList [] [4]) (a2 `index` 0 `index` 1)+      index_4 = assertThrows "<0" (index a1 (-1))+      index_5 = assertThrows ">" (index a1 2)+      toList_1 = assertEqual "1" [1,2,3,4,5,6] (toList a1)+      toList_2 = assertEqual "2" [1,4,2,5,3,6] (toList a2)+      toVector_1 = assertEqual "1" (V.fromList [1,2,3,4,5,6]) (toVector a1)+      toVector_2 = assertEqual "2" (V.fromList [1,4,2,5,3,6]) (toVector a2)+      fromList_1 = assertThrows "sh" (fromList [] [1,2::Int])+      fromList_2 = assertThrows "sh" (fromList [4,5] [1,2::Int])+      fromVector_1 = assertEqual "1" a1 (fromVector [2,3] $ V.fromList [1..6])+      normalize_1 = assertEqual "1" a1 (normalize a1)+      reshape_1 = assertEqual "1" (fromList [6] [1..6]) (reshape [6] a1)+      reshape_2 = assertEqual "1" (fromList [1,2,3,1] [1,4,2,5,3,6]) (reshape [1,2,3,1] a2)+      a3, a4 :: Array Int+      a3 = fromList [1] [5]+      a4 = fromList [] [5]+      stretch_1 = assertEqual "1" (fromList [3] [5,5,5]) (stretch [3] a3)+      stretch_2 = assertEqual "2" (fromList [2,2,3,2] [1,1,2,2,3,3,4,4,5,5,6,6,1,1,2,2,3,3,4,4,5,5,6,6])+                                  (stretch [2,2,3,2] $ reshape [1,2,3,1] a1)+      stretch_3 = assertThrows "3" (stretch [1,2] a3)+      stretch_4 = assertThrows "4" (stretch [4,3] a1)+      scalar_1 = assertEqual "1" a4 (scalar 5)+      unScalar_1 = assertEqual "1" 5 (unScalar a4)+      unScalar_2 = assertThrows "2" (unScalar a3)+      constant_1 = assertEqual "1" (fromList [2,3] [1,1,1,1,1,1]) (constant [2,3] (1::Int))+      mapA_1 = assertEqual "1" (fromList [2,3] [2..7]) (mapA succ a1)+      mapA_2 = assertEqual "1" (fromList [3,2] [2,5,3,6,4,7]) (mapA succ a2)+      zipWithA_1 = assertEqual "1" (fromList [2,3] [2,4..12]) (zipWithA (+) a1 a1)+      zipWithA_2 = assertThrows "2" (zipWithA (+) a1 a2)+      zipWith3A_1 = assertEqual "1" (fromList [2,3] [2,6,12,20,30,42]) (zipWith3A (\ x y z -> x*y+z) a1 a1 a1)+      pad_1 = assertEqual "1" (fromList [5,10] [9,9,9,9,9,9,9,9,9,9,+                                                9,9,9,1,2,3,9,9,9,9,+                                                9,9,9,4,5,6,9,9,9,9,+                                                9,9,9,9,9,9,9,9,9,9,+                                                9,9,9,9,9,9,9,9,9,9])+                              (pad [(1,2),(3,4)] 9 a1)+      pad_2 = assertThrows "2" (pad [(1,1),(1,1),(1,1)] 0 a1)+      a5 :: Array Int+      a5 = fromList [2,3,4] [1..24]+      transpose_1 = assertEqual "1" (fromList [2,3,4] [1,2,3,4,+                                                       5,6,7,8,+                                                       9,10,11,12,++                                                       13,14,15,16,+                                                       17,18,19,20,+                                                       21,22,23,24])+                                    (transpose [0,1,2] a5)+      transpose_2 = assertEqual "2" (fromList [2,4,3] [1,5,9,+                                                       2,6,10,+                                                       3,7,11,+                                                       4,8,12,++                                                       13,17,21,+                                                       14,18,22,+                                                       15,19,23,+                                                       16,20,24])+                                    (transpose [0,2,1] a5)+      transpose_3 = assertEqual "3" (fromList [3,2,4] [1,2,3,4,+                                                       13,14,15,16,++                                                       5,6,7,8,+                                                       17,18,19,20,++                                                       9,10,11,12,+                                                       21,22,23,24])+                                    (transpose [1,0,2] a5)+      transpose_4 = assertEqual "4" (fromList [3,4,2] [1,13,+                                                       2,14,+                                                       3,15,+                                                       4,16,++                                                       5,17,+                                                       6,18,+                                                       7,19,+                                                       8,20,++                                                       9,21,+                                                       10,22,+                                                       11,23,+                                                       12,24])+                                    (transpose [1,2,0] a5)+      transpose_5 = assertEqual "5" (fromList [4,2,3] [1,5,9,+                                                       13,17,21,++                                                       2,6,10,++                                                       14,18,22,++                                                       3,7,11,+                                                       15,19,23,++                                                       4,8,12,+                                                       16,20,24])+                                    (transpose [2,0,1] a5)+      transpose_6 = assertEqual "6" (fromList [4,3,2] [1,13,+                                                       5,17,+                                                       9,21,++                                                       2,14,+                                                       6,18,+                                                       10,22,++                                                       3,15,+                                                       7,19,+                                                       11,23,++                                                       4,16,+                                                       8,20,+                                                       12,24])+                                    (transpose [2,1,0] a5)+      transpose_7 = assertThrows "7" (transpose [0,1,2,3] a5)+      transpose_8 = assertThrows "7" (transpose [0,1,3] a5)+      transpose_9 = assertEqual "9" (fromList [3,2,4] [1,2,3,4,+                                                       13,14,15,16,++                                                       5,6,7,8,+                                                       17,18,19,20,++                                                       9,10,11,12,+                                                       21,22,23,24])+                                    (transpose [1,0] a5)+      append_1 = assertEqual "1" (fromList [3,3] [1..9])+                                 (append a1 (fromList [1,3] [7,8,9]))+      concatOuter_1 = assertEqual "1" (fromList [6,3] [1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6])+                                      (concatOuter [a1, concatOuter [a1,a1]])+      concatOuter_2 = assertThrows "2" (concatOuter [a1, a2])+      a6 :: Array Int+      a6 = fromList [4,5] [1..20]+      window_1 = assertEqual "1" (fromList [2,3,3,3] [1,2,3,+                                                      6,7,8,+                                                      11,12,13,++                                                      2,3,4,+                                                      7,8,9,+                                                      12,13,14,++                                                      3,4,5,+                                                      8,9,10,+                                                      13,14,15,+++                                                      6,7,8,+                                                      11,12,13,+                                                      16,17,18,++                                                      7,8,9,+                                                      12,13,14,+                                                      17,18,19,++                                                      8,9,10,+                                                      13,14,15,+                                                      18,19,20])+                                 (window [3,3] a6)+      window_2 = assertThrows "2" (window [3,6] a6)+      window_3 = assertThrows "3" (window [3,3,3] a6)+      stride_1 = assertEqual "1" (fromList [2,2,2] [1,3,+                                                    9,11,++                                                    13,15,+                                                    21,23])+                                 (stride [1,2,2] a5)+      stride_2 = assertThrows "2" (stride [1,2,2] a1)+      slice_1 = assertEqual "1" (fromList [2,2,1] [8,12,20,24])+                                (slice [(0,2),(1,2),(3,1)] a5)+      slice_2 = assertThrows "2" (slice [(0,0)] a4)+      slice_3 = assertThrows "3" (slice [(-1,1)] a5)+      slice_4 = assertThrows "4" (slice [(10,0)] a5)+      slice_5 = assertThrows "5" (slice [(0,3)] a5)+      a7 = mapA succ a5+      dot x y = reduce (+) 0 $ zipWithA (*) x y+      rerank2_1 = assertEqual "1" (fromList [2,3] [40,200,488,904,1448,2120])+                                  (rerank2 2 dot a5 a7)+      rev_1 = assertEqual "1" (fromList [2,3] [3,2,1,6,5,4])+                              (rev [1] a1)+      rev_2 = assertEqual "2" (fromList [2,3] [6,5,4,3,2,1])+                              (rev [0,1] a1)+      rev_3 = assertThrows "3" (rev [2] a1)+      reduce_1 = assertEqual "1" (scalar 720) (reduce (*) 1 a1)+      reduce_2 = assertEqual "2" (fromList [2] [6,120]) (rerank 1 (reduce (*) 1) a1)+      reduce_3 = assertEqual "3" (fromList [3] [4,10,18]) (rerank 1 (reduce (*) 1) a2)++      tests =+        [ testCase "show_1" show_1+        , testCase "show_2" show_2+        , testCase "eq_1" eq_1+        , testCase "eq_2" eq_2+        , testCase "ord_1" ord_1+        , testCase "ord_2" ord_2+        , testCase "shapeL_1" shapeL_1+        , testCase "shapeL_2" shapeL_2+        , testCase "rank_1" rank_1+        , testCase "rank_2" rank_2+        , testCase "index_1" index_1+        , testCase "index_2" index_2+        , testCase "index_3" index_3+        , testCase "index_4" index_4+        , testCase "index_5" index_5+        , testCase "toList_1" toList_1+        , testCase "toList_2" toList_2+        , testCase "toVector_1" toVector_1+        , testCase "toVector_2" toVector_2+        , testCase "fromList_1" fromList_1+        , testCase "fromList_2" fromList_2+        , testCase "fromVector_1" fromVector_1+        , testCase "normalize_1" normalize_1+        , testCase "reshape_1" reshape_1+        , testCase "reshape_2" reshape_2+        , testCase "stretch_1" stretch_1+        , testCase "stretch_2" stretch_2+        , testCase "stretch_3" stretch_3+        , testCase "stretch_4" stretch_4+        , testCase "scalar_1" scalar_1+        , testCase "unScalar_1" unScalar_1+        , testCase "unScalar_2" unScalar_2+        , testCase "constant_1" constant_1+        , testCase "mapA_1" mapA_1+        , testCase "mapA_2" mapA_2+        , testCase "zipWithA_1" zipWithA_1+        , testCase "zipWithA_2" zipWithA_2+        , testCase "zipWith3A_1" zipWith3A_1+        , testCase "pad_1" pad_1+        , testCase "pad_2" pad_2+        , testCase "transpose_1" transpose_1+        , testCase "transpose_2" transpose_2+        , testCase "transpose_3" transpose_3+        , testCase "transpose_4" transpose_4+        , testCase "transpose_5" transpose_5+        , testCase "transpose_6" transpose_6+        , testCase "transpose_7" transpose_7+        , testCase "transpose_8" transpose_8+        , testCase "transpose_9" transpose_9+        , testCase "append_1" append_1+        , testCase "concatOuter_1" concatOuter_1+        , testCase "concatOuter_2" concatOuter_2+        , testCase "window_1" window_1+        , testCase "window_2" window_2+        , testCase "window_3" window_3+        , testCase "stride_1" stride_1+        , testCase "stride_2" stride_2+        , testCase "slice_1" slice_1+        , testCase "slice_2" slice_2+        , testCase "slice_3" slice_3+        , testCase "slice_4" slice_4+        , testCase "slice_5" slice_5+        , testCase "rerank2_1" rerank2_1+        , testCase "rev_1" rev_1+        , testCase "rev_2" rev_2+        , testCase "rev_3" rev_3+        , testCase "reduce_1" reduce_1+        , testCase "reduce_2" reduce_2+        , testCase "reduce_3" reduce_3+        ]+  in  tests
+ tests/RankedSTest.hs view
@@ -0,0 +1,299 @@+-- Copyright 2020 Google LLC+--+-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+--+--      http://www.apache.org/licenses/LICENSE-2.0+--+-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+module RankedSTest(test) where++import Control.DeepSeq+import Control.Exception+import Data.Array.RankedS+import qualified Data.Vector.Storable as V+import Test.Framework (Test, testGroup)+import Test.Framework.Providers.HUnit (testCase)+import Test.HUnit (assertEqual, assertFailure, Assertion)++assertThrows :: (NFData a) => String -> a -> Assertion+assertThrows s a = catch (deepseq a $ assertFailure s) (\ (_ :: ErrorCall) -> return ())++test :: Test+test = testGroup "RankedS" $+  let a1, a2 :: Array 2 Int+      a1 = fromList [2,3] [1..6]+      a2 = transpose [1,0] a1+      show_1 = assertEqual "1" "fromList [2,3] [1,2,3,4,5,6]" (show a1)+      show_2 = assertEqual "2" "fromList [3,2] [1,4,2,5,3,6]" (show a2)+      eq_1 = assertEqual "1" True (a1 == a1)+      eq_2 = assertEqual "2" False (a1 == a2)+      ord_1 = assertEqual "1" EQ (a1 `compare` a1)+      ord_2 = assertEqual "2" LT (a1 `compare` a2)+      shapeL_1 = assertEqual "1" [2,3] (shapeL a1)+      shapeL_2 = assertEqual "2" [3,2] (shapeL a2)+      rank_1 = assertEqual "1" 2 (rank a1)+      rank_2 = assertEqual "2" 2 (rank a2)+      index_1 = assertEqual "1" (fromList [3] [1,2,3]) (index a1 0)+      index_2 = assertEqual "2" (fromList [2] [1,4]) (index a2 0)+      index_3 = assertEqual "3" (fromList [] [4]) (a2 `index` 0 `index` 1)+      index_4 = assertThrows "<0" (index a1 (-1))+      index_5 = assertThrows ">" (index a1 2)+      toList_1 = assertEqual "1" [1,2,3,4,5,6] (toList a1)+      toList_2 = assertEqual "2" [1,4,2,5,3,6] (toList a2)+      toVector_1 = assertEqual "1" (V.fromList [1,2,3,4,5,6]) (toVector a1)+      toVector_2 = assertEqual "2" (V.fromList [1,4,2,5,3,6]) (toVector a2)+      fromList_1 = assertThrows "sh" (fromList [] [1,2] :: Array 0 Int)+      fromList_2 = assertThrows "sh" (fromList [4,5] [1,2] :: Array 2 Int)+      fromVector_1 = assertEqual "1" a1 (fromVector [2,3] $ V.fromList [1..6])+      normalize_1 = assertEqual "1" a1 (normalize a1)+      reshape_1 = assertEqual "1" (fromList [6] [1..6] :: Array 1 Int) (reshape [6] a1)+      reshape_2 = assertEqual "1" (fromList [1,2,3,1] [1,4,2,5,3,6]) (reshape [1,2,3,1] a2 :: Array 4 Int)+      a3 :: Array 1 Int+      a3 = fromList [1] [5]+      a4 :: Array 0 Int+      a4 = fromList [] [5]+      stretch_1 = assertEqual "1" (fromList [3] [5,5,5]) (stretch [3] a3)+      stretch_2 = assertEqual "2" (fromList [2,2,3,2] [1,1,2,2,3,3,4,4,5,5,6,6,1,1,2,2,3,3,4,4,5,5,6,6])+                                  (stretch [2,2,3,2] (reshape [1,2,3,1] a1 :: Array 4 Int))+      stretch_3 = assertThrows "3" (stretch [1,2] a3)+      stretch_4 = assertThrows "4" (stretch [4,3] a1)+      scalar_1 = assertEqual "1" a4 (scalar 5)+      unScalar_1 = assertEqual "1" 5 (unScalar a4)+      constant_1 = assertEqual "1" (fromList [2,3] [1,1,1,1,1,1]) (constant [2,3] 1 :: Array 2 Int)+      mapA_1 = assertEqual "1" (fromList [2,3] [2..7]) (mapA succ a1)+      mapA_2 = assertEqual "1" (fromList [3,2] [2,5,3,6,4,7]) (mapA succ a2)+      zipWithA_1 = assertEqual "1" (fromList [2,3] [2,4..12]) (zipWithA (+) a1 a1)+      zipWithA_2 = assertThrows "2" (zipWithA (+) a1 a2)+      zipWith3A_1 = assertEqual "1" (fromList [2,3] [2,6,12,20,30,42]) (zipWith3A (\ x y z -> x*y+z) a1 a1 a1)+      pad_1 = assertEqual "1" (fromList [5,10] [9,9,9,9,9,9,9,9,9,9,+                                                9,9,9,1,2,3,9,9,9,9,+                                                9,9,9,4,5,6,9,9,9,9,+                                                9,9,9,9,9,9,9,9,9,9,+                                                9,9,9,9,9,9,9,9,9,9])+                              (pad [(1,2),(3,4)] 9 a1)+      pad_2 = assertThrows "2" (pad [(1,1),(1,1),(1,1)] 0 a1)+      a5 :: Array 3 Int+      a5 = fromList [2,3,4] [1..24]+      transpose_1 = assertEqual "1" (fromList [2,3,4] [1,2,3,4,+                                                       5,6,7,8,+                                                       9,10,11,12,++                                                       13,14,15,16,+                                                       17,18,19,20,+                                                       21,22,23,24])+                                    (transpose [0,1,2] a5)+      transpose_2 = assertEqual "2" (fromList [2,4,3] [1,5,9,+                                                       2,6,10,+                                                       3,7,11,+                                                       4,8,12,++                                                       13,17,21,+                                                       14,18,22,+                                                       15,19,23,+                                                       16,20,24])+                                    (transpose [0,2,1] a5)+      transpose_3 = assertEqual "3" (fromList [3,2,4] [1,2,3,4,+                                                       13,14,15,16,++                                                       5,6,7,8,+                                                       17,18,19,20,++                                                       9,10,11,12,+                                                       21,22,23,24])+                                    (transpose [1,0,2] a5)+      transpose_4 = assertEqual "4" (fromList [3,4,2] [1,13,+                                                       2,14,+                                                       3,15,+                                                       4,16,++                                                       5,17,+                                                       6,18,+                                                       7,19,+                                                       8,20,++                                                       9,21,+                                                       10,22,+                                                       11,23,+                                                       12,24])+                                    (transpose [1,2,0] a5)+      transpose_5 = assertEqual "5" (fromList [4,2,3] [1,5,9,+                                                       13,17,21,++                                                       2,6,10,++                                                       14,18,22,++                                                       3,7,11,+                                                       15,19,23,++                                                       4,8,12,+                                                       16,20,24])+                                    (transpose [2,0,1] a5)+      transpose_6 = assertEqual "6" (fromList [4,3,2] [1,13,+                                                       5,17,+                                                       9,21,++                                                       2,14,+                                                       6,18,+                                                       10,22,++                                                       3,15,+                                                       7,19,+                                                       11,23,++                                                       4,16,+                                                       8,20,+                                                       12,24])+                                    (transpose [2,1,0] a5)+      transpose_7 = assertThrows "7" (transpose [0,1,2,3] a5)+      transpose_8 = assertThrows "7" (transpose [0,1,3] a5)+      transpose_9 = assertEqual "9" (fromList [3,2,4] [1,2,3,4,+                                                       13,14,15,16,++                                                       5,6,7,8,+                                                       17,18,19,20,++                                                       9,10,11,12,+                                                       21,22,23,24])+                                    (transpose [1,0] a5)+      append_1 = assertEqual "1" (fromList [3,3] [1..9])+                                 (append a1 (fromList [1,3] [7,8,9]))+      concatOuter_1 = assertEqual "1" (fromList [6,3] [1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6])+                                      (concatOuter [a1, concatOuter [a1,a1]])+      concatOuter_2 = assertThrows "2" (concatOuter [a1, a2])+      a6 :: Array 2 Int+      a6 = fromList [4,5] [1..20]+      window_1 = assertEqual "1" (fromList [2,3,3,3] [1,2,3,+                                                      6,7,8,+                                                      11,12,13,++                                                      2,3,4,+                                                      7,8,9,+                                                      12,13,14,++                                                      3,4,5,+                                                      8,9,10,+                                                      13,14,15,+++                                                      6,7,8,+                                                      11,12,13,+                                                      16,17,18,++                                                      7,8,9,+                                                      12,13,14,+                                                      17,18,19,++                                                      8,9,10,+                                                      13,14,15,+                                                      18,19,20])+                                 (window [3,3] a6 :: Array 4 Int)+      window_2 = assertThrows "2" (window [3,6] a6 :: Array 4 Int)+      window_3 = assertThrows "3" (window [3,3,3] a6 :: Array 5 Int)+      stride_1 = assertEqual "1" (fromList [2,2,2] [1,3,+                                                    9,11,++                                                    13,15,+                                                    21,23])+                                 (stride [1,2,2] a5)+      stride_2 = assertThrows "2" (stride [1,2,2] a1)+      slice_1 = assertEqual "1" (fromList [2,2,1] [8,12,20,24])+                                (slice [(0,2),(1,2),(3,1)] a5)+      slice_2 = assertThrows "2" (slice [(0,0)] a4)+      slice_3 = assertThrows "3" (slice [(-1,1)] a5)+      slice_4 = assertThrows "4" (slice [(10,0)] a5)+      slice_5 = assertThrows "5" (slice [(0,3)] a5)+      a7 = mapA succ a5+      dot x y = reduce (+) 0 $ zipWithA (*) x y+      rerank2_1 = assertEqual "1" (fromList [2,3] [40,200,488,904,1448,2120])+                                  (rerank2 @2 dot a5 a7)+      rev_1 = assertEqual "1" (fromList [2,3] [3,2,1,6,5,4])+                              (rev [1] a1)+      rev_2 = assertEqual "2" (fromList [2,3] [6,5,4,3,2,1])+                              (rev [0,1] a1)+      rev_3 = assertThrows "3" (rev [2] a1)+      reduce_1 = assertEqual "1" (scalar 720) (reduce (*) 1 a1)+      reduce_2 = assertEqual "2" (fromList [2] [6,120]) (rerank @1 (reduce (*) 1) a1)+      reduce_3 = assertEqual "3" (fromList [3] [4,10,18]) (rerank @1 (reduce (*) 1) a2)++      tests =+        [ testCase "show_1" show_1+        , testCase "show_2" show_2+        , testCase "eq_1" eq_1+        , testCase "eq_2" eq_2+        , testCase "ord_1" ord_1+        , testCase "ord_2" ord_2+        , testCase "shapeL_1" shapeL_1+        , testCase "shapeL_2" shapeL_2+        , testCase "rank_1" rank_1+        , testCase "rank_2" rank_2+        , testCase "index_1" index_1+        , testCase "index_2" index_2+        , testCase "index_3" index_3+        , testCase "index_4" index_4+        , testCase "index_5" index_5+        , testCase "toList_1" toList_1+        , testCase "toList_2" toList_2+        , testCase "toVector_1" toVector_1+        , testCase "toVector_2" toVector_2+        , testCase "fromList_1" fromList_1+        , testCase "fromList_2" fromList_2+        , testCase "fromVector_1" fromVector_1+        , testCase "normalize_1" normalize_1+        , testCase "reshape_1" reshape_1+        , testCase "reshape_2" reshape_2+        , testCase "stretch_1" stretch_1+        , testCase "stretch_2" stretch_2+        , testCase "stretch_3" stretch_3+        , testCase "stretch_4" stretch_4+        , testCase "scalar_1" scalar_1+        , testCase "unScalar_1" unScalar_1+        , testCase "constant_1" constant_1+        , testCase "mapA_1" mapA_1+        , testCase "mapA_2" mapA_2+        , testCase "zipWithA_1" zipWithA_1+        , testCase "zipWithA_2" zipWithA_2+        , testCase "zipWith3A_1" zipWith3A_1+        , testCase "pad_1" pad_1+        , testCase "pad_2" pad_2+        , testCase "transpose_1" transpose_1+        , testCase "transpose_2" transpose_2+        , testCase "transpose_3" transpose_3+        , testCase "transpose_4" transpose_4+        , testCase "transpose_5" transpose_5+        , testCase "transpose_6" transpose_6+        , testCase "transpose_7" transpose_7+        , testCase "transpose_8" transpose_8+        , testCase "transpose_9" transpose_9+        , testCase "append_1" append_1+        , testCase "concatOuter_1" concatOuter_1+        , testCase "concatOuter_2" concatOuter_2+        , testCase "window_1" window_1+        , testCase "window_2" window_2+        , testCase "window_3" window_3+        , testCase "stride_1" stride_1+        , testCase "stride_2" stride_2+        , testCase "slice_1" slice_1+        , testCase "slice_2" slice_2+        , testCase "slice_3" slice_3+        , testCase "slice_4" slice_4+        , testCase "slice_5" slice_5+        , testCase "rerank2_1" rerank2_1+        , testCase "rev_1" rev_1+        , testCase "rev_2" rev_2+        , testCase "rev_3" rev_3+        , testCase "reduce_1" reduce_1+        , testCase "reduce_2" reduce_2+        , testCase "reduce_3" reduce_3+        ]+  in  tests
+ tests/ShapedSTest.hs view
@@ -0,0 +1,269 @@+-- Copyright 2020 Google LLC+--+-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+--+--      http://www.apache.org/licenses/LICENSE-2.0+--+-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+module ShapedSTest(test) where++import Control.DeepSeq+import Control.Exception+import Data.Array.ShapedS+import qualified Data.Vector.Storable as V+import Test.Framework (Test, testGroup)+import Test.Framework.Providers.HUnit (testCase)+import Test.HUnit (assertEqual, assertFailure, Assertion)++assertThrows :: (NFData a) => String -> a -> Assertion+assertThrows s a = catch (deepseq a $ assertFailure s) (\ (_ :: ErrorCall) -> return ())++test :: Test+test = testGroup "ShapedS" $+  let a1, a1' :: Array [2,3] Int+      a1 = fromList [1..6]+      a1' = fromList [2..7]+      a2 :: Array [3,2] Int+      a2 = fromList [1,4,2,5,3,6]+      show_1 = assertEqual "1" "fromList @[2,3] [1,2,3,4,5,6]" (show a1)+      show_2 = assertEqual "2" "fromList @[3,2] [1,4,2,5,3,6]" (show a2)+      eq_1 = assertEqual "1" True (a1 == a1)+      eq_2 = assertEqual "2" False (a1 == a1')+      ord_1 = assertEqual "1" EQ (a1 `compare` a1)+      ord_2 = assertEqual "2" LT (a1 `compare` a1')+      shapeL_1 = assertEqual "1" [2,3] (shapeL a1)+      shapeL_2 = assertEqual "2" [3,2] (shapeL a2)+      rank_1 = assertEqual "1" 2 (rank a1)+      rank_2 = assertEqual "2" 2 (rank a2)+      index_1 = assertEqual "1" (fromList [1,2,3]) (index a1 0)+      index_2 = assertEqual "2" (fromList [1,4]) (index a2 0)+      index_3 = assertEqual "3" (fromList [4]) (a2 `index` 0 `index` 1)+      index_4 = assertThrows "<0" (index a1 (-1))+      index_5 = assertThrows ">" (index a1 2)+      toList_1 = assertEqual "1" [1,2,3,4,5,6] (toList a1)+      toList_2 = assertEqual "2" [1,4,2,5,3,6] (toList a2)+      toVector_1 = assertEqual "1" (V.fromList [1,2,3,4,5,6]) (toVector a1)+      toVector_2 = assertEqual "2" (V.fromList [1,4,2,5,3,6]) (toVector a2)+      fromList_1 = assertThrows "sh" (fromList [1,2] :: Array '[] Int)+      fromList_2 = assertThrows "sh" (fromList [1,2] :: Array [4,5] Int)+      fromVector_1 = assertEqual "1" a1 (fromVector $ V.fromList [1..6])+      normalize_1 = assertEqual "1" a1 (normalize a1)+      reshape_1 = assertEqual "1" (fromList [1..6] :: Array '[6] Int) (reshape a1)+      reshape_2 = assertEqual "1" (fromList [1,4,2,5,3,6]) (reshape a2 :: Array [1,2,3,1] Int)+      a3 :: Array '[1] Int+      a3 = fromList [5]+      a4 :: Array '[] Int+      a4 = fromList [5]+      stretch_1 = assertEqual "1" (fromList @'[3] [5,5,5]) (stretch @'[3] a3)+      stretch_2 = assertEqual "2" (fromList @[2,2,3,2] [1,1,2,2,3,3,4,4,5,5,6,6,1,1,2,2,3,3,4,4,5,5,6,6])+                                  (stretch @[2,2,3,2] (reshape @[1,2,3,1] a1))++      scalar_1 = assertEqual "1" a4 (scalar 5)+      unScalar_1 = assertEqual "1" 5 (unScalar a4)+      constant_1 = assertEqual "1" (fromList [1,1,1,1,1,1]) (constant 1 :: Array [2,3] Int)+      mapA_1 = assertEqual "1" (fromList [2..7]) (mapA succ a1)+      mapA_2 = assertEqual "1" (fromList [2,5,3,6,4,7]) (mapA succ a2)+      zipWithA_1 = assertEqual "1" (fromList [2,4..12]) (zipWithA (+) a1 a1)+      zipWith3A_1 = assertEqual "1" (fromList [2,6,12,20,30,42]) (zipWith3A (\ x y z -> x*y+z) a1 a1 a1)+      pad_1 = assertEqual "1" (fromList [9,9,9,9,9,9,9,9,9,9,+                                         9,9,9,1,2,3,9,9,9,9,+                                         9,9,9,4,5,6,9,9,9,9,+                                         9,9,9,9,9,9,9,9,9,9,+                                         9,9,9,9,9,9,9,9,9,9])+                              (pad @['(1,2), '(3,4)] 9 a1)+      a5 :: Array '[2,3,4] Int+      a5 = fromList [1..24]+      transpose_1 = assertEqual "1" (fromList [1,2,3,4,+                                               5,6,7,8,+                                               9,10,11,12,++                                               13,14,15,16,+                                               17,18,19,20,+                                               21,22,23,24])+                                    (transpose @'[0,1,2] a5)+      transpose_2 = assertEqual "2" (fromList [1,5,9,+                                               2,6,10,+                                               3,7,11,+                                               4,8,12,++                                               13,17,21,+                                               14,18,22,+                                               15,19,23,+                                               16,20,24])+                                    (transpose @'[0,2,1] a5)+      transpose_3 = assertEqual "3" (fromList [1,2,3,4,+                                               13,14,15,16,++                                               5,6,7,8,+                                               17,18,19,20,++                                               9,10,11,12,+                                               21,22,23,24])+                                    (transpose @'[1,0,2] a5)+      transpose_4 = assertEqual "4" (fromList [1,13,+                                               2,14,+                                               3,15,+                                               4,16,++                                               5,17,+                                               6,18,+                                               7,19,+                                               8,20,++                                               9,21,+                                               10,22,+                                               11,23,+                                               12,24])+                                    (transpose @'[1,2,0] a5)+      transpose_5 = assertEqual "5" (fromList [1,5,9,+                                               13,17,21,++                                               2,6,10,++                                               14,18,22,++                                               3,7,11,+                                               15,19,23,++                                               4,8,12,+                                               16,20,24])+                                    (transpose @'[2,0,1] a5)+      transpose_6 = assertEqual "6" (fromList [1,13,+                                               5,17,+                                               9,21,++                                               2,14,+                                               6,18,+                                               10,22,++                                               3,15,+                                               7,19,+                                               11,23,++                                               4,16,+                                               8,20,+                                               12,24])+                                    (transpose @'[2,1,0] a5)+      transpose_9 = assertEqual "9" (fromList [1,2,3,4,+                                               13,14,15,16,++                                               5,6,7,8,+                                               17,18,19,20,++                                               9,10,11,12,+                                               21,22,23,24])+                                    (transpose @'[1,0] a5)+      append_1 = assertEqual "1" (fromList [1..9])+                                 (append a1 (fromList @[1,3] [7,8,9]))+      a6 :: Array [4,5] Int+      a6 = fromList [1..20]+      window_1 = assertEqual "1" (fromList @[2,3,3,3] [1,2,3,+                                                      6,7,8,+                                                      11,12,13,++                                                      2,3,4,+                                                      7,8,9,+                                                      12,13,14,++                                                      3,4,5,+                                                      8,9,10,+                                                      13,14,15,+++                                                      6,7,8,+                                                      11,12,13,+                                                      16,17,18,++                                                      7,8,9,+                                                      12,13,14,+                                                      17,18,19,++                                                      8,9,10,+                                                      13,14,15,+                                                      18,19,20])+                                 (window @[3,3] a6)+      stride_1 = assertEqual "1" (fromList @[2,2,2] [1,3,+                                                    9,11,++                                                    13,15,+                                                    21,23])+                                 (stride @[1,2,2] a5)+      slice_1 = assertEqual "1" (fromList @[2,2,1] [8,12,20,24])+                                (slice @['(0,2), '(1,2), '(3,1)] a5)+      a7 = mapA succ a5+      dot x y = reduce (+) 0 $ zipWithA (*) x y+      rerank2_1 = assertEqual "1" (fromList [40,200,488,904,1448,2120])+                                  (rerank2 @2 dot a5 a7)+      rev_1 = assertEqual "1" (fromList [3,2,1,6,5,4])+                              (rev @'[1] a1)+      rev_2 = assertEqual "2" (fromList [6,5,4,3,2,1])+                              (rev @[0,1] a1)+      reduce_1 = assertEqual "1" (scalar 720) (reduce (*) 1 a1)+      reduce_2 = assertEqual "2" (fromList @'[2] [6,120]) (rerank @1 (reduce (*) 1) a1)+      reduce_3 = assertEqual "3" (fromList @'[3] [4,10,18]) (rerank @1 (reduce (*) 1) a2)++      tests =+        [ testCase "show_1" show_1+        , testCase "show_2" show_2+        , testCase "eq_1" eq_1+        , testCase "eq_2" eq_2+        , testCase "ord_1" ord_1+        , testCase "ord_2" ord_2+        , testCase "shapeL_1" shapeL_1+        , testCase "shapeL_2" shapeL_2+        , testCase "rank_1" rank_1+        , testCase "rank_2" rank_2+        , testCase "index_1" index_1+        , testCase "index_2" index_2+        , testCase "index_3" index_3+        , testCase "index_4" index_4+        , testCase "index_5" index_5+        , testCase "toList_1" toList_1+        , testCase "toList_2" toList_2+        , testCase "toVector_1" toVector_1+        , testCase "toVector_2" toVector_2+        , testCase "fromList_1" fromList_1+        , testCase "fromList_2" fromList_2+        , testCase "fromVector_1" fromVector_1+        , testCase "normalize_1" normalize_1+        , testCase "reshape_1" reshape_1+        , testCase "reshape_2" reshape_2+        , testCase "stretch_1" stretch_1+        , testCase "stretch_2" stretch_2+        , testCase "scalar_1" scalar_1+        , testCase "unScalar_1" unScalar_1+        , testCase "constant_1" constant_1+        , testCase "mapA_1" mapA_1+        , testCase "mapA_2" mapA_2+        , testCase "zipWithA_1" zipWithA_1+        , testCase "zipWith3A_1" zipWith3A_1+        , testCase "pad_1" pad_1+        , testCase "transpose_1" transpose_1+        , testCase "transpose_2" transpose_2+        , testCase "transpose_3" transpose_3+        , testCase "transpose_4" transpose_4+        , testCase "transpose_5" transpose_5+        , testCase "transpose_6" transpose_6+        , testCase "transpose_9" transpose_9+        , testCase "append_1" append_1+        , testCase "window_1" window_1+        , testCase "stride_1" stride_1+        , testCase "slice_1" slice_1+        , testCase "rerank2_1" rerank2_1+        , testCase "rev_1" rev_1+        , testCase "rev_2" rev_2+        , testCase "reduce_1" reduce_1+        , testCase "reduce_2" reduce_2+        , testCase "reduce_3" reduce_3+        ]+  in  tests