packages feed

comfort-array 0.5.4.2 → 0.5.5

raw patch · 15 files changed

+1579/−541 lines, 15 filesdep +bifunctorsdep ~containersdep ~transformers-compatPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: bifunctors

Dependency ranges changed: containers, transformers-compat

API changes (from Hackage documentation)

+ Data.Array.Comfort.Bool: data Array sh
+ Data.Array.Comfort.Bool: difference :: (Indexed sh, Eq sh) => Array sh -> Array sh -> Array sh
+ Data.Array.Comfort.Bool: fromList :: Indexed sh => sh -> [Index sh] -> Array sh
+ Data.Array.Comfort.Bool: fromSet :: (Indexed sh, Index sh ~ ix, Ord ix) => sh -> Set ix -> Array sh
+ Data.Array.Comfort.Bool: intersection :: (Indexed sh, Eq sh) => Array sh -> Array sh -> Array sh
+ Data.Array.Comfort.Bool: mapShape :: (C sh0, C sh1) => (sh0 -> sh1) -> Array sh0 -> Array sh1
+ Data.Array.Comfort.Bool: member :: Indexed sh => Index sh -> Array sh -> Bool
+ Data.Array.Comfort.Bool: reshape :: (C sh0, C sh1) => sh1 -> Array sh0 -> Array sh1
+ Data.Array.Comfort.Bool: shape :: Array sh -> sh
+ Data.Array.Comfort.Bool: toList :: InvIndexed sh => Array sh -> [Index sh]
+ Data.Array.Comfort.Bool: toSet :: (InvIndexed sh, Index sh ~ ix, Ord ix) => Array sh -> Set ix
+ Data.Array.Comfort.Bool: union :: (Indexed sh, Eq sh) => Array sh -> Array sh -> Array sh
+ Data.Array.Comfort.Shape.SubSize: Atom :: Int -> Atom sh
+ Data.Array.Comfort.Shape.SubSize: Cons :: (sh -> (Int, nsize)) -> T sh nsize
+ Data.Array.Comfort.Shape.SubSize: Sub :: Int -> nsize -> Sub nsize
+ Data.Array.Comfort.Shape.SubSize: [measure] :: T sh nsize -> sh -> (Int, nsize)
+ Data.Array.Comfort.Shape.SubSize: append :: T sh0 nsize0 -> T sh1 nsize1 -> T (sh0 ::+ sh1) (nsize0 ::+ nsize1)
+ Data.Array.Comfort.Shape.SubSize: atom :: C sh => T sh Int
+ Data.Array.Comfort.Shape.SubSize: auto :: C nsize => T (ToShape nsize) nsize
+ Data.Array.Comfort.Shape.SubSize: class C nsize where {
+ Data.Array.Comfort.Shape.SubSize: data Sub nsize
+ Data.Array.Comfort.Shape.SubSize: evaluate :: C nsize => ToShape nsize -> (Int, nsize)
+ Data.Array.Comfort.Shape.SubSize: instance (Data.Array.Comfort.Shape.SubSize.C nsize0, Data.Array.Comfort.Shape.SubSize.C nsize1) => Data.Array.Comfort.Shape.SubSize.C (nsize0 Data.Array.Comfort.Shape.::+ nsize1)
+ Data.Array.Comfort.Shape.SubSize: instance (Data.Array.Comfort.Shape.SubSize.C nsize0, Data.Array.Comfort.Shape.SubSize.C nsize1) => Data.Array.Comfort.Shape.SubSize.C (nsize0, nsize1)
+ Data.Array.Comfort.Shape.SubSize: instance (Data.Array.Comfort.Shape.SubSize.C nsize0, Data.Array.Comfort.Shape.SubSize.C nsize1, Data.Array.Comfort.Shape.SubSize.C nsize2) => Data.Array.Comfort.Shape.SubSize.C (nsize0, nsize1, nsize2)
+ Data.Array.Comfort.Shape.SubSize: instance Data.Array.Comfort.Shape.C sh => Data.Array.Comfort.Shape.SubSize.C (Data.Array.Comfort.Shape.SubSize.Atom sh)
+ Data.Array.Comfort.Shape.SubSize: instance Data.Array.Comfort.Shape.SubSize.C sub => Data.Array.Comfort.Shape.SubSize.C (Data.Array.Comfort.Shape.SubSize.Sub sub)
+ Data.Array.Comfort.Shape.SubSize: newtype Atom sh
+ Data.Array.Comfort.Shape.SubSize: newtype T sh nsize
+ Data.Array.Comfort.Shape.SubSize: pair :: T sh0 nsize0 -> T sh1 nsize1 -> T (sh0, sh1) (nsize0, nsize1)
+ Data.Array.Comfort.Shape.SubSize: sub :: T sh nsize -> T sh (Sub nsize)
+ Data.Array.Comfort.Shape.SubSize: triple :: T sh0 nsize0 -> T sh1 nsize1 -> T sh2 nsize2 -> T (sh0, sh1, sh2) (nsize0, nsize1, nsize2)
+ Data.Array.Comfort.Shape.SubSize: type ToShape nsize;
+ Data.Array.Comfort.Shape.SubSize: }
+ Data.Array.Comfort.Storable: takeIntSet :: (Indexed sh, Index sh ~ Int, Storable a) => IntSet -> Array sh a -> Array IntSet a
+ Data.Array.Comfort.Storable: takeSet :: (Indexed sh, Index sh ~ ix, Ord ix, Storable a) => Set ix -> Array sh a -> Array (Set ix) a
+ Data.Array.Comfort.Storable.Dim2: (&===) :: (Block blockA, Block blockB) => (C heightA, C heightB) => (C width, Eq width) => Storable a => blockA (heightA, width) a -> blockB (heightB, width) a -> BlockMatrix (heightA ::+ heightB) width a
+ Data.Array.Comfort.Storable.Dim2: (&|||) :: (Block blockA, Block blockB) => (C height, Eq height) => (C widthA, C widthB) => Storable a => blockA (height, widthA) a -> blockB (height, widthB) a -> BlockMatrix height (widthA ::+ widthB) a
+ Data.Array.Comfort.Storable.Dim2: above :: (C heightA, C heightB) => (C width, Eq width) => Storable a => Array2 heightA width a -> Array2 heightB width a -> Array2 (heightA ::+ heightB) width a
+ Data.Array.Comfort.Storable.Dim2: beside :: (C height, Eq height) => (C widthA, C widthB) => Storable a => Array2 height widthA a -> Array2 height widthB a -> Array2 height (widthA ::+ widthB) a
+ Data.Array.Comfort.Storable.Dim2: block :: (Block block, C height, C width, Storable a) => block (height, width) a -> BlockMatrix height width a
+ Data.Array.Comfort.Storable.Dim2: blockAbove :: Eq width => BlockMatrix heightA width a -> BlockMatrix heightB width a -> BlockMatrix (heightA ::+ heightB) width a
+ Data.Array.Comfort.Storable.Dim2: blockBeside :: Eq height => BlockMatrix height widthA a -> BlockMatrix height widthB a -> BlockMatrix height (widthA ::+ widthB) a
+ Data.Array.Comfort.Storable.Dim2: class Block block
+ Data.Array.Comfort.Storable.Dim2: class (C sh) => ShapeSequence sh
+ Data.Array.Comfort.Storable.Dim2: data BlockArray shape a
+ Data.Array.Comfort.Storable.Dim2: flattenColumn :: Array2 height () a -> Array height a
+ Data.Array.Comfort.Storable.Dim2: flattenRow :: Array2 () width a -> Array width a
+ Data.Array.Comfort.Storable.Dim2: fromBlockArray :: (Ord row, C height, Eq height) => (Ord column, C width, Eq width) => Storable a => Map row height -> Map column width -> Array (Set row, Set column) (Array2 height width a) -> Array2 (Map row height) (Map column width) a
+ Data.Array.Comfort.Storable.Dim2: fromBlockMatrix :: (C height, C width, Storable a) => BlockMatrix height width a -> Array2 height width a
+ Data.Array.Comfort.Storable.Dim2: fromBlocks :: (ShapeSequence height, ShapeSequence width, Storable a) => height -> width -> Proxy a -> BlockFunction height width a (Array2 height width a)
+ Data.Array.Comfort.Storable.Dim2: fromNonEmptyBlockArray :: (Ord row, C height, Eq height) => (Ord column, C width, Eq width) => Storable a => Array (Set row, Set column) (Array2 height width a) -> Array2 (Map row height) (Map column width) a
+ Data.Array.Comfort.Storable.Dim2: fromRowArray :: (C sh0, C sh1, Eq sh1, Storable a) => sh1 -> Array sh0 (Array sh1 a) -> Array2 sh0 sh1 a
+ Data.Array.Comfort.Storable.Dim2: infixr 2 &===
+ Data.Array.Comfort.Storable.Dim2: infixr 3 &|||
+ Data.Array.Comfort.Storable.Dim2: instance (Data.Array.Comfort.Shape.C sh, GHC.Classes.Eq sh, Data.Array.Comfort.Storable.Dim2.ShapeSequence shs) => Data.Array.Comfort.Storable.Dim2.ShapeSequence (sh Data.Array.Comfort.Shape.::+ shs)
+ Data.Array.Comfort.Storable.Dim2: instance Data.Array.Comfort.Storable.Dim2.Block Data.Array.Comfort.Storable.Dim2.BlockArray
+ Data.Array.Comfort.Storable.Dim2: instance Data.Array.Comfort.Storable.Dim2.Block Data.Array.Comfort.Storable.Private.Array
+ Data.Array.Comfort.Storable.Dim2: instance Data.Array.Comfort.Storable.Dim2.ShapeSequence Data.Array.Comfort.Shape.Zero
+ Data.Array.Comfort.Storable.Dim2: singleColumn :: Array height a -> Array2 height () a
+ Data.Array.Comfort.Storable.Dim2: singleRow :: Array width a -> Array2 () width a
+ Data.Array.Comfort.Storable.Dim2: switchSequence :: ShapeSequence sh => f Zero -> (forall sh0 shs. (C sh0, Eq sh0, ShapeSequence shs) => f (sh0 ::+ shs)) -> f sh
+ Data.Array.Comfort.Storable.Dim2: takeBottom :: (C heightA, C heightB, C width, Storable a) => Array2 (heightA ::+ heightB) width a -> Array2 heightB width a
+ Data.Array.Comfort.Storable.Dim2: takeLeft :: (C height, C widthA, C widthB, Storable a) => Array2 height (widthA ::+ widthB) a -> Array2 height widthA a
+ Data.Array.Comfort.Storable.Dim2: takeRight :: (C height, C widthA, C widthB, Storable a) => Array2 height (widthA ::+ widthB) a -> Array2 height widthB a
+ Data.Array.Comfort.Storable.Dim2: takeRow :: (Indexed sh0, C sh1, Storable a) => Array2 sh0 sh1 a -> Index sh0 -> Array sh1 a
+ Data.Array.Comfort.Storable.Dim2: takeTop :: (C heightA, C heightB, C width, Storable a) => Array2 (heightA ::+ heightB) width a -> Array2 heightA width a
+ Data.Array.Comfort.Storable.Dim2: toRowArray :: (C sh0, C sh1, Storable a) => Array2 sh0 sh1 a -> Array sh0 (Array sh1 a)
+ Data.Array.Comfort.Storable.Dim2: type Array2 sh0 sh1 = Array (sh0, sh1)
+ Data.Array.Comfort.Storable.Dim2: type BlockMatrix height width = BlockArray (height, width)
+ Data.Array.Comfort.Storable.Dim2: type family RowFunction height widths a r
+ Data.Array.Comfort.Storable.Unchecked: fromStorableVector :: Storable a => Vector a -> Array (ZeroBased Int) a
+ Data.Array.Comfort.Storable.Unchecked: toStorableVector :: (C sh, Storable a) => Array sh a -> Vector a
+ Data.Array.Comfort.Storable.Unchecked: unsafeCreateWithAutoSizes :: (C sh, sh ~ ToShape nsize, C nsize, Storable a) => sh -> (nsize -> Ptr a -> IO ()) -> Array sh a
+ Data.Array.Comfort.Storable.Unchecked: unsafeCreateWithSizes :: (C sh, Storable a) => T sh nsize -> sh -> (nsize -> Ptr a -> IO ()) -> Array sh a
+ Data.Array.Comfort.Storable.Unchecked.Creator: Creator :: (forall a. (ptr -> IO a) -> IO (arr, a)) -> Creator arr ptr
+ Data.Array.Comfort.Storable.Unchecked.Creator: create :: (C sh, Storable a) => sh -> Creator (Array sh a) (Ptr a)
+ Data.Array.Comfort.Storable.Unchecked.Creator: createWithSize :: (C sh, Storable a) => sh -> Creator (Array sh a) (Int, Ptr a)
+ Data.Array.Comfort.Storable.Unchecked.Creator: createWithSizes :: (C sh, Storable a) => T sh nsize -> sh -> Creator (Array sh a) (nsize, Ptr a)
+ Data.Array.Comfort.Storable.Unchecked.Creator: instance Data.Biapplicative.Biapplicative Data.Array.Comfort.Storable.Unchecked.Creator.Creator
+ Data.Array.Comfort.Storable.Unchecked.Creator: instance Data.Bifunctor.Bifunctor Data.Array.Comfort.Storable.Unchecked.Creator.Creator
+ Data.Array.Comfort.Storable.Unchecked.Creator: instance GHC.Base.Functor (Data.Array.Comfort.Storable.Unchecked.Creator.Creator arr)
+ Data.Array.Comfort.Storable.Unchecked.Creator: liftContT :: (forall a. ContT a IO ptr) -> Creator () ptr
+ Data.Array.Comfort.Storable.Unchecked.Creator: liftIO :: IO ptr -> Creator () ptr
+ Data.Array.Comfort.Storable.Unchecked.Creator: newtype Creator arr ptr
+ Data.Array.Comfort.Storable.Unchecked.Creator: pair :: Creator arr0 ptr0 -> Creator arr1 ptr1 -> Creator (arr0, arr1) (ptr0, ptr1)
+ Data.Array.Comfort.Storable.Unchecked.Creator: unsafeRun :: PrimMonad m => Creator arr ptr -> (ptr -> IO ()) -> m arr
+ Data.Array.Comfort.Storable.Unchecked.Creator: unsafeRunWithResult :: PrimMonad m => Creator arr ptr -> (ptr -> IO b) -> m (arr, b)
+ Data.Array.Comfort.Storable.Unchecked.Monadic: _unsafeCreateWithSizesAndResult :: (PrimMonad m, Storable a, C nsize, ToShape nsize ~ sh, C sh) => sh -> (Int -> nsize -> Ptr a -> IO b) -> m (Array sh a, b)
+ Data.Array.Comfort.Storable.Unchecked.Monadic: unsafeCreateWithSizes :: (PrimMonad m, C sh, Storable a) => T sh nsize -> sh -> (nsize -> Ptr a -> IO ()) -> m (Array sh a)
+ Data.Array.Comfort.Storable.Unchecked.Monadic: unsafeCreateWithSizesAndResult :: (PrimMonad m, C sh, Storable a) => T sh nsize -> sh -> (nsize -> Ptr a -> IO b) -> m (Array sh a, b)
- Data.Array.Comfort.Storable: replicate :: (Indexed sh, Storable a) => sh -> a -> Array sh a
+ Data.Array.Comfort.Storable: replicate :: (C sh, Storable a) => sh -> a -> Array sh a

Files

comfort-array.cabal view
@@ -1,5 +1,5 @@ Name:             comfort-array-Version:          0.5.4.2+Version:          0.5.5 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -97,10 +97,9 @@ Build-Type:       Simple Extra-Source-Files:   Changes.md-  test-module.list  Source-Repository this-  Tag:         0.5.4.2+  Tag:         0.5.5   Type:        darcs   Location:    https://hub.darcs.net/thielema/comfort-array/ @@ -127,6 +126,7 @@     -- transformers-compat required for Functor.Classes in GHC-7.8.4     transformers-compat >=0.6.6 && <0.8,     transformers >=0.3 && <0.7,+    bifunctors >=5.5 && <5.7,     non-empty >=0.3.2 && <0.4,     utility-ht >=0.0.10 && <0.1,     prelude-compat >=0.0 && <0.1,@@ -144,15 +144,19 @@   Exposed-Modules:     Data.Array.Comfort.Shape     Data.Array.Comfort.Shape.Test+    Data.Array.Comfort.Shape.SubSize     Data.Array.Comfort.Storable+    Data.Array.Comfort.Storable.Dim2     Data.Array.Comfort.Storable.Unchecked     Data.Array.Comfort.Storable.Unchecked.Monadic+    Data.Array.Comfort.Storable.Unchecked.Creator     Data.Array.Comfort.Storable.Private     Data.Array.Comfort.Storable.Mutable     Data.Array.Comfort.Storable.Mutable.Unchecked     Data.Array.Comfort.Storable.Mutable.Private     Data.Array.Comfort.Boxed     Data.Array.Comfort.Boxed.Unchecked+    Data.Array.Comfort.Bool     Data.Array.Comfort.Container   Other-Modules:     Data.Array.Comfort.Shape.Tuple@@ -184,6 +188,7 @@     DocTest.Data.Array.Comfort.Shape     DocTest.Data.Array.Comfort.Storable.Unchecked     DocTest.Data.Array.Comfort.Storable+    DocTest.Data.Array.Comfort.Storable.Dim2     DocTest.Data.Array.Comfort.Boxed.Unchecked     DocTest.Data.Array.Comfort.Boxed     DocTest.Main
+ src/Data/Array/Comfort/Bool.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{- |+Can be an alternative to the @enumset@ package.+-}+module Data.Array.Comfort.Bool (+   Array,+   shape,+   reshape,+   mapShape,++   fromList,+   toList,+   fromSet,+   toSet,++   member,+   union,+   difference,+   intersection,+   ) where++import qualified Data.Array.Comfort.Shape as Shape+import qualified Data.Array.Comfort.Check as Check++import qualified Data.IntSet as IntSet+import qualified Data.Set as Set+import qualified Data.List as List+import Data.IntSet (IntSet)+import Data.Set (Set)+++data Array sh =+   Array {+      shape_ :: sh,+      _intSet :: IntSet+   }+++shape :: Array sh -> sh+shape = shape_++reshape :: (Shape.C sh0, Shape.C sh1) => sh1 -> Array sh0 -> Array sh1+reshape = Check.reshape "Storable" shape (\sh arr -> arr{shape_ = sh})++mapShape ::+   (Shape.C sh0, Shape.C sh1) => (sh0 -> sh1) -> Array sh0 -> Array sh1+mapShape f arr = reshape (f $ shape arr) arr++++fromList :: (Shape.Indexed sh) => sh -> [Shape.Index sh] -> Array sh+fromList sh = Array sh . IntSet.fromList . List.map (Shape.offset sh)++toList :: (Shape.InvIndexed sh) => Array sh -> [Shape.Index sh]+toList (Array sh set) = map (Shape.indexFromOffset sh) $ IntSet.toList set++fromSet ::+   (Shape.Indexed sh, Shape.Index sh ~ ix, Ord ix) => sh -> Set ix -> Array sh+fromSet sh = fromList sh . Set.toList++toSet ::+   (Shape.InvIndexed sh, Shape.Index sh ~ ix, Ord ix) => Array sh -> Set ix+toSet = Set.fromList . toList+++errorArray :: String -> String -> a+errorArray name msg =+   error ("Array.Comfort.Bool." ++ name ++ ": " ++ msg)+++member :: (Shape.Indexed sh) => Shape.Index sh -> Array sh -> Bool+member ix (Array sh set) = IntSet.member (Shape.offset sh ix) set+++lift2 :: (Shape.Indexed sh, Eq sh) =>+   String -> (IntSet -> IntSet -> IntSet) ->+   Array sh -> Array sh -> Array sh+lift2 name op (Array shA setA) (Array shB setB) =+   if shA == shB+      then Array shA $ op setA setB+      else errorArray name "shapes mismatch"++union :: (Shape.Indexed sh, Eq sh) => Array sh -> Array sh -> Array sh+union = lift2 "union" IntSet.union++intersection :: (Shape.Indexed sh, Eq sh) => Array sh -> Array sh -> Array sh+intersection = lift2 "intersection" IntSet.intersection++difference :: (Shape.Indexed sh, Eq sh) => Array sh -> Array sh -> Array sh+difference = lift2 "difference" IntSet.difference
src/Data/Array/Comfort/Shape.hs view
@@ -301,6 +301,7 @@   + {- | We cannot use 'Semigroup' because 'Semigroup' instances for '()' and '(a,b)' are already defined in a way,@@ -1929,6 +1930,9 @@   +{- |+Dynamically build a shape and its indices in the 'Construction' monad.+-} newtype Constructed tag = Constructed {constructedSize :: Int}    deriving (Eq, Show) 
+ src/Data/Array/Comfort/Shape/SubSize.hs view
@@ -0,0 +1,105 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{- |+Framework for extracting subsize in 'Array.unsafeCreateWithSizes'.+-}+module Data.Array.Comfort.Shape.SubSize (+   T(Cons, measure),+   auto,+   atom,+   Sub(Sub),+   sub,+   pair,+   triple,+   append,++   C(ToShape),+   Atom(Atom),+   evaluate,+   ) where++import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Shape ((::+)((::+)))+++newtype T sh nsize = Cons {measure :: sh -> (Int,nsize)}++auto :: (C nsize) => T (ToShape nsize) nsize+auto = Cons evaluate++atom :: (Shape.C sh) => T sh Int+atom = Cons $ \sh -> let n = Shape.size sh in (n,n)++data Sub nsize = Sub Int nsize++sub :: T sh nsize -> T sh (Sub nsize)+sub (Cons s) =+   Cons $ \sh ->+      let (n,subSizes) = s sh+      in (n, Sub n subSizes)++pair ::+   T sh0 nsize0 ->+   T sh1 nsize1 ->+   T (sh0,sh1) (nsize0,nsize1)+pair (Cons s0) (Cons s1) =+   Cons $ \(sh0,sh1) ->+      let (n0,sub0) = s0 sh0+          (n1,sub1) = s1 sh1+      in (n0*n1, (sub0,sub1))++triple ::+   T sh0 nsize0 ->+   T sh1 nsize1 ->+   T sh2 nsize2 ->+   T (sh0,sh1,sh2) (nsize0,nsize1,nsize2)+triple (Cons s0) (Cons s1) (Cons s2) =+   Cons $ \(sh0,sh1,sh2) ->+      let (n0,sub0) = s0 sh0+          (n1,sub1) = s1 sh1+          (n2,sub2) = s2 sh2+      in (n0*n1*n2, (sub0,sub1,sub2))++append ::+   T sh0 nsize0 ->+   T sh1 nsize1 ->+   T (sh0::+sh1) (nsize0::+nsize1)+append (Cons s0) (Cons s1) =+   Cons $ \(sh0::+sh1) ->+      let (n0,sub0) = s0 sh0+          (n1,sub1) = s1 sh1+      in (n0+n1, sub0::+sub1)+++++class C nsize where+   type ToShape nsize+   {- |+   Compute the sizes of a shape and some sub-shapes.+   -}+   evaluate :: ToShape nsize -> (Int, nsize)++newtype Atom sh = Atom Int++instance (Shape.C sh) => C (Atom sh) where+   type ToShape (Atom sh) = sh+   evaluate sh = let n = Shape.size sh in (n, Atom n)++instance (C sub) => C (Sub sub) where+   type ToShape (Sub sub) = ToShape sub+   evaluate = measure $ sub auto++instance (C nsize0, C nsize1) => C (nsize0,nsize1) where+   type ToShape (nsize0,nsize1) =+            (ToShape nsize0, ToShape nsize1)+   evaluate = measure $ pair auto auto++instance (C nsize0, C nsize1, C nsize2) => C (nsize0,nsize1,nsize2) where+   type ToShape (nsize0,nsize1,nsize2) =+            (ToShape nsize0, ToShape nsize1, ToShape nsize2)+   evaluate = measure $ triple auto auto auto++instance (C nsize0, C nsize1) => C (nsize0::+nsize1) where+   type ToShape (nsize0::+nsize1) = (ToShape nsize0 ::+ ToShape nsize1)+   evaluate = measure $ append auto auto
src/Data/Array/Comfort/Storable.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Data.Array.Comfort.Storable (    Array,    shape,@@ -19,8 +21,8 @@    replicate,    fromBoxed,    toBoxed,-   fromStorableVector,-   toStorableVector,+   Array.fromStorableVector,+   Array.toStorableVector,    fromBlockArray1,    fromBlockArray2,    fromNonEmptyBlockArray2,@@ -40,6 +42,8 @@    Array.take, Array.drop,    Array.takeLeft, Array.takeRight, Array.split,    Array.takeCenter,+   takeSet,+   takeIntSet,     Array.sum, Array.product,    minimum, argMinimum,@@ -54,6 +58,7 @@ import qualified Data.Array.Comfort.Storable.Mutable.Private as MutArrayPriv import qualified Data.Array.Comfort.Storable.Mutable as MutArray import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Storable.Dim2 as Array2 import qualified Data.Array.Comfort.Storable.Memory as Memory import qualified Data.Array.Comfort.Container as Container import qualified Data.Array.Comfort.Boxed as BoxedArray@@ -61,24 +66,22 @@ import qualified Data.Array.Comfort.Shape.Tuple as TupleShape import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable.Unchecked (Array(Array))-import Data.Array.Comfort.Shape ((::+)((::+)))  import System.IO.Unsafe (unsafePerformIO)-import Foreign.Marshal.Array (copyArray, advancePtr)-import Foreign.Storable (Storable)+import Foreign.Marshal.Array (advancePtr)+import Foreign.Storable (Storable, poke, peekElemOff) import Foreign.ForeignPtr (withForeignPtr)  import qualified Control.Monad.Trans.State as MS import Control.Monad.ST (runST)  import qualified Data.StorableVector as SV-import qualified Data.StorableVector.Base as SVB import qualified Data.IntMap as IntMap+import qualified Data.IntSet as IntSet import qualified Data.Map as Map import qualified Data.Set as Set import qualified Data.Traversable as Trav import qualified Data.Foldable as Fold-import qualified Data.List.HT as ListHT import qualified Data.List as List import qualified Data.Tuple.Strict as StrictTuple import Data.IntMap (IntMap)@@ -87,7 +90,6 @@ import Data.Set (Set) import Data.Foldable (forM_) import Data.Either.HT (maybeRight)-import Data.Tuple.HT (mapPair) import Data.Semigroup          (Semigroup, (<>), Min(Min,getMin), Max(Max,getMax), Arg(Arg)) @@ -96,9 +98,6 @@   {- $setup->>> import qualified DocTest.Data.Array.Comfort.Boxed.Unchecked->>>                                              as TestBoxedArray->>> import qualified Data.Array.Comfort.Boxed as BoxedArray >>> import qualified Data.Array.Comfort.Storable as Array >>> import qualified Data.Array.Comfort.Shape as Shape >>> import Data.Array.Comfort.Storable (Array, (!))@@ -106,18 +105,12 @@ >>> import qualified Test.QuickCheck as QC >>> import Test.ChasingBottoms.IsBottom (isBottom) >>>->>> import Control.Monad (replicateM)->>> import Control.Applicative ((<$>), (<*>))+>>> import Control.Applicative ((<$>)) >>>->>> import qualified Data.Map as Map+>>> import qualified Data.IntSet as IntSet >>> import qualified Data.Set as Set->>> import Data.Map (Map)->>> import Data.Function.HT (Id) >>> import Data.Complex (Complex((:+)))->>> import Data.Tuple.HT (swap)->>> import Data.Word (Word16)->>>->>> import Foreign.Storable (Storable)+>>> import Data.Word (Word8, Word16) >>> >>> type ShapeInt = Shape.ZeroBased Int >>> type X = Shape.Element@@ -128,27 +121,6 @@ >>> genArray :: QC.Gen (Array ShapeInt Word16) >>> genArray = Array.vectorFromList <$> QC.arbitrary >>>->>> genArray2 :: QC.Gen (Array (ShapeInt,ShapeInt) Word16)->>> genArray2 = do->>>    xs <- QC.arbitrary->>>    let n = length xs->>>    (k,m) <-->>>       if n == 0->>>          then QC.elements [(,) 0, flip (,) 0] <*> QC.choose (1,20)->>>          else fmap (\m -> (div n m, m)) $ QC.choose (1,n)->>>    return $ Array.fromList (Shape.ZeroBased k, Shape.ZeroBased m) xs->>>->>> genArrayForShape :: (Shape.C shape) => shape -> QC.Gen (Array shape Word16)->>> genArrayForShape sh =->>>    Array.fromList sh <$> replicateM (Shape.size sh) QC.arbitrary->>>->>> genNonEmptyArray2 :: QC.Gen (Array (ShapeInt,ShapeInt) Word16)->>> genNonEmptyArray2 = do->>>    xs <- QC.getNonEmpty <$> QC.arbitrary->>>    let n = length xs->>>    m <- QC.choose (1,n)->>>    return $ Array.fromList (Shape.ZeroBased (div n m), Shape.ZeroBased m) xs->>> >>> infix 4 ==? >>> (==?) :: a -> a -> (a,a) >>> (==?) = (,)@@ -161,12 +133,6 @@ >>>          if Array.shape xs == Shape.ZeroBased 0 >>>             then isBottom resultArray >>>             else resultArray == resultList->>>->>>->>> transpose ::->>>    (Shape.Indexed sh0, Shape.Indexed sh1, Storable a) =>->>>    Array (sh0,sh1) a -> Array (sh1,sh0) a->>> transpose a = Array.sample (swap $ Array.shape a) (\(i,j) -> a!(j,i)) -}  @@ -264,9 +230,7 @@    (Shape.Indexed sh, Storable a) => sh -> (Shape.Index sh -> a) -> Array sh a sample sh f = Array.fromList sh $ List.map f $ Shape.indices sh -replicate ::-   (Shape.Indexed sh, Storable a) =>-   sh -> a -> Array sh a+replicate :: (Shape.C sh, Storable a) => sh -> a -> Array sh a replicate sh a = runST (MutArrayNC.unsafeFreeze =<< MutArray.new sh a)  @@ -277,147 +241,27 @@ toBoxed arr = BoxedArray.fromList (Array.shape arr) $ Array.toList arr  -fromStorableVector ::-   (Storable a) => SVB.Vector a -> Array (Shape.ZeroBased Int) a-fromStorableVector xs =-   case SVB.toForeignPtr xs of-      (fptr,0,n) -> Array (Shape.ZeroBased n) fptr-      (fptr,s,n) ->-         Array.takeRight $-         Array (Shape.ZeroBased s ::+ Shape.ZeroBased n) fptr--toStorableVector :: (Shape.C sh, Storable a) => Array sh a -> SVB.Vector a-toStorableVector (Array sh fptr) =-   SVB.fromForeignPtr fptr $ Shape.size sh---{- |->>> :{-   Array.fromBlockArray1 $ BoxedArray.fromList Set.empty [] :: Array (Map Char ShapeInt) Word16-:}-StorableArray.fromList (fromList []) []-->>> :{-   let block n a = Array.replicate (shapeInt n) (a::Word16) in-   Array.fromBlockArray1 $-   BoxedArray.fromList (Set.fromList "ABC") [block 2 0, block 3 1, block 5 2]-:}-StorableArray.fromList (fromList [('A',ZeroBased {... 2}),('B',ZeroBased {... 3}),('C',ZeroBased {... 5})]) [0,0,1,1,1,2,2,2,2,2]--}-fromBlockArray1 ::+{-# DEPRECATED fromBlockArray1 "Use fromBlockArray instead." #-}+fromBlockArray, fromBlockArray1 ::    (Ord k, Shape.C shape, Storable a) =>    BoxedArray.Array (Set k) (Array shape a) -> Array (Map k shape) a-fromBlockArray1 a =+fromBlockArray1 = fromBlockArray+fromBlockArray a =    reshape (BoxedArray.toMap $ fmap Array.shape a) $-   fromStorableVector $ SV.concat $-   List.map toStorableVector $ BoxedArray.toList a--{- |-Only the outer @BoxedArray@ need to be non-empty.-->>> :{-   let shapeR0 = shapeInt 2; shapeR1 = shapeInt 3 in-   let shapeC0 = shapeInt 3; shapeC1 = shapeInt 2 in-   let block sh a = Array.replicate sh (a::Word16) in-   Array.fromBlockArray2-      (Map.singleton 'A' shapeR0 <> Map.singleton 'B' shapeR1)-      (Map.singleton '1' shapeC0 <> Map.singleton '2' shapeC1) $-   BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")-      [block (shapeR0,shapeC0) 0, block (shapeR0,shapeC1) 1,-       block (shapeR1,shapeC0) 2, block (shapeR1,shapeC1) 3]-:}-StorableArray.fromList (fromList [('A',ZeroBased {... 2}),('B',ZeroBased {... 3})],fromList [('1',ZeroBased {... 3}),('2',ZeroBased {... 2})]) [0,0,0,1,1,0,0,0,1,1,2,2,2,3,3,2,2,2,3,3,2,2,2,3,3]--prop> :{-   QC.forAll genArray2 $ \blockA1 ->-   QC.forAll genArray2 $ \blockB2 ->-   let shapeR0 = fst $ Array.shape blockA1 in-   let shapeC0 = snd $ Array.shape blockA1 in-   let shapeR1 = fst $ Array.shape blockB2 in-   let shapeC1 = snd $ Array.shape blockB2 in-   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->-   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->-   let blocked =-         BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")-            [blockA1, blockA2, blockB1, blockB2] in--   transpose (Array.fromNonEmptyBlockArray2 blocked)-   QC.===-   Array.fromNonEmptyBlockArray2-      (TestBoxedArray.transpose (fmap transpose blocked))-:}--prop> :{-   QC.forAll genArray2 $ \blockA1 ->-   QC.forAll genArray2 $ \blockB2 ->-   QC.forAll genArray2 $ \blockC3 ->-   let shapeR0 = fst $ Array.shape blockA1 in-   let shapeC0 = snd $ Array.shape blockA1 in-   let shapeR1 = fst $ Array.shape blockB2 in-   let shapeC1 = snd $ Array.shape blockB2 in-   let shapeR2 = fst $ Array.shape blockC3 in-   let shapeC2 = snd $ Array.shape blockC3 in-   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->-   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->-   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->-   QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ \blockB3 ->-   QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ \blockC1 ->-   QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ \blockC2 ->-   let blocked =-         BoxedArray.fromList (Set.fromList "ABC", Set.fromList "123")-            [blockA1, blockA2, blockA3,-             blockB1, blockB2, blockB3,-             blockC1, blockC2, blockC3] in+   Array.fromStorableVector $ SV.concat $+   List.map Array.toStorableVector $ BoxedArray.toList a -   transpose (Array.fromNonEmptyBlockArray2 blocked)-   QC.===-   Array.fromNonEmptyBlockArray2-      (TestBoxedArray.transpose (fmap transpose blocked))-:}--}+{-# DEPRECATED fromNonEmptyBlockArray2+      "Use Storable.Dim2.fromNonEmptyBlockArray instead." #-} fromNonEmptyBlockArray2 ::    (Ord row,    Shape.C height, Eq height) =>    (Ord column, Shape.C width,  Eq width) =>    (Storable a) =>    BoxedArray.Array (Set row, Set column) (Array (height, width) a) ->    Array (Map row height, Map column width) a-fromNonEmptyBlockArray2 arr =-   let shapes = List.map Array.shape $ BoxedArray.toList arr in-   let width = Set.size $ snd $ BoxedArray.shape arr in-   let (rowIxs, columnIxs) =-         mapPair (Set.toAscList, Set.toAscList) $ BoxedArray.shape arr in-   case (ListHT.sieve width shapes, take width shapes) of-      (leftColumn@(_:_), topRow@(_:_)) ->-         fromBlockArray2-            (Map.fromList $ List.zip rowIxs $ List.map fst leftColumn)-            (Map.fromList $ List.zip columnIxs $ List.map snd topRow)-            arr-      _ -> errorArray "fromNonEmptyBlockArray2" "empty array"--{- |-Explicit parameters for the shape of the result matrix-allow for working with arrays of zero rows or columns.-->>> :{-   (id :: Id (array (height, Map Char ShapeInt) Word16)) $-   Array.fromBlockArray2-      (Map.singleton 'A' (shapeInt 2) <> Map.singleton 'B' (shapeInt 3))-      Map.empty $-   BoxedArray.fromList (Set.fromList "AB", Set.empty) []-:}-StorableArray.fromList (fromList [('A',ZeroBased {... 2}),('B',ZeroBased {... 3})],fromList []) []--prop> :{-   QC.forAll genArray2 $ \block ->-   let height = Map.singleton 'A' $ fst $ Array.shape block in-   let width  = Map.singleton '1' $ snd $ Array.shape block in+fromNonEmptyBlockArray2 = Array2.fromNonEmptyBlockArray -   Array.reshape (height,width) block-   QC.===-   Array.fromBlockArray2 height width-      (BoxedArray.replicate (Set.singleton 'A', Set.singleton '1') block)-:}--}+{-# DEPRECATED fromBlockArray2 "Use Storable.Dim2.fromBlockArray instead." #-} fromBlockArray2 ::    (Ord row,    Shape.C height, Eq height) =>    (Ord column, Shape.C width,  Eq width) =>@@ -425,29 +269,7 @@    Map row height -> Map column width ->    BoxedArray.Array (Set row, Set column) (Array (height, width) a) ->    Array (Map row height, Map column width) a-fromBlockArray2 height width =-   Array.reshape (height, width) . fromStorableVector .-   SV.concat . List.concat . List.concatMap List.transpose .-   ListHT.sliceVertical (Map.size width) . BoxedArray.toList .-   BoxedArray.zipWith-      (\(h,w) block ->-         if (h,w) == Array.shape block-            then toRowSlices block-            else errorArray "fromBlockArray2" "block shapes mismatch")-      (BoxedArray.cartesian-         (BoxedArray.fromMap height) (BoxedArray.fromMap width))-{--[[[111,111],[222,222]],[[333,333],[444,444]]]-  |-  v-[111,222,111,222,333,444,333,444]--}--toRowSlices ::-   (Shape.C sh0, Shape.C sh1, Storable a) =>-   Array (sh0, sh1) a -> [SV.Vector a]-toRowSlices arr =-   SV.sliceVertical (Shape.size $ snd $ shape arr) $ toStorableVector arr+fromBlockArray2 = Array2.fromBlockArray   toAssociations ::@@ -513,36 +335,56 @@   {- |-prop> QC.forAll genNonEmptyArray2 $ \xs -> QC.forAll (QC.elements $ Shape.indices $ Array.shape xs) $ \(ix0,ix1) -> Array.pick xs ix0 ! ix1 == xs!(ix0,ix1)+>>> Array.takeSet (Set.fromList [0,2,4,7,13]) (Array.vectorFromList [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3::Word8])+StorableArray... (... [0,2,4,7,13]) [3,4,5,6,7] -}+{-# INLINE takeSet #-}+takeSet ::+   (Shape.Indexed sh, Shape.Index sh ~ ix, Ord ix, Storable a) =>+   Set ix -> Array sh a -> Array (Set ix) a+takeSet = takeSetGen Set.toAscList++{- |+>>> Array.takeIntSet (IntSet.fromList [0,2,4,7,13]) (Array.vectorFromList [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3::Word8])+StorableArray... (... [0,2,4,7,13]) [3,4,5,6,7]+-}+{-# INLINE takeIntSet #-}+takeIntSet ::+   (Shape.Indexed sh, Shape.Index sh ~ Int, Storable a) =>+   IntSet -> Array sh a -> Array IntSet a+takeIntSet = takeSetGen IntSet.toAscList++{-# INLINE takeSetGen #-}+takeSetGen ::+   (Shape.Indexed sh, Shape.Index sh ~ ix, Shape.C set, Storable a) =>+   (set -> [ix]) -> set -> Array sh a -> Array set a+takeSetGen listFromSet ixs (Array sh a) =+   Array.unsafeCreate ixs $ \dstPtr ->+   withForeignPtr a $ \srcPtr ->+   sequence_ $+      List.zipWith+         (\src dst -> poke dst =<< peekElemOff srcPtr src)+         (List.map (Shape.offset sh) $ listFromSet ixs)+         (iterate (flip advancePtr 1) dstPtr)+++{-# DEPRECATED pick "Use Storable.Dim2.takeRow instead." #-} pick ::    (Shape.Indexed sh0, Shape.C sh1, Storable a) =>    Array (sh0,sh1) a -> Shape.Index sh0 -> Array sh1 a-pick (Array (sh0,sh1) x) ix0 =-   Array.unsafeCreateWithSize sh1 $ \k yPtr ->-   withForeignPtr x $ \xPtr ->-      copyArray yPtr (advancePtr xPtr (Shape.offset sh0 ix0 * k)) k+pick = Array2.takeRow +{-# DEPRECATED toRowArray "Use Storable.Dim2.toRowArray instead." #-} toRowArray ::    (Shape.Indexed sh0, Shape.C sh1, Storable a) =>    Array (sh0,sh1) a -> BoxedArray.Array sh0 (Array sh1 a)-toRowArray x = fmap (pick x) $ BoxedArray.indices $ fst $ Array.shape x--{- |-It is a checked error if a row width differs from the result array width.+toRowArray = Array2.toRowArray -prop> QC.forAll genArray2 $ \xs -> xs == Array.fromRowArray (snd $ Array.shape xs) (Array.toRowArray xs)--}+{-# DEPRECATED fromRowArray "Use Storable.Dim2.fromRowArray instead." #-} fromRowArray ::    (Shape.C sh0, Shape.C sh1, Eq sh1, Storable a) =>    sh1 -> BoxedArray.Array sh0 (Array sh1 a) -> Array (sh0,sh1) a-fromRowArray sh1 x =-   Array.unsafeCreate (BoxedArray.shape x, sh1) $ \yPtr ->-   let k = Shape.size sh1 in-   forM_ (zip [0,k..] (BoxedArray.toList x)) $ \(j, Array sh1i row) ->-   if sh1 == sh1i-      then withForeignPtr row $ \xPtr -> copyArray (advancePtr yPtr j) xPtr k-      else errorArray "fromRowArray" "mismatching row width"+fromRowArray = Array2.fromRowArray   {- |
+ src/Data/Array/Comfort/Storable/Dim2.hs view
@@ -0,0 +1,697 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE UndecidableInstances #-}+module Data.Array.Comfort.Storable.Dim2 (+   Array2,+   singleRow, flattenRow,+   singleColumn, flattenColumn,+   takeRow,+   toRowArray,+   fromRowArray,+   above, beside,+   takeTop, takeBottom,+   takeLeft, takeRight,++   fromNonEmptyBlockArray,+   fromBlockArray,+   fromBlocks, BlockFunction, RowFunction,+   ShapeSequence(switchSequence),++   BlockArray, BlockMatrix, Block,+   fromBlockMatrix, block, blockAbove, blockBeside, (&===), (&|||),+   ) where++import qualified Data.Array.Comfort.Boxed as BoxedArray+import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Shape.SubSize as SubSize+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Unchecked (Array(Array))+import Data.Array.Comfort.Shape ((::+)((::+)))++import Foreign.Marshal.Array (copyArray, advancePtr)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Storable (Storable)++import qualified Data.StorableVector as SV++import qualified Data.Map as Map+import qualified Data.Set as Set+import qualified Data.List.HT as ListHT+import qualified Data.List as List+import Data.Map (Map)+import Data.Set (Set)+import Data.Foldable (forM_)+import Data.Tuple.HT (mapPair, mapFst)+import Data.Proxy (Proxy(Proxy))+++{- $setup+>>> import qualified DocTest.Data.Array.Comfort.Boxed.Unchecked+>>>                                              as TestBoxedArray+>>> import DocTest.Data.Array.Comfort.Storable (ShapeInt, shapeInt)+>>>+>>> import qualified Data.Array.Comfort.Boxed as BoxedArray+>>> import qualified Data.Array.Comfort.Storable.Dim2 as Array2+>>> import qualified Data.Array.Comfort.Storable as Array+>>> import qualified Data.Array.Comfort.Shape as Shape+>>> import Data.Array.Comfort.Storable.Dim2 (Array2, (&===), (&|||))+>>> import Data.Array.Comfort.Storable (Array, (!))+>>> import Data.Array.Comfort.Shape ((::+)((::+)))+>>>+>>> import qualified Test.QuickCheck as QC+>>>+>>> import Control.Monad (replicateM)+>>> import Control.Applicative (liftA2, (<$>), (<*>))+>>>+>>> import qualified Data.Map as Map+>>> import qualified Data.Set as Set+>>> import Data.Map (Map)+>>> import Data.Function.HT (Id)+>>> import Data.Tuple.HT (swap)+>>> import Data.Word (Word16)+>>> import Data.Proxy (Proxy(Proxy))+>>>+>>> import Foreign.Storable (Storable)+>>>+>>> genArray2 :: QC.Gen (Array2 ShapeInt ShapeInt Word16)+>>> genArray2 = do+>>>    xs <- QC.arbitrary+>>>    let n = length xs+>>>    (k,m) <-+>>>       if n == 0+>>>          then QC.elements [(,) 0, flip (,) 0] <*> QC.choose (1,20)+>>>          else fmap (\m -> (div n m, m)) $ QC.choose (1,n)+>>>    return $ Array.fromList (Shape.ZeroBased k, Shape.ZeroBased m) xs+>>>+>>> genArrayForShape :: (Shape.C shape) => shape -> QC.Gen (Array shape Word16)+>>> genArrayForShape sh =+>>>    Array.fromList sh <$> replicateM (Shape.size sh) QC.arbitrary+>>>+>>> genNonEmptyArray2 :: QC.Gen (Array2 ShapeInt ShapeInt Word16)+>>> genNonEmptyArray2 = do+>>>    xs <- QC.getNonEmpty <$> QC.arbitrary+>>>    let n = length xs+>>>    m <- QC.choose (1,n)+>>>    return $ Array.fromList (Shape.ZeroBased (div n m), Shape.ZeroBased m) xs+>>>+>>>+>>> transpose ::+>>>    (Shape.Indexed sh0, Shape.Indexed sh1, Storable a) =>+>>>    Array2 sh0 sh1 a -> Array2 sh1 sh0 a+>>> transpose a = Array.sample (swap $ Array.shape a) (\(i,j) -> a!(j,i))+-}+++type Array2 sh0 sh1 = Array (sh0,sh1)++singleRow :: Array width a -> Array2 () width a+singleRow = Array.mapShape ((,) ())++singleColumn :: Array height a -> Array2 height () a+singleColumn = Array.mapShape (flip (,) ())++flattenRow :: Array2 () width a -> Array width a+flattenRow = Array.mapShape snd++flattenColumn :: Array2 height () a -> Array height a+flattenColumn = Array.mapShape fst+++{- |+prop> :{+   QC.forAll genNonEmptyArray2 $ \xs ->+   QC.forAll (QC.elements $ Shape.indices $ Array.shape xs) $ \(ix0,ix1) ->+      Array2.takeRow xs ix0 ! ix1 == xs!(ix0,ix1)+:}+-}+takeRow ::+   (Shape.Indexed sh0, Shape.C sh1, Storable a) =>+   Array2 sh0 sh1 a -> Shape.Index sh0 -> Array sh1 a+takeRow (Array (sh0,sh1) x) ix0 =+   Array.unsafeCreateWithSize sh1 $ \k yPtr ->+   withForeignPtr x $ \xPtr ->+      copyArray yPtr (advancePtr xPtr (Shape.offset sh0 ix0 * k)) k++toRowArray ::+   (Shape.C sh0, Shape.C sh1, Storable a) =>+   Array2 sh0 sh1 a -> BoxedArray.Array sh0 (Array sh1 a)+toRowArray x =+   let y = Array.mapShape (mapFst Shape.Deferred) x in+   BoxedArray.mapShape (\(Shape.Deferred sh0) -> sh0) $+   fmap (takeRow y) $ BoxedArray.indices $ fst $ Array.shape y++{- |+It is a checked error if a row width differs from the result array width.++prop> :{+   QC.forAll genArray2 $ \xs ->+      xs == Array2.fromRowArray (snd $ Array.shape xs) (Array2.toRowArray xs)+:}+-}+fromRowArray ::+   (Shape.C sh0, Shape.C sh1, Eq sh1, Storable a) =>+   sh1 -> BoxedArray.Array sh0 (Array sh1 a) -> Array2 sh0 sh1 a+fromRowArray sh1 x =+   Array.unsafeCreateWithAutoSizes (BoxedArray.shape x, sh1) $+      \(SubSize.Atom _, SubSize.Atom k) yPtr ->+   forM_ (zip [0,k..] (BoxedArray.toList x)) $ \(j, Array sh1i row) ->+   if sh1 == sh1i+      then withForeignPtr row $ \xPtr -> copyArray (advancePtr yPtr j) xPtr k+      else errorArray "fromRowArray" "mismatching row width"+++infixr 2 `above`+infixr 3 `beside`++{- |+prop> :{+   QC.forAll genArray2 $ \xs ->+   let (Shape.ZeroBased m, width) = Array.shape xs in+   QC.forAll (QC.choose (0, m)) $ \k ->+      let ys = Array.reshape+                  (Shape.ZeroBased k ::+ Shape.ZeroBased (m-k), width) xs in+      ys == Array2.above (Array2.takeTop ys) (Array2.takeBottom ys)+:}+-}+above ::+   (Shape.C heightA, Shape.C heightB) =>+   (Shape.C width, Eq width) =>+   (Storable a) =>+   Array2 heightA width a ->+   Array2 heightB width a ->+   Array2 (heightA::+heightB) width a+above a b =+   Array.mapShape+      (\((heightA,widthA)::+(heightB,widthB)) ->+         if widthA == widthB+            then (heightA::+heightB, widthA)+            else error "Array.Dim2.above: widths mismatch") $+   Array.append a b++{- |+prop> :{+   QC.forAll genArray2 $ \xs ->+   let (height, Shape.ZeroBased n) = Array.shape xs in+   QC.forAll (QC.choose (0, n)) $ \k ->+      let ys = Array.reshape+                  (height, Shape.ZeroBased k ::+ Shape.ZeroBased (n-k)) xs in+      ys == Array2.beside (Array2.takeLeft ys) (Array2.takeRight ys)+:}+-}+beside ::+   (Shape.C height, Eq height) =>+   (Shape.C widthA, Shape.C widthB) =>+   (Storable a) =>+   Array2 height widthA a ->+   Array2 height widthB a ->+   Array2 height (widthA::+widthB) a+beside a b =+   case (Array.shape a, Array.shape b) of+      ((heightA, widthA), (heightB, widthB)) ->+         if heightA == heightB+            then+               Array.reshape (heightA, widthA::+widthB) .+               Array.fromStorableVector .+               SV.concat . concat . take (Shape.size heightA) $+               zipWith+                  (\arow brow -> [arow, brow])+                  (toRowSlicesInf a)+                  (toRowSlicesInf b)+            else error "Array.Dim2.beside: heights mismatch"+++takeTop ::+   (Shape.C heightA, Shape.C heightB, Shape.C width, Storable a) =>+   Array2 (heightA::+heightB) width a ->+   Array2 heightA width a+takeTop = Array.takeLeft . splitVertically++takeBottom ::+   (Shape.C heightA, Shape.C heightB, Shape.C width, Storable a) =>+   Array2 (heightA::+heightB) width a ->+   Array2 heightB width a+takeBottom = Array.takeRight . splitVertically++splitVertically ::+   (Shape.C heightA, Shape.C heightB, Shape.C width) =>+   Array2 (heightA::+heightB) width a ->+   Array ((heightA,width)::+(heightB,width)) a+splitVertically =+   Array.mapShape+      (\(heightA::+heightB, width) -> (heightA,width)::+(heightB,width))+++takeLeft ::+   (Shape.C height, Shape.C widthA, Shape.C widthB, Storable a) =>+   Array2 height (widthA::+widthB) a ->+   Array2 height widthA a+takeLeft a =+   case Array.shape a of+      (height, widthA::+widthB) ->+         let m = Shape.size height+             na = Shape.size widthA+             nb = Shape.size widthB+         in Array.reshape (height, widthA) . Array.fromStorableVector .+            SV.concat . take m . map (SV.take na) .+            iterate (SV.drop (na+nb)) .+            Array.toStorableVector $ a++takeRight ::+   (Shape.C height, Shape.C widthA, Shape.C widthB, Storable a) =>+   Array2 height (widthA::+widthB) a ->+   Array2 height widthB a+takeRight a =+   case Array.shape a of+      (height, widthA::+widthB) ->+         let m = Shape.size height+             na = Shape.size widthA+             nb = Shape.size widthB+         in Array.reshape (height, widthB) . Array.fromStorableVector .+            SV.concat . take m . map (SV.take nb) .+            iterate (SV.drop (na+nb)) . SV.drop na .+            Array.toStorableVector $ a+++{- |+Only the outer @BoxedArray@ need to be non-empty.++>>> :{+   let shapeR0 = shapeInt 2; shapeR1 = shapeInt 3 in+   let shapeC0 = shapeInt 3; shapeC1 = shapeInt 2 in+   let block sh a = Array.replicate sh (a::Word16) in+   Array2.fromBlockArray+      (Map.singleton 'A' shapeR0 <> Map.singleton 'B' shapeR1)+      (Map.singleton '1' shapeC0 <> Map.singleton '2' shapeC1) $+   BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")+      [block (shapeR0,shapeC0) 0, block (shapeR0,shapeC1) 1,+       block (shapeR1,shapeC0) 2, block (shapeR1,shapeC1) 3]+:}+StorableArray.fromList (fromList [('A',ZeroBased {... 2}),('B',ZeroBased {... 3})],fromList [('1',ZeroBased {... 3}),('2',ZeroBased {... 2})]) [0,0,0,1,1,0,0,0,1,1,2,2,2,3,3,2,2,2,3,3,2,2,2,3,3]++prop> :{+   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB2 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB2 in+   let shapeC1 = snd $ Array.shape blockB2 in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   let blocked =+         BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")+            [blockA1, blockA2, blockB1, blockB2] in++   transpose (Array2.fromNonEmptyBlockArray blocked)+   QC.===+   Array2.fromNonEmptyBlockArray+      (TestBoxedArray.transpose (fmap transpose blocked))+:}++prop> :{+   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB2 ->+   QC.forAll genArray2 $ \blockC3 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB2 in+   let shapeC1 = snd $ Array.shape blockB2 in+   let shapeR2 = fst $ Array.shape blockC3 in+   let shapeC2 = snd $ Array.shape blockC3 in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ \blockB3 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ \blockC1 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ \blockC2 ->+   let blocked =+         BoxedArray.fromList (Set.fromList "ABC", Set.fromList "123")+            [blockA1, blockA2, blockA3,+             blockB1, blockB2, blockB3,+             blockC1, blockC2, blockC3] in++   transpose (Array2.fromNonEmptyBlockArray blocked)+   QC.===+   Array2.fromNonEmptyBlockArray+      (TestBoxedArray.transpose (fmap transpose blocked))+:}+-}+fromNonEmptyBlockArray ::+   (Ord row,    Shape.C height, Eq height) =>+   (Ord column, Shape.C width,  Eq width) =>+   (Storable a) =>+   BoxedArray.Array (Set row, Set column) (Array2 height width a) ->+   Array2 (Map row height) (Map column width) a+fromNonEmptyBlockArray arr =+   let shapes = List.map Array.shape $ BoxedArray.toList arr in+   let width = Set.size $ snd $ BoxedArray.shape arr in+   let (rowIxs, columnIxs) =+         mapPair (Set.toAscList, Set.toAscList) $ BoxedArray.shape arr in+   case (ListHT.sieve width shapes, take width shapes) of+      (leftColumn@(_:_), topRow@(_:_)) ->+         fromBlockArray+            (Map.fromList $ List.zip rowIxs $ List.map fst leftColumn)+            (Map.fromList $ List.zip columnIxs $ List.map snd topRow)+            arr+      _ -> errorArray "fromNonEmptyBlockArray" "empty array"++{- |+Explicit parameters for the shape of the result matrix+allow for working with arrays of zero rows or columns.++>>> :{+   (id :: Id (array (height, Map Char ShapeInt) Word16)) $+   Array2.fromBlockArray+      (Map.singleton 'A' (shapeInt 2) <> Map.singleton 'B' (shapeInt 3))+      Map.empty $+   BoxedArray.fromList (Set.fromList "AB", Set.empty) []+:}+StorableArray.fromList (fromList [('A',ZeroBased {... 2}),('B',ZeroBased {... 3})],fromList []) []++prop> :{+   QC.forAll genArray2 $ \block ->+   let height = Map.singleton 'A' $ fst $ Array.shape block in+   let width  = Map.singleton '1' $ snd $ Array.shape block in++   Array.reshape (height,width) block+   QC.===+   Array2.fromBlockArray height width+      (BoxedArray.replicate (Set.singleton 'A', Set.singleton '1') block)+:}+-}+fromBlockArray ::+   (Ord row,    Shape.C height, Eq height) =>+   (Ord column, Shape.C width,  Eq width) =>+   (Storable a) =>+   Map row height -> Map column width ->+   BoxedArray.Array (Set row, Set column) (Array2 height width a) ->+   Array2 (Map row height) (Map column width) a+fromBlockArray height width =+   Array.reshape (height, width) . Array.fromStorableVector .+   SV.concat . List.concat . List.concatMap List.transpose .+   ListHT.sliceVertical (Map.size width) . BoxedArray.toList .+   BoxedArray.zipWith checkSliceBlock+      (BoxedArray.cartesian+         (BoxedArray.fromMap height) (BoxedArray.fromMap width))+{-+[[[111,111],[222,222]],[[333,333],[444,444]]]+  |+  v+[111,222,111,222,333,444,333,444]+-}++++class (Shape.C sh) => ShapeSequence sh where+   switchSequence ::+      f Shape.Zero ->+      (forall sh0 shs. (Shape.C sh0, Eq sh0, ShapeSequence shs) =>+         f (sh0::+shs)) ->+      f sh++instance ShapeSequence Shape.Zero where+   switchSequence f _ = f++instance+   (Shape.C sh, Eq sh, ShapeSequence shs) =>+      ShapeSequence (sh::+shs) where+   switchSequence _ f = f+++type family BlockFunction heights widths a r+type instance BlockFunction Shape.Zero widths a r = r+type instance BlockFunction (height::+heights) widths a r =+       RowFunction height widths a (BlockFunction heights widths a r)++newtype CreateBig widths a r heights =+   CreateBig {+      getCreateBig ::+         heights -> widths ->+         ([[SV.Vector a]] -> r) ->+         BlockFunction heights widths a r+   }++createBig ::+   (ShapeSequence heights, ShapeSequence widths, Storable a) =>+   heights -> widths ->+   ([[SV.Vector a]] -> r) ->+   BlockFunction heights widths a r+createBig =+   getCreateBig $+   switchSequence+      (CreateBig $ \Shape.Zero _widths cons -> cons [])+      (CreateBig $ \(height::+heights) widths cons ->+         createBlockRow heights widths cons height widths id)+++type family RowFunction height widths a r+type instance RowFunction height Shape.Zero a r = r+type instance RowFunction height (width::+widths) a r =+       Array2 height width a -> RowFunction height widths a r++newtype CreateBlockRow heightsRem widthsRem height a r widths =+   CreateBlockRow {+      getCreateBlockRow ::+         heightsRem -> widthsRem -> ([[SV.Vector a]] -> r) ->+         height ->     widths ->    ([[SV.Vector a]] -> [[SV.Vector a]]) ->+         RowFunction height widths a+            (BlockFunction heightsRem widthsRem a r)+   }++createBlockRow ::+   (ShapeSequence heightsRem, ShapeSequence widthsRem) =>+   (Shape.C height, Eq height, ShapeSequence widths, Storable a) =>+   heightsRem -> widthsRem -> ([[SV.Vector a]] -> r) ->+   height ->     widths ->    ([[SV.Vector a]] -> [[SV.Vector a]]) ->+   RowFunction height widths a+      (BlockFunction heightsRem widthsRem a r)+createBlockRow =+   getCreateBlockRow $+   switchSequence+      (CreateBlockRow $+         \heightsRem widthsRem consBig _height Shape.Zero consRow ->+            createBig heightsRem widthsRem+               (consBig . (List.transpose (consRow []) ++)))+      (CreateBlockRow $+         \heightsRem widthsRem consBig height (width::+widths) consRow blk ->+            createBlockRow+               heightsRem widthsRem consBig+               height widths+                  (consRow . (checkSliceBlock (height,width) blk :)))+++{- |+prop> :{+   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB2 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB2 in+   let shapeC1 = snd $ Array.shape blockB2 in+   let shapeR = shapeR0::+shapeR1::+Shape.Zero in+   let shapeC = shapeC0::+shapeC1::+Shape.Zero in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   let blocked =+         BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")+            [blockA1, blockA2, blockB1, blockB2] in++   Array.reshape (shapeR, shapeC)+      (Array2.fromNonEmptyBlockArray blocked)+   QC.===+   Array2.fromBlocks shapeR shapeC Proxy+      blockA1 blockA2+      blockB1 blockB2+:}+-}+fromBlocks ::+   (ShapeSequence height, ShapeSequence width, Storable a) =>+   height -> width -> Proxy a ->+   BlockFunction height width a (Array2 height width a)+fromBlocks height width proxy =+   createBig height width+      (Array.reshape (height, width) . Array.fromStorableVector .+       idSV proxy . SV.concat . List.concat)++idSV :: Proxy a -> SV.Vector a -> SV.Vector a+idSV Proxy = id++++data BlockArray shape a = BlockArray shape [[SV.Vector a]]+type BlockMatrix height width = BlockArray (height, width)++block ::+   (Block block, Shape.C height, Shape.C width, Storable a) =>+   block (height, width) a -> BlockMatrix height width a+block = blockPrivate++class Block block where+   blockPrivate ::+      (Shape.C height, Shape.C width, Storable a) =>+      block (height, width) a -> BlockMatrix height width a++instance Block BlockArray where+   blockPrivate = id++instance Block Array where+   blockPrivate arr =+      BlockArray (Array.shape arr)+         (map (:[]) $ take (Shape.size $ fst $ Array.shape arr) $+         toRowSlicesInf arr)++blockAbove ::+   (Eq width) =>+   BlockMatrix heightA width a -> BlockMatrix heightB width a ->+   BlockMatrix (heightA::+heightB) width a+blockAbove (BlockArray (heightA,widthA) a) (BlockArray (heightB,widthB) b) =+   BlockArray+      (if widthA == widthB+         then (heightA::+heightB, widthA)+         else error "Array.Dim2.blockAbove: widths mismatch")+      (a ++ b)++blockBeside ::+   (Eq height) =>+   BlockMatrix height widthA a -> BlockMatrix height widthB a ->+   BlockMatrix height (widthA::+widthB) a+blockBeside (BlockArray (heightA,widthA) a) (BlockArray (heightB,widthB) b) =+   BlockArray+      (if heightA == heightB+         then (heightA, widthA::+widthB)+         else error "Array.Dim2.beside: heights mismatch")+      (zipWith (++) a b)++infixr 2 &===+infixr 3 &|||++(&===) ::+   (Block blockA, Block blockB) =>+   (Shape.C heightA, Shape.C heightB) =>+   (Shape.C width, Eq width) =>+   (Storable a) =>+   blockA (heightA,width) a -> blockB (heightB,width) a ->+   BlockMatrix (heightA::+heightB) width a+(&===) a b = blockAbove (block a) (block b)++(&|||) ::+   (Block blockA, Block blockB) =>+   (Shape.C height, Eq height) =>+   (Shape.C widthA, Shape.C widthB) =>+   (Storable a) =>+   blockA (height,widthA) a -> blockB (height,widthB) a ->+   BlockMatrix height (widthA::+widthB) a+(&|||) a b = blockBeside (block a) (block b)++++{- |+prop> :{+   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB3 ->+   QC.forAll+      (liftA2+         (\char0 char1 -> Shape.Range (min char0 char1) (max char0 char1))+         (QC.choose ('a','k')) (QC.choose ('a','k'))) $+      \shapeC1 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB3 in+   let shapeC2 = snd $ Array.shape blockB3 in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC1)) $ \blockB2 ->++   Array2.fromBlockMatrix+      (blockA1 &||| Array2.beside blockA2 blockA3+       &===+       blockB1 &||| blockB2 &||| blockB3)+   QC.===+   Array.reshape+      (shapeR0::+shapeR1, shapeC0::+shapeC1::+shapeC2)+      (Array2.fromBlocks+         (shapeR0::+shapeR1::+Shape.Zero)+         (shapeC0::+shapeC1::+shapeC2::+Shape.Zero)+         Proxy+         blockA1 blockA2 blockA3+         blockB1 blockB2 blockB3)+:}++prop> :{+   QC.forAll+      (liftA2+         (\char0 char1 -> Shape.Range (min char0 char1) (max char0 char1))+         (QC.choose ('a','k')) (QC.choose ('a','k'))) $+      \shapeR0 ->+   QC.forAll+         (liftA2 Shape.Shifted (QC.choose (-10,10)) (QC.choose (0,10::Int))) $+      \shapeR1 ->+   let shapeR2 = () in+   QC.forAll (fmap Shape.ZeroBased (QC.choose (0,10::Int))) $+      \shapeC0 ->+   QC.forAll (fmap Shape.OneBased (QC.choose (0,10::Int))) $+      \shapeC1 ->+   let shapeC2 :: Shape.Enumeration Ordering+       shapeC2 = Shape.Enumeration in++   QC.forAll (genArrayForShape (shapeR0, shapeC0)) $ \blockA1 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC1)) $ \blockB2 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ \blockB3 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ \blockC1 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ \blockC2 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC2)) $ \blockC3 ->++   Array2.fromBlockMatrix+      (blockA1 &||| blockA2 &||| blockA3+       &===+       blockB1 &||| blockB2 &||| blockB3+       &===+       blockC1 &||| blockC2 &||| blockC3)+   QC.===+   Array2.beside+      (Array2.above blockA1 $ Array2.above blockB1 blockC1)+      (Array2.above+         (Array2.beside blockA2 blockA3)+         (Array2.beside+            (Array2.above blockB2 blockC2)+            (Array2.above blockB3 blockC3)))+:}+-}+fromBlockMatrix ::+   (Shape.C height, Shape.C width, Storable a) =>+   BlockMatrix height width a -> Array2 height width a+fromBlockMatrix (BlockArray (height, width) rows) =+   Array.reshape (height, width) .+   Array.fromStorableVector . SV.concat . List.concat $ rows+++checkSliceBlock ::+   (Shape.C sh0, Eq sh0, Shape.C sh1, Eq sh1, Storable a) =>+   (sh0, sh1) -> Array (sh0, sh1) a -> [SV.Vector a]+checkSliceBlock sh blk =+   if sh == Array.shape blk+      then toRowSlices blk+      else errorArray "fromBlockArray" "block shapes mismatch"++toRowSlices ::+   (Shape.C sh0, Shape.C sh1, Storable a) =>+   Array2 sh0 sh1 a -> [SV.Vector a]+toRowSlices arr =+   SV.sliceVertical (Shape.size $ snd $ Array.shape arr) $+   Array.toStorableVector arr++toRowSlicesInf ::+   (Shape.C sh0, Shape.C sh1, Storable a) =>+   Array2 sh0 sh1 a -> [SV.Vector a]+toRowSlicesInf arr =+   let n = Shape.size $ snd $ Array.shape arr in+   map (SV.take n) . iterate (SV.drop n) . Array.toStorableVector $ arr+++errorArray :: String -> String -> a+errorArray name msg =+   error ("Array.Comfort.Storable.Dim2." ++ name ++ ": " ++ msg)
src/Data/Array/Comfort/Storable/Unchecked.hs view
@@ -11,10 +11,14 @@    (Priv.!),    unsafeCreate,    unsafeCreateWithSize,+   unsafeCreateWithSizes,+   unsafeCreateWithAutoSizes,    unsafeCreateWithSizeAndResult,    Priv.toList,    Priv.fromList,    Priv.vectorFromList,+   fromStorableVector,+   toStorableVector,     map,    mapWithIndex,@@ -36,10 +40,13 @@ import qualified Data.Array.Comfort.Storable.Unchecked.Monadic as Monadic import qualified Data.Array.Comfort.Storable.Private as Priv import qualified Data.Array.Comfort.Storable.Memory as Memory+import qualified Data.Array.Comfort.Shape.SubSize as SubSize import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable.Private (Array(Array), mapShape) import Data.Array.Comfort.Shape ((::+)((::+))) +import qualified Data.StorableVector.Base as SVB+ import System.IO.Unsafe (unsafePerformIO) import Foreign.Marshal.Array (copyArray, advancePtr) import Foreign.Storable (Storable, poke, peek)@@ -83,6 +90,18 @@    sh -> (Int -> Ptr a -> IO ()) -> Array sh a unsafeCreateWithSize sh arr = runST (Monadic.unsafeCreateWithSize sh arr) +unsafeCreateWithSizes ::+   (Shape.C sh, Storable a) =>+   SubSize.T sh nsize -> sh -> (nsize -> Ptr a -> IO ()) -> Array sh a+unsafeCreateWithSizes sub sh arr =+   runST (Monadic.unsafeCreateWithSizes sub sh arr)++unsafeCreateWithAutoSizes ::+   (Shape.C sh, sh ~ SubSize.ToShape nsize, SubSize.C nsize,+    Storable a) =>+   sh -> (nsize -> Ptr a -> IO ()) -> Array sh a+unsafeCreateWithAutoSizes = unsafeCreateWithSizes SubSize.auto+ unsafeCreateWithSizeAndResult ::    (Shape.C sh, Storable a) =>    sh -> (Int -> Ptr a -> IO b) -> (Array sh a, b)@@ -90,13 +109,26 @@    runST (Monadic.unsafeCreateWithSizeAndResult sh arr)  +fromStorableVector ::+   (Storable a) => SVB.Vector a -> Array (Shape.ZeroBased Int) a+fromStorableVector xs =+   case SVB.toForeignPtr xs of+      (fptr,0,n) -> Array (Shape.ZeroBased n) fptr+      (fptr,s,n) ->+         takeRight $ Array (Shape.ZeroBased s ::+ Shape.ZeroBased n) fptr++toStorableVector :: (Shape.C sh, Storable a) => Array sh a -> SVB.Vector a+toStorableVector (Array sh fptr) =+   SVB.fromForeignPtr fptr $ Shape.size sh++ map ::    (Shape.C sh, Storable a, Storable b) =>    (a -> b) -> Array sh a -> Array sh b map f (Array sh a) =-   unsafeCreate sh $ \dstPtr ->+   unsafeCreateWithSize sh $ \n dstPtr ->    withForeignPtr a $ \srcPtr ->-   sequence_ $ List.take (Shape.size sh) $+   sequence_ $ List.take n $       List.zipWith          (\src dst -> poke dst . f =<< peek src)          (iterate (flip advancePtr 1) srcPtr)@@ -119,10 +151,10 @@    (Shape.C sh, Storable a, Storable b, Storable c) =>    (a -> b -> c) -> Array sh a -> Array sh b -> Array sh c zipWith f (Array _sh a) (Array sh b) =-   unsafeCreate sh $ \dstPtr ->+   unsafeCreateWithSize sh $ \n dstPtr ->    withForeignPtr a $ \srcAPtr ->    withForeignPtr b $ \srcBPtr ->-   sequence_ $ List.take (Shape.size sh) $+   sequence_ $ List.take n $       List.zipWith3          (\srcA srcB dst -> poke dst =<< liftA2 f (peek srcA) (peek srcB))          (iterate (flip advancePtr 1) srcAPtr)
+ src/Data/Array/Comfort/Storable/Unchecked/Creator.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE Rank2Types #-}+module Data.Array.Comfort.Storable.Unchecked.Creator where++import qualified Data.Array.Comfort.Shape.SubSize as SubSize+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Private (Array(Array))++import Foreign.Storable (Storable, )+import Foreign.Ptr (Ptr, )++import qualified Foreign.Marshal.Array.Guarded as Alloc+import qualified Control.Monad.Trans.Cont as MC+import Control.Monad.Primitive (PrimMonad, unsafeIOToPrim)++import Data.Biapplicative (Biapplicative(bipure, (<<*>>)))+import Data.Bifunctor (Bifunctor(bimap))++import Data.Tuple.HT (mapFst)+++newtype Creator arr ptr = Creator (forall a. (ptr -> IO a) -> IO (arr, a))++liftIO :: IO ptr -> Creator () ptr+liftIO act = Creator $ \f -> fmap ((,) ()) $ f =<< act++liftContT :: (forall a. MC.ContT a IO ptr) -> Creator () ptr+liftContT act = Creator $ \f -> fmap ((,) ()) $ MC.runContT act f++instance Functor (Creator arr) where+   fmap g (Creator act) = Creator $ \f -> act (f . g)+++pair ::+   Creator arr0 ptr0 -> Creator arr1 ptr1 ->+   Creator (arr0,arr1) (ptr0,ptr1)+pair (Creator act0) (Creator act1) =+   Creator $ \f ->+      fmap (\(arr0,(arr1,a)) -> ((arr0,arr1),a)) $+      act0 $ \ptr0 ->+      act1 $ \ptr1 ->+         f (ptr0, ptr1)++instance Bifunctor Creator where+   bimap g h (Creator act) = Creator $ \f -> fmap (mapFst g) $ act (f . h)++instance Biapplicative Creator where+   bipure a b = Creator $ \f -> fmap ((,) a) $ f b+   creator0 <<*>> creator1 =+      bimap (uncurry id) (uncurry id) $ pair creator0 creator1++unsafeRun :: (PrimMonad m) => Creator arr ptr -> (ptr -> IO ()) -> m arr+unsafeRun (Creator act) f = unsafeIOToPrim $ fmap (\(arr,()) -> arr) $ act f++unsafeRunWithResult ::+   (PrimMonad m) => Creator arr ptr -> (ptr -> IO b) -> m (arr, b)+unsafeRunWithResult (Creator act) f = unsafeIOToPrim $ act f++{-# INLINE create #-}+create ::+   (Shape.C sh, Storable a) =>+   sh -> Creator (Array sh a) (Ptr a)+create sh = fmap snd $ createWithSize sh++{-# INLINE createWithSize #-}+createWithSize ::+   (Shape.C sh, Storable a) =>+   sh -> Creator (Array sh a) (Int, Ptr a)+createWithSize sh =+   let size = Shape.size sh+   in Creator $ \f ->+         fmap (mapFst (Array sh)) $ Alloc.create size $ curry f size++{-# INLINE createWithSizes #-}+createWithSizes ::+   (Shape.C sh, Storable a) =>+   SubSize.T sh nsize -> sh -> Creator (Array sh a) (nsize, Ptr a)+createWithSizes (SubSize.Cons subSize) sh =+   let (size, subSizes) = subSize sh+   in Creator $ \f ->+         fmap (mapFst (Array sh)) $ Alloc.create size $ curry f subSizes
src/Data/Array/Comfort/Storable/Unchecked/Monadic.hs view
@@ -1,5 +1,8 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-} module Data.Array.Comfort.Storable.Unchecked.Monadic where +import qualified Data.Array.Comfort.Shape.SubSize as SubSize import qualified Data.Array.Comfort.Shape as Shape import Data.Array.Comfort.Storable.Private (Array(Array)) @@ -23,9 +26,30 @@    sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a) unsafeCreateWithSize sh f = liftM fst $ unsafeCreateWithSizeAndResult sh f +unsafeCreateWithSizes ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   SubSize.T sh nsize -> sh -> (nsize -> Ptr a -> IO ()) -> m (Array sh a)+unsafeCreateWithSizes sub sh f =+   liftM fst $ unsafeCreateWithSizesAndResult sub sh f+ unsafeCreateWithSizeAndResult ::    (PrimMonad m, Shape.C sh, Storable a) =>    sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b) unsafeCreateWithSizeAndResult sh f = unsafeIOToPrim $    let size = Shape.size sh    in fmap (mapFst (Array sh)) $ Alloc.create size $ f size++unsafeCreateWithSizesAndResult ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   SubSize.T sh nsize -> sh -> (nsize -> Ptr a -> IO b) -> m (Array sh a, b)+unsafeCreateWithSizesAndResult (SubSize.Cons subSize) sh f = unsafeIOToPrim $+   let (size, subSizes) = subSize sh+   in fmap (mapFst (Array sh)) $ Alloc.create size $ f subSizes++_unsafeCreateWithSizesAndResult ::+   (PrimMonad m, Storable a,+    SubSize.C nsize, SubSize.ToShape nsize ~ sh, Shape.C sh) =>+   sh -> (Int -> nsize -> Ptr a -> IO b) -> m (Array sh a, b)+_unsafeCreateWithSizesAndResult sh f = unsafeIOToPrim $+   let (size, subSizes) = SubSize.evaluate sh+   in fmap (mapFst (Array sh)) $ Alloc.create size $ f size subSizes
− test-module.list
@@ -1,5 +0,0 @@-Data.Array.Comfort.Shape-Data.Array.Comfort.Storable-Data.Array.Comfort.Storable.Unchecked-Data.Array.Comfort.Boxed-Data.Array.Comfort.Boxed.Unchecked
test/DocTest/Data/Array/Comfort/Shape.hs view
@@ -19,87 +19,87 @@  test :: DocTest.T () test = do- DocTest.printPrefix "Data.Array.Comfort.Shape:344: "-{-# LINE 344 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:345: "+{-# LINE 345 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 344 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 345 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices ()   )   [ExpectedLine [LineChunk "[()]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:367: "-{-# LINE 367 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:368: "+{-# LINE 368 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 367 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 368 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.ZeroBased (7::Int))   )   [ExpectedLine [LineChunk "[0,1,2,3,4,5,6]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:425: "-{-# LINE 425 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:426: "+{-# LINE 426 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 425 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 426 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.OneBased (7::Int))   )   [ExpectedLine [LineChunk "[1,2,3,4,5,6,7]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:475: "-{-# LINE 475 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:476: "+{-# LINE 476 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 475 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 476 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.Range (-5) (5::Int))   )   [ExpectedLine [LineChunk "[-5,-4,-3,-2,-1,0,1,2,3,4,5]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:477: "-{-# LINE 477 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:478: "+{-# LINE 478 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 477 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 478 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.Range (-1,-1) (1::Int,1::Int))   )   [ExpectedLine [LineChunk "[(-1,-1),(-1,0),(-1,1),(0,-1),(0,0),(0,1),(1,-1),(1,0),(1,1)]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:527: "-{-# LINE 527 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:528: "+{-# LINE 528 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 527 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 528 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.Shifted (-4) (8::Int))   )   [ExpectedLine [LineChunk "[-4,-3,-2,-1,0,1,2,3]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:598: "-{-# LINE 598 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:599: "+{-# LINE 599 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 598 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 599 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.Enumeration :: Shape.Enumeration Ordering)   )   [ExpectedLine [LineChunk "[LT,EQ,GT]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:662: "-{-# LINE 662 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:663: "+{-# LINE 663 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 662 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 663 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Set.fromList "comfort")   )   [ExpectedLine [LineChunk "\"cfmort\""]]- DocTest.printPrefix "Data.Array.Comfort.Shape:693: "-{-# LINE 693 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:694: "+{-# LINE 694 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 693 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 694 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (IntSet.fromList [3,1,4,1,5,9,2,6,5,3])   )   [ExpectedLine [LineChunk "[1,2,3,4,5,6,9]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:726: "-{-# LINE 726 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:727: "+{-# LINE 727 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 726 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 727 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ fmap Shape.ZeroBased $ Map.fromList [('b', (0::Int)), ('a', 5), ('c', 2)]   )   [ExpectedLine [LineChunk "[('a',0),('a',1),('a',2),('a',3),('a',4),('c',0),('c',1)]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:784: "-{-# LINE 784 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:785: "+{-# LINE 785 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 784 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 785 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ IntMap.fromList [(2, Set.fromList "abc"), (0, Set.fromList "a"), (1, Set.fromList "d")]   )   [ExpectedLine [LineChunk "[(0,'a'),(1,'d'),(2,'a'),(2,'b'),(2,'c')]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:850: "-{-# LINE 850 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:851: "+{-# LINE 851 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 850 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 851 "src/Data/Array/Comfort/Shape.hs" #-}           let sh2 = (Shape.ZeroBased (2::Int), Shape.ZeroBased (2::Int)) in    let sh3 = (Shape.ZeroBased (3::Int), Shape.ZeroBased (3::Int)) in@@ -108,156 +108,156 @@       Shape.indexFromOffset (Shape.Deferred sh2) 3)   )   [ExpectedLine [LineChunk "(4,3)"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:954: "-{-# LINE 954 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:955: "+{-# LINE 955 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 954 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 955 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.ZeroBased (3::Int), Shape.ZeroBased (3::Int))   )   [ExpectedLine [LineChunk "[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1076: "-{-# LINE 1076 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1077: "+{-# LINE 1077 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1076 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1077 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.Square $ Shape.ZeroBased (3::Int)   )   [ExpectedLine [LineChunk "[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1133: "-{-# LINE 1133 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1134: "+{-# LINE 1134 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1133 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1134 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.Cube $ Shape.ZeroBased (2::Int)   )   [ExpectedLine [LineChunk "[(0,0,0),(0,0,1),(0,1,0),(0,1,1),(1,0,0),(1,0,1),(1,1,0),(1,1,1)]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1195: "-{-# LINE 1195 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1196: "+{-# LINE 1196 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1195 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1196 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.Triangular Shape.Upper $ Shape.ZeroBased (3::Int)   )   [ExpectedLine [LineChunk "[(0,0),(0,1),(0,2),(1,1),(1,2),(2,2)]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1197: "-{-# LINE 1197 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1198: "+{-# LINE 1198 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1197 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1198 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.Triangular Shape.Lower $ Shape.ZeroBased (3::Int)   )   [ExpectedLine [LineChunk "[(0,0),(1,0),(1,1),(2,0),(2,1),(2,2)]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1329: "-{-# LINE 1329 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1330: "+{-# LINE 1330 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1329 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1330 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexAscending (replicate 3 Shape.AllDistinct) $ Shape.ZeroBased (4::Int)   )   [ExpectedLine [LineChunk "[[0,1,2],[0,1,3],[0,2,3],[1,2,3]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1331: "-{-# LINE 1331 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1332: "+{-# LINE 1332 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1331 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1332 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexAscending (replicate 3 Shape.SomeRepetitive) $ Shape.ZeroBased (3::Int)   )   [ExpectedLine [LineChunk "[[0,0,0],[0,0,1],[0,0,2],[0,1,1],[0,1,2],[0,2,2],[1,1,1],[1,1,2],[1,2,2],[2,2,2]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1333: "-{-# LINE 1333 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1334: "+{-# LINE 1334 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1333 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1334 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexAscending [Shape.Repetitive,Shape.Distinct,Shape.Repetitive] $ Shape.ZeroBased (4::Int)   )   [ExpectedLine [LineChunk "[[0,0,1],[0,0,2],[0,0,3],[0,1,2],[0,1,3],[0,2,3],[1,1,2],[1,1,3],[1,2,3],[2,2,3]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1335: "-{-# LINE 1335 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1336: "+{-# LINE 1336 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1335 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1336 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexAscending [Shape.Repetitive,Shape.Distinct,Shape.Distinct] $ Shape.ZeroBased (4::Int)   )   [ExpectedLine [LineChunk "[[0,0,1],[0,0,2],[0,0,3],[0,1,2],[0,1,3],[0,2,3],[1,1,2],[1,1,3],[1,2,3],[2,2,3]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1338: "-{-# LINE 1338 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1339: "+{-# LINE 1339 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1338 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1339 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexDescending (replicate 3 Shape.AllDistinct) $ Shape.ZeroBased (4::Int)   )   [ExpectedLine [LineChunk "[[2,1,0],[3,1,0],[3,2,0],[3,2,1]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1340: "-{-# LINE 1340 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1341: "+{-# LINE 1341 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1340 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1341 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexDescending (replicate 3 Shape.SomeRepetitive) $ Shape.ZeroBased (3::Int)   )   [ExpectedLine [LineChunk "[[0,0,0],[1,0,0],[1,1,0],[1,1,1],[2,0,0],[2,1,0],[2,1,1],[2,2,0],[2,2,1],[2,2,2]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1342: "-{-# LINE 1342 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1343: "+{-# LINE 1343 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1342 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1343 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexDescending [Shape.Repetitive,Shape.Distinct,Shape.Repetitive] $ Shape.ZeroBased (4::Int)   )   [ExpectedLine [LineChunk "[[1,1,0],[2,1,0],[2,2,0],[2,2,1],[3,1,0],[3,2,0],[3,2,1],[3,3,0],[3,3,1],[3,3,2]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1344: "-{-# LINE 1344 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1345: "+{-# LINE 1345 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1344 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1345 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices $ Shape.simplexDescending [Shape.Repetitive,Shape.Distinct,Shape.Distinct] $ Shape.ZeroBased (4::Int)   )   [ExpectedLine [LineChunk "[[1,1,0],[2,1,0],[2,2,0],[2,2,1],[3,1,0],[3,2,0],[3,2,1],[3,3,0],[3,3,1],[3,3,2]]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1578: "-{-# LINE 1578 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1579: "+{-# LINE 1579 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.property(-{-# LINE 1578 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1579 "src/Data/Array/Comfort/Shape.hs" #-}       let shape = Shape.Cyclic (10::Int) in Shape.offset shape (-1) == Shape.offset shape 9   )- DocTest.printPrefix "Data.Array.Comfort.Shape:1583: "-{-# LINE 1583 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1584: "+{-# LINE 1584 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1583 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1584 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.Cyclic (7::Int))   )   [ExpectedLine [LineChunk "[0,1,2,3,4,5,6]"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1627: "-{-# LINE 1627 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1628: "+{-# LINE 1628 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1627 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1628 "src/Data/Array/Comfort/Shape.hs" #-}     Shape.indices (Shape.ZeroBased (3::Int) ::+ Shape.Range 'a' 'c')   )   [ExpectedLine [LineChunk "[Left 0,Left 1,Left 2,Right 'a',Right 'b',Right 'c']"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1714: "-{-# LINE 1714 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1715: "+{-# LINE 1715 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1714 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1715 "src/Data/Array/Comfort/Shape.hs" #-}     rnf (Shape.NestedTuple (Shape.Element 1, Shape.Element 2))   )   [ExpectedLine [LineChunk "()"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1716: "-{-# LINE 1716 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1717: "+{-# LINE 1717 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1716 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1717 "src/Data/Array/Comfort/Shape.hs" #-}     rnf (Shape.NestedTuple (Shape.Element 1, (Shape.Element 2, Shape.Element 3)))   )   [ExpectedLine [LineChunk "()"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1718: "-{-# LINE 1718 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1719: "+{-# LINE 1719 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1718 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1719 "src/Data/Array/Comfort/Shape.hs" #-}     isBottom $ rnf (Shape.NestedTuple (Shape.Element undefined, Shape.Element 2))   )   [ExpectedLine [LineChunk "True"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1720: "-{-# LINE 1720 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1721: "+{-# LINE 1721 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1720 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1721 "src/Data/Array/Comfort/Shape.hs" #-}     isBottom $ rnf (Shape.NestedTuple (Shape.Element undefined, (Shape.Element 2, Shape.Element 3)))   )   [ExpectedLine [LineChunk "True"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1722: "-{-# LINE 1722 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1723: "+{-# LINE 1723 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1722 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1723 "src/Data/Array/Comfort/Shape.hs" #-}     isBottom $ rnf (Shape.NestedTuple (Shape.Element 1, (Shape.Element undefined, Shape.Element 3)))   )   [ExpectedLine [LineChunk "True"]]- DocTest.printPrefix "Data.Array.Comfort.Shape:1724: "-{-# LINE 1724 "src/Data/Array/Comfort/Shape.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Shape:1725: "+{-# LINE 1725 "src/Data/Array/Comfort/Shape.hs" #-}  DocTest.example(-{-# LINE 1724 "src/Data/Array/Comfort/Shape.hs" #-}+{-# LINE 1725 "src/Data/Array/Comfort/Shape.hs" #-}     isBottom $ rnf (Shape.NestedTuple (Shape.Element 1, (Shape.Element 2, Shape.Element undefined)))   )   [ExpectedLine [LineChunk "True"]]
test/DocTest/Data/Array/Comfort/Storable.hs view
@@ -1,15 +1,12 @@ -- Do not edit! Automatically created with doctest-extract from src/Data/Array/Comfort/Storable.hs-{-# LINE 98 "src/Data/Array/Comfort/Storable.hs" #-}+{-# LINE 100 "src/Data/Array/Comfort/Storable.hs" #-}  module DocTest.Data.Array.Comfort.Storable where  import Test.DocTest.Base import qualified Test.DocTest.Driver as DocTest -{-# LINE 99 "src/Data/Array/Comfort/Storable.hs" #-}-import     qualified DocTest.Data.Array.Comfort.Boxed.Unchecked-                                                 as TestBoxedArray-import     qualified Data.Array.Comfort.Boxed as BoxedArray+{-# LINE 101 "src/Data/Array/Comfort/Storable.hs" #-} import     qualified Data.Array.Comfort.Storable as Array import     qualified Data.Array.Comfort.Shape as Shape import     Data.Array.Comfort.Storable (Array, (!))@@ -17,18 +14,12 @@ import     qualified Test.QuickCheck as QC import     Test.ChasingBottoms.IsBottom (isBottom) -import     Control.Monad (replicateM)-import     Control.Applicative ((<$>), (<*>))+import     Control.Applicative ((<$>)) -import     qualified Data.Map as Map+import     qualified Data.IntSet as IntSet import     qualified Data.Set as Set-import     Data.Map (Map)-import     Data.Function.HT (Id) import     Data.Complex (Complex((:+)))-import     Data.Tuple.HT (swap)-import     Data.Word (Word16)--import     Foreign.Storable (Storable)+import     Data.Word (Word8, Word16)  type     ShapeInt = Shape.ZeroBased Int type     X = Shape.Element@@ -39,27 +30,6 @@ genArray     :: QC.Gen (Array ShapeInt Word16) genArray     = Array.vectorFromList <$> QC.arbitrary -genArray2     :: QC.Gen (Array (ShapeInt,ShapeInt) Word16)-genArray2     = do-       xs <- QC.arbitrary-       let n = length xs-       (k,m) <--          if n == 0-             then QC.elements [(,) 0, flip (,) 0] <*> QC.choose (1,20)-             else fmap (\m -> (div n m, m)) $ QC.choose (1,n)-       return $ Array.fromList (Shape.ZeroBased k, Shape.ZeroBased m) xs--genArrayForShape     :: (Shape.C shape) => shape -> QC.Gen (Array shape Word16)-genArrayForShape     sh =-       Array.fromList sh <$> replicateM (Shape.size sh) QC.arbitrary--genNonEmptyArray2     :: QC.Gen (Array (ShapeInt,ShapeInt) Word16)-genNonEmptyArray2     = do-       xs <- QC.getNonEmpty <$> QC.arbitrary-       let n = length xs-       m <- QC.choose (1,n)-       return $ Array.fromList (Shape.ZeroBased (div n m), Shape.ZeroBased m) xs- infix     4 ==? (==?)     :: a -> a -> (a,a) (==?)     = (,)@@ -73,188 +43,71 @@                 then isBottom resultArray                 else resultArray == resultList --transpose     ::-       (Shape.Indexed sh0, Shape.Indexed sh1, Storable a) =>-       Array (sh0,sh1) a -> Array (sh1,sh0) a-transpose     a = Array.sample (swap $ Array.shape a) (\(i,j) -> a!(j,i))- test :: DocTest.T () test = do- DocTest.printPrefix "Data.Array.Comfort.Storable:185: "-{-# LINE 185 "src/Data/Array/Comfort/Storable.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable:151: "+{-# LINE 151 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.example(-{-# LINE 185 "src/Data/Array/Comfort/Storable.hs" #-}+{-# LINE 151 "src/Data/Array/Comfort/Storable.hs" #-}     Array.fromList (shapeInt 5) ['a'..]   )   [ExpectedLine [LineChunk "StorableArray.fromList (ZeroBased {zeroBasedSize = 5}) \"abcde\""]]- DocTest.printPrefix "Data.Array.Comfort.Storable:204: "-{-# LINE 204 "src/Data/Array/Comfort/Storable.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable:170: "+{-# LINE 170 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.example(-{-# LINE 204 "src/Data/Array/Comfort/Storable.hs" #-}+{-# LINE 170 "src/Data/Array/Comfort/Storable.hs" #-}     Array.fromTuple ('a',('b','c')) :: Array (Shape.NestedTuple Shape.TupleIndex (X,(X,X))) Char   )   [ExpectedLine [LineChunk "StorableArray.fromList (NestedTuple {getNestedTuple = (Element 0,(Element 1,Element 2))}) \"abc\""]]- DocTest.printPrefix "Data.Array.Comfort.Storable:207: "-{-# LINE 207 "src/Data/Array/Comfort/Storable.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable:173: "+{-# LINE 173 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.example(-{-# LINE 207 "src/Data/Array/Comfort/Storable.hs" #-}+{-# LINE 173 "src/Data/Array/Comfort/Storable.hs" #-}           let arr :: Array (Shape.NestedTuple Shape.TupleAccessor (X,(X,X))) Char        arr = Array.fromTuple ('a',('b','c'))    in (arr ! fst, arr ! (fst.snd))   )   [ExpectedLine [LineChunk "('a','b')"]]- DocTest.printPrefix "Data.Array.Comfort.Storable:230: "-{-# LINE 230 "src/Data/Array/Comfort/Storable.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable:196: "+{-# LINE 196 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.example(-{-# LINE 230 "src/Data/Array/Comfort/Storable.hs" #-}+{-# LINE 196 "src/Data/Array/Comfort/Storable.hs" #-}           let arr = Array.fromRecord ('a' :+ 'b') in    let (real:+imag) = Shape.indexRecordFromShape $ Array.shape arr in    (arr ! real, arr ! imag)   )   [ExpectedLine [LineChunk "('a','b')"]]- DocTest.printPrefix "Data.Array.Comfort.Storable:295: "-{-# LINE 295 "src/Data/Array/Comfort/Storable.hs" #-}- DocTest.example(-{-# LINE 295 "src/Data/Array/Comfort/Storable.hs" #-}-      -   Array.fromBlockArray1 $ BoxedArray.fromList Set.empty [] :: Array (Map Char ShapeInt) Word16-  )-  [ExpectedLine [LineChunk "StorableArray.fromList (fromList []) []"]]- DocTest.printPrefix "Data.Array.Comfort.Storable:300: "-{-# LINE 300 "src/Data/Array/Comfort/Storable.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable:338: "+{-# LINE 338 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.example(-{-# LINE 300 "src/Data/Array/Comfort/Storable.hs" #-}-      -   let block n a = Array.replicate (shapeInt n) (a::Word16) in-   Array.fromBlockArray1 $-   BoxedArray.fromList (Set.fromList "ABC") [block 2 0, block 3 1, block 5 2]+{-# LINE 338 "src/Data/Array/Comfort/Storable.hs" #-}+    Array.takeSet (Set.fromList [0,2,4,7,13]) (Array.vectorFromList [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3::Word8])   )-  [ExpectedLine [LineChunk "StorableArray.fromList (fromList [('A',ZeroBased {",WildCardChunk,LineChunk " 2}),('B',ZeroBased {",WildCardChunk,LineChunk " 3}),('C',ZeroBased {",WildCardChunk,LineChunk " 5})]) [0,0,1,1,1,2,2,2,2,2]"]]- DocTest.printPrefix "Data.Array.Comfort.Storable:318: "-{-# LINE 318 "src/Data/Array/Comfort/Storable.hs" #-}+  [ExpectedLine [LineChunk "StorableArray",WildCardChunk,LineChunk " (",WildCardChunk,LineChunk " [0,2,4,7,13]) [3,4,5,6,7]"]]+ DocTest.printPrefix "Data.Array.Comfort.Storable:348: "+{-# LINE 348 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.example(-{-# LINE 318 "src/Data/Array/Comfort/Storable.hs" #-}-      -   let shapeR0 = shapeInt 2; shapeR1 = shapeInt 3 in-   let shapeC0 = shapeInt 3; shapeC1 = shapeInt 2 in-   let block sh a = Array.replicate sh (a::Word16) in-   Array.fromBlockArray2-      (Map.singleton 'A' shapeR0 <> Map.singleton 'B' shapeR1)-      (Map.singleton '1' shapeC0 <> Map.singleton '2' shapeC1) $-   BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")-      [block (shapeR0,shapeC0) 0, block (shapeR0,shapeC1) 1,-       block (shapeR1,shapeC0) 2, block (shapeR1,shapeC1) 3]-  )-  [ExpectedLine [LineChunk "StorableArray.fromList (fromList [('A',ZeroBased {",WildCardChunk,LineChunk " 2}),('B',ZeroBased {",WildCardChunk,LineChunk " 3})],fromList [('1',ZeroBased {",WildCardChunk,LineChunk " 3}),('2',ZeroBased {",WildCardChunk,LineChunk " 2})]) [0,0,0,1,1,0,0,0,1,1,2,2,2,3,3,2,2,2,3,3,2,2,2,3,3]"]]- DocTest.printPrefix "Data.Array.Comfort.Storable:331: "-{-# LINE 331 "src/Data/Array/Comfort/Storable.hs" #-}- DocTest.property(-{-# LINE 331 "src/Data/Array/Comfort/Storable.hs" #-}-        -   QC.forAll genArray2 $ \blockA1 ->-   QC.forAll genArray2 $ \blockB2 ->-   let shapeR0 = fst $ Array.shape blockA1 in-   let shapeC0 = snd $ Array.shape blockA1 in-   let shapeR1 = fst $ Array.shape blockB2 in-   let shapeC1 = snd $ Array.shape blockB2 in-   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->-   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->-   let blocked =-         BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")-            [blockA1, blockA2, blockB1, blockB2] in--   transpose (Array.fromNonEmptyBlockArray2 blocked)-   QC.===-   Array.fromNonEmptyBlockArray2-      (TestBoxedArray.transpose (fmap transpose blocked))+{-# LINE 348 "src/Data/Array/Comfort/Storable.hs" #-}+    Array.takeIntSet (IntSet.fromList [0,2,4,7,13]) (Array.vectorFromList [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3::Word8])   )- DocTest.printPrefix "Data.Array.Comfort.Storable:350: "-{-# LINE 350 "src/Data/Array/Comfort/Storable.hs" #-}+  [ExpectedLine [LineChunk "StorableArray",WildCardChunk,LineChunk " (",WildCardChunk,LineChunk " [0,2,4,7,13]) [3,4,5,6,7]"]]+ DocTest.printPrefix "Data.Array.Comfort.Storable:393: "+{-# LINE 393 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.property(-{-# LINE 350 "src/Data/Array/Comfort/Storable.hs" #-}-        -   QC.forAll genArray2 $ \blockA1 ->-   QC.forAll genArray2 $ \blockB2 ->-   QC.forAll genArray2 $ \blockC3 ->-   let shapeR0 = fst $ Array.shape blockA1 in-   let shapeC0 = snd $ Array.shape blockA1 in-   let shapeR1 = fst $ Array.shape blockB2 in-   let shapeC1 = snd $ Array.shape blockB2 in-   let shapeR2 = fst $ Array.shape blockC3 in-   let shapeC2 = snd $ Array.shape blockC3 in-   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->-   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->-   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->-   QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ \blockB3 ->-   QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ \blockC1 ->-   QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ \blockC2 ->-   let blocked =-         BoxedArray.fromList (Set.fromList "ABC", Set.fromList "123")-            [blockA1, blockA2, blockA3,-             blockB1, blockB2, blockB3,-             blockC1, blockC2, blockC3] in--   transpose (Array.fromNonEmptyBlockArray2 blocked)-   QC.===-   Array.fromNonEmptyBlockArray2-      (TestBoxedArray.transpose (fmap transpose blocked))+{-# LINE 393 "src/Data/Array/Comfort/Storable.hs" #-}+      forAllNonEmpty $ \xs -> Array.minimum xs ==? minimum (Array.toList xs)   )  DocTest.printPrefix "Data.Array.Comfort.Storable:401: " {-# LINE 401 "src/Data/Array/Comfort/Storable.hs" #-}- DocTest.example(-{-# LINE 401 "src/Data/Array/Comfort/Storable.hs" #-}-      -   (id :: Id (array (height, Map Char ShapeInt) Word16)) $-   Array.fromBlockArray2-      (Map.singleton 'A' (shapeInt 2) <> Map.singleton 'B' (shapeInt 3))-      Map.empty $-   BoxedArray.fromList (Set.fromList "AB", Set.empty) []-  )-  [ExpectedLine [LineChunk "StorableArray.fromList (fromList [('A',ZeroBased {",WildCardChunk,LineChunk " 2}),('B',ZeroBased {",WildCardChunk,LineChunk " 3})],fromList []) []"]]- DocTest.printPrefix "Data.Array.Comfort.Storable:410: "-{-# LINE 410 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.property(-{-# LINE 410 "src/Data/Array/Comfort/Storable.hs" #-}-        -   QC.forAll genArray2 $ \block ->-   let height = Map.singleton 'A' $ fst $ Array.shape block in-   let width  = Map.singleton '1' $ snd $ Array.shape block in--   Array.reshape (height,width) block-   QC.===-   Array.fromBlockArray2 height width-      (BoxedArray.replicate (Set.singleton 'A', Set.singleton '1') block)-  )- DocTest.printPrefix "Data.Array.Comfort.Storable:516: "-{-# LINE 516 "src/Data/Array/Comfort/Storable.hs" #-}- DocTest.property(-{-# LINE 516 "src/Data/Array/Comfort/Storable.hs" #-}-      QC.forAll genNonEmptyArray2 $ \xs -> QC.forAll (QC.elements $ Shape.indices $ Array.shape xs) $ \(ix0,ix1) -> Array.pick xs ix0 ! ix1 == xs!(ix0,ix1)-  )- DocTest.printPrefix "Data.Array.Comfort.Storable:534: "-{-# LINE 534 "src/Data/Array/Comfort/Storable.hs" #-}- DocTest.property(-{-# LINE 534 "src/Data/Array/Comfort/Storable.hs" #-}-      QC.forAll genArray2 $ \xs -> xs == Array.fromRowArray (snd $ Array.shape xs) (Array.toRowArray xs)-  )- DocTest.printPrefix "Data.Array.Comfort.Storable:551: "-{-# LINE 551 "src/Data/Array/Comfort/Storable.hs" #-}- DocTest.property(-{-# LINE 551 "src/Data/Array/Comfort/Storable.hs" #-}-      forAllNonEmpty $ \xs -> Array.minimum xs ==? minimum (Array.toList xs)-  )- DocTest.printPrefix "Data.Array.Comfort.Storable:559: "-{-# LINE 559 "src/Data/Array/Comfort/Storable.hs" #-}- DocTest.property(-{-# LINE 559 "src/Data/Array/Comfort/Storable.hs" #-}+{-# LINE 401 "src/Data/Array/Comfort/Storable.hs" #-}       forAllNonEmpty $ \xs -> Array.maximum xs ==? maximum (Array.toList xs)   )- DocTest.printPrefix "Data.Array.Comfort.Storable:571: "-{-# LINE 571 "src/Data/Array/Comfort/Storable.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable:413: "+{-# LINE 413 "src/Data/Array/Comfort/Storable.hs" #-}  DocTest.property(-{-# LINE 571 "src/Data/Array/Comfort/Storable.hs" #-}+{-# LINE 413 "src/Data/Array/Comfort/Storable.hs" #-}       forAllNonEmpty $ \xs -> Array.limits xs ==? (Array.minimum xs, Array.maximum xs)   )
+ test/DocTest/Data/Array/Comfort/Storable/Dim2.hs view
@@ -0,0 +1,308 @@+-- Do not edit! Automatically created with doctest-extract from src/Data/Array/Comfort/Storable/Dim2.hs+{-# LINE 49 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}++module DocTest.Data.Array.Comfort.Storable.Dim2 where++import Test.DocTest.Base+import qualified Test.DocTest.Driver as DocTest++{-# LINE 50 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+import     qualified DocTest.Data.Array.Comfort.Boxed.Unchecked+                                                 as TestBoxedArray+import     DocTest.Data.Array.Comfort.Storable (ShapeInt, shapeInt)++import     qualified Data.Array.Comfort.Boxed as BoxedArray+import     qualified Data.Array.Comfort.Storable.Dim2 as Array2+import     qualified Data.Array.Comfort.Storable as Array+import     qualified Data.Array.Comfort.Shape as Shape+import     Data.Array.Comfort.Storable.Dim2 (Array2, (&===), (&|||))+import     Data.Array.Comfort.Storable (Array, (!))+import     Data.Array.Comfort.Shape ((::+)((::+)))++import     qualified Test.QuickCheck as QC++import     Control.Monad (replicateM)+import     Control.Applicative (liftA2, (<$>), (<*>))++import     qualified Data.Map as Map+import     qualified Data.Set as Set+import     Data.Map (Map)+import     Data.Function.HT (Id)+import     Data.Tuple.HT (swap)+import     Data.Word (Word16)+import     Data.Proxy (Proxy(Proxy))++import     Foreign.Storable (Storable)++genArray2     :: QC.Gen (Array2 ShapeInt ShapeInt Word16)+genArray2     = do+       xs <- QC.arbitrary+       let n = length xs+       (k,m) <-+          if n == 0+             then QC.elements [(,) 0, flip (,) 0] <*> QC.choose (1,20)+             else fmap (\m -> (div n m, m)) $ QC.choose (1,n)+       return $ Array.fromList (Shape.ZeroBased k, Shape.ZeroBased m) xs++genArrayForShape     :: (Shape.C shape) => shape -> QC.Gen (Array shape Word16)+genArrayForShape     sh =+       Array.fromList sh <$> replicateM (Shape.size sh) QC.arbitrary++genNonEmptyArray2     :: QC.Gen (Array2 ShapeInt ShapeInt Word16)+genNonEmptyArray2     = do+       xs <- QC.getNonEmpty <$> QC.arbitrary+       let n = length xs+       m <- QC.choose (1,n)+       return $ Array.fromList (Shape.ZeroBased (div n m), Shape.ZeroBased m) xs+++transpose     ::+       (Shape.Indexed sh0, Shape.Indexed sh1, Storable a) =>+       Array2 sh0 sh1 a -> Array2 sh1 sh0 a+transpose     a = Array.sample (swap $ Array.shape a) (\(i,j) -> a!(j,i))++test :: DocTest.T ()+test = do+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:122: "+{-# LINE 122 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 122 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genNonEmptyArray2 $ \xs ->+   QC.forAll (QC.elements $ Shape.indices $ Array.shape xs) $ \(ix0,ix1) ->+      Array2.takeRow xs ix0 ! ix1 == xs!(ix0,ix1)+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:147: "+{-# LINE 147 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 147 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \xs ->+      xs == Array2.fromRowArray (snd $ Array.shape xs) (Array2.toRowArray xs)+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:168: "+{-# LINE 168 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 168 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \xs ->+   let (Shape.ZeroBased m, width) = Array.shape xs in+   QC.forAll (QC.choose (0, m)) $ \k ->+      let ys = Array.reshape+                  (Shape.ZeroBased k ::+ Shape.ZeroBased (m-k), width) xs in+      ys == Array2.above (Array2.takeTop ys) (Array2.takeBottom ys)+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:193: "+{-# LINE 193 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 193 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \xs ->+   let (height, Shape.ZeroBased n) = Array.shape xs in+   QC.forAll (QC.choose (0, n)) $ \k ->+      let ys = Array.reshape+                  (height, Shape.ZeroBased k ::+ Shape.ZeroBased (n-k)) xs in+      ys == Array2.beside (Array2.takeLeft ys) (Array2.takeRight ys)+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:279: "+{-# LINE 279 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.example(+{-# LINE 279 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+      +   let shapeR0 = shapeInt 2; shapeR1 = shapeInt 3 in+   let shapeC0 = shapeInt 3; shapeC1 = shapeInt 2 in+   let block sh a = Array.replicate sh (a::Word16) in+   Array2.fromBlockArray+      (Map.singleton 'A' shapeR0 <> Map.singleton 'B' shapeR1)+      (Map.singleton '1' shapeC0 <> Map.singleton '2' shapeC1) $+   BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")+      [block (shapeR0,shapeC0) 0, block (shapeR0,shapeC1) 1,+       block (shapeR1,shapeC0) 2, block (shapeR1,shapeC1) 3]+  )+  [ExpectedLine [LineChunk "StorableArray.fromList (fromList [('A',ZeroBased {",WildCardChunk,LineChunk " 2}),('B',ZeroBased {",WildCardChunk,LineChunk " 3})],fromList [('1',ZeroBased {",WildCardChunk,LineChunk " 3}),('2',ZeroBased {",WildCardChunk,LineChunk " 2})]) [0,0,0,1,1,0,0,0,1,1,2,2,2,3,3,2,2,2,3,3,2,2,2,3,3]"]]+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:292: "+{-# LINE 292 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 292 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB2 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB2 in+   let shapeC1 = snd $ Array.shape blockB2 in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   let blocked =+         BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")+            [blockA1, blockA2, blockB1, blockB2] in++   transpose (Array2.fromNonEmptyBlockArray blocked)+   QC.===+   Array2.fromNonEmptyBlockArray+      (TestBoxedArray.transpose (fmap transpose blocked))+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:311: "+{-# LINE 311 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 311 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB2 ->+   QC.forAll genArray2 $ \blockC3 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB2 in+   let shapeC1 = snd $ Array.shape blockB2 in+   let shapeR2 = fst $ Array.shape blockC3 in+   let shapeC2 = snd $ Array.shape blockC3 in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ \blockB3 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ \blockC1 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ \blockC2 ->+   let blocked =+         BoxedArray.fromList (Set.fromList "ABC", Set.fromList "123")+            [blockA1, blockA2, blockA3,+             blockB1, blockB2, blockB3,+             blockC1, blockC2, blockC3] in++   transpose (Array2.fromNonEmptyBlockArray blocked)+   QC.===+   Array2.fromNonEmptyBlockArray+      (TestBoxedArray.transpose (fmap transpose blocked))+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:362: "+{-# LINE 362 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.example(+{-# LINE 362 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+      +   (id :: Id (array (height, Map Char ShapeInt) Word16)) $+   Array2.fromBlockArray+      (Map.singleton 'A' (shapeInt 2) <> Map.singleton 'B' (shapeInt 3))+      Map.empty $+   BoxedArray.fromList (Set.fromList "AB", Set.empty) []+  )+  [ExpectedLine [LineChunk "StorableArray.fromList (fromList [('A',ZeroBased {",WildCardChunk,LineChunk " 2}),('B',ZeroBased {",WildCardChunk,LineChunk " 3})],fromList []) []"]]+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:371: "+{-# LINE 371 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 371 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \block ->+   let height = Map.singleton 'A' $ fst $ Array.shape block in+   let width  = Map.singleton '1' $ snd $ Array.shape block in++   Array.reshape (height,width) block+   QC.===+   Array2.fromBlockArray height width+      (BoxedArray.replicate (Set.singleton 'A', Set.singleton '1') block)+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:484: "+{-# LINE 484 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 484 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB2 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB2 in+   let shapeC1 = snd $ Array.shape blockB2 in+   let shapeR = shapeR0::+shapeR1::+Shape.Zero in+   let shapeC = shapeC0::+shapeC1::+Shape.Zero in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   let blocked =+         BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")+            [blockA1, blockA2, blockB1, blockB2] in++   Array.reshape (shapeR, shapeC)+      (Array2.fromNonEmptyBlockArray blocked)+   QC.===+   Array2.fromBlocks shapeR shapeC Proxy+      blockA1 blockA2+      blockB1 blockB2+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:589: "+{-# LINE 589 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 589 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll genArray2 $ \blockA1 ->+   QC.forAll genArray2 $ \blockB3 ->+   QC.forAll+      (liftA2+         (\char0 char1 -> Shape.Range (min char0 char1) (max char0 char1))+         (QC.choose ('a','k')) (QC.choose ('a','k'))) $+      \shapeC1 ->+   let shapeR0 = fst $ Array.shape blockA1 in+   let shapeC0 = snd $ Array.shape blockA1 in+   let shapeR1 = fst $ Array.shape blockB3 in+   let shapeC2 = snd $ Array.shape blockB3 in+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC1)) $ \blockB2 ->++   Array2.fromBlockMatrix+      (blockA1 &||| Array2.beside blockA2 blockA3+       &===+       blockB1 &||| blockB2 &||| blockB3)+   QC.===+   Array.reshape+      (shapeR0::+shapeR1, shapeC0::+shapeC1::+shapeC2)+      (Array2.fromBlocks+         (shapeR0::+shapeR1::+Shape.Zero)+         (shapeC0::+shapeC1::+shapeC2::+Shape.Zero)+         Proxy+         blockA1 blockA2 blockA3+         blockB1 blockB2 blockB3)+  )+ DocTest.printPrefix "Data.Array.Comfort.Storable.Dim2:621: "+{-# LINE 621 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+ DocTest.property(+{-# LINE 621 "src/Data/Array/Comfort/Storable/Dim2.hs" #-}+        +   QC.forAll+      (liftA2+         (\char0 char1 -> Shape.Range (min char0 char1) (max char0 char1))+         (QC.choose ('a','k')) (QC.choose ('a','k'))) $+      \shapeR0 ->+   QC.forAll+         (liftA2 Shape.Shifted (QC.choose (-10,10)) (QC.choose (0,10::Int))) $+      \shapeR1 ->+   let shapeR2 = () in+   QC.forAll (fmap Shape.ZeroBased (QC.choose (0,10::Int))) $+      \shapeC0 ->+   QC.forAll (fmap Shape.OneBased (QC.choose (0,10::Int))) $+      \shapeC1 ->+   let shapeC2 :: Shape.Enumeration Ordering+       shapeC2 = Shape.Enumeration in++   QC.forAll (genArrayForShape (shapeR0, shapeC0)) $ \blockA1 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ \blockA2 ->+   QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ \blockA3 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ \blockB1 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC1)) $ \blockB2 ->+   QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ \blockB3 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ \blockC1 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ \blockC2 ->+   QC.forAll (genArrayForShape (shapeR2, shapeC2)) $ \blockC3 ->++   Array2.fromBlockMatrix+      (blockA1 &||| blockA2 &||| blockA3+       &===+       blockB1 &||| blockB2 &||| blockB3+       &===+       blockC1 &||| blockC2 &||| blockC3)+   QC.===+   Array2.beside+      (Array2.above blockA1 $ Array2.above blockB1 blockC1)+      (Array2.above+         (Array2.beside blockA2 blockA3)+         (Array2.beside+            (Array2.above blockB2 blockC2)+            (Array2.above blockB3 blockC3)))+  )
test/DocTest/Data/Array/Comfort/Storable/Unchecked.hs view
@@ -1,11 +1,11 @@ -- Do not edit! Automatically created with doctest-extract from src/Data/Array/Comfort/Storable/Unchecked.hs-{-# LINE 57 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 64 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}  module DocTest.Data.Array.Comfort.Storable.Unchecked where  import qualified Test.DocTest.Driver as DocTest -{-# LINE 58 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 65 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-} import     DocTest.Data.Array.Comfort.Storable (ShapeInt, genArray)  import     qualified Data.Array.Comfort.Storable as Array@@ -24,39 +24,39 @@  test :: DocTest.T () test = do- DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:134: "-{-# LINE 134 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:166: "+{-# LINE 166 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}  DocTest.property(-{-# LINE 134 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 166 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}       \x  ->  Array.singleton x ! () == (x::Word16)   )- DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:148: "-{-# LINE 148 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:180: "+{-# LINE 180 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}  DocTest.property(-{-# LINE 148 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 180 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}       \(QC.NonNegative n) (Array16 x)  ->  x == Array.mapShape (Shape.ZeroBased . Shape.size) (Array.append (Array.take n x) (Array.drop n x))   )- DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:163: "-{-# LINE 163 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:195: "+{-# LINE 195 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}  DocTest.property(-{-# LINE 163 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 195 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}       \(Array16 x) (Array16 y) -> let xy = Array.append x y in x == Array.takeLeft xy  &&  y == Array.takeRight xy   )- DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:183: "-{-# LINE 183 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:215: "+{-# LINE 215 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}  DocTest.property(-{-# LINE 183 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 215 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}       \(Array16 x) (Array16 y) (Array16 z) -> let xyz = Array.append x $ Array.append y z in y == Array.takeCenter xyz   )- DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:196: "-{-# LINE 196 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:228: "+{-# LINE 228 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}  DocTest.property(-{-# LINE 196 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 228 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}       \(Array16 xs)  ->  Array.sum xs == sum (Array.toList xs)   )- DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:202: "-{-# LINE 202 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+ DocTest.printPrefix "Data.Array.Comfort.Storable.Unchecked:234: "+{-# LINE 234 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}  DocTest.property(-{-# LINE 202 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}+{-# LINE 234 "src/Data/Array/Comfort/Storable/Unchecked.hs" #-}       \(Array16 xs)  ->  Array.product xs == product (Array.toList xs)   )
test/DocTest/Main.hs view
@@ -2,17 +2,19 @@ module DocTest.Main where  import qualified DocTest.Data.Array.Comfort.Shape-import qualified DocTest.Data.Array.Comfort.Storable import qualified DocTest.Data.Array.Comfort.Storable.Unchecked-import qualified DocTest.Data.Array.Comfort.Boxed+import qualified DocTest.Data.Array.Comfort.Storable+import qualified DocTest.Data.Array.Comfort.Storable.Dim2 import qualified DocTest.Data.Array.Comfort.Boxed.Unchecked+import qualified DocTest.Data.Array.Comfort.Boxed  import qualified Test.DocTest.Driver as DocTest  main :: DocTest.T () main = do     DocTest.Data.Array.Comfort.Shape.test-    DocTest.Data.Array.Comfort.Storable.test     DocTest.Data.Array.Comfort.Storable.Unchecked.test-    DocTest.Data.Array.Comfort.Boxed.test+    DocTest.Data.Array.Comfort.Storable.test+    DocTest.Data.Array.Comfort.Storable.Dim2.test     DocTest.Data.Array.Comfort.Boxed.Unchecked.test+    DocTest.Data.Array.Comfort.Boxed.test