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 +79/−34
- README.md +127/−42
- orthotope.cabal +5/−2
- tests/DynamicSTest.hs +298/−0
- tests/RankedSTest.hs +299/−0
- tests/ShapedSTest.hs +269/−0
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