packages feed

comfort-array 0.1.2 → 0.2

raw patch · 13 files changed

+864/−239 lines, 13 filesdep +deepseqdep +non-emptyPVP ok

version bump matches the API change (PVP)

Dependencies added: deepseq, non-empty

API changes (from Hackage documentation)

- Data.Array.Comfort.Storable.Internal: copyIO :: (C sh, Storable a) => Array sh a -> IO (Array sh a)
- Data.Array.Comfort.Storable.Internal: createIO :: (C sh, Storable a) => sh -> (Ptr a -> IO ()) -> IO (Array sh a)
- Data.Array.Comfort.Storable.Internal: createWithSizeAndResultIO :: (C sh, Storable a) => sh -> (Int -> Ptr a -> IO b) -> IO (Array sh a, b)
- Data.Array.Comfort.Storable.Internal: createWithSizeIO :: (C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> IO (Array sh a)
- Data.Array.Comfort.Storable.Internal: fromListIO :: (C sh, Storable a) => sh -> [a] -> IO (Array sh a)
- Data.Array.Comfort.Storable.Internal: instance (Data.Array.Comfort.Shape.C sh, GHC.Show.Show sh, Foreign.Storable.Storable a, GHC.Show.Show a) => GHC.Show.Show (Data.Array.Comfort.Storable.Internal.Array sh a)
- Data.Array.Comfort.Storable.Internal: readIO :: (Indexed sh, Storable a) => Array sh a -> Index sh -> IO a
- Data.Array.Comfort.Storable.Internal: showIO :: (C sh, Show sh, Storable a, Show a) => Array sh a -> IO String
- Data.Array.Comfort.Storable.Internal: toListIO :: (C sh, Storable a) => Array sh a -> IO [a]
- Data.Array.Comfort.Storable.Internal: vectorFromListIO :: (Storable a) => [a] -> IO (Array (ZeroBased Int) a)
+ Data.Array.Comfort.Boxed: (//) :: Indexed sh => Array sh a -> [(Index sh, a)] -> Array sh a
+ Data.Array.Comfort.Boxed: accumulate :: Indexed sh => (a -> b -> a) -> Array sh a -> [(Index sh, b)] -> Array sh a
+ Data.Array.Comfort.Boxed: fromAssociations :: Indexed sh => sh -> a -> [(Index sh, a)] -> Array sh a
+ Data.Array.Comfort.Boxed: toAssociations :: Indexed sh => Array sh a -> [(Index sh, a)]
+ Data.Array.Comfort.Boxed: zipWith :: (C sh, Eq sh) => (a -> b -> c) -> Array sh a -> Array sh b -> Array sh c
+ Data.Array.Comfort.Shape: Deferred :: sh -> Deferred sh
+ Data.Array.Comfort.Shape: Enumeration :: Enumeration n
+ Data.Array.Comfort.Shape: Lower :: Lower
+ Data.Array.Comfort.Shape: Triangular :: part -> size -> Triangular part size
+ Data.Array.Comfort.Shape: Upper :: Upper
+ Data.Array.Comfort.Shape: [triangularPart] :: Triangular part size -> part
+ Data.Array.Comfort.Shape: [triangularSize] :: Triangular part size -> size
+ Data.Array.Comfort.Shape: data DeferredIndex ix
+ Data.Array.Comfort.Shape: data Enumeration n
+ Data.Array.Comfort.Shape: data Lower
+ Data.Array.Comfort.Shape: data Triangular part size
+ Data.Array.Comfort.Shape: data Upper
+ Data.Array.Comfort.Shape: deferIndex :: (Indexed sh, Index sh ~ ix) => sh -> ix -> DeferredIndex ix
+ Data.Array.Comfort.Shape: infixr 5 :+:
+ Data.Array.Comfort.Shape: instance (Control.DeepSeq.NFData sh0, Control.DeepSeq.NFData sh1) => Control.DeepSeq.NFData (sh0 Data.Array.Comfort.Shape.:+: sh1)
+ Data.Array.Comfort.Shape: instance (Data.Array.Comfort.Shape.TriangularPart part, Control.DeepSeq.NFData size) => Control.DeepSeq.NFData (Data.Array.Comfort.Shape.Triangular part size)
+ Data.Array.Comfort.Shape: instance (Data.Array.Comfort.Shape.TriangularPart part, Data.Array.Comfort.Shape.C size) => Data.Array.Comfort.Shape.C (Data.Array.Comfort.Shape.Triangular part size)
+ Data.Array.Comfort.Shape: instance (Data.Array.Comfort.Shape.TriangularPart part, Data.Array.Comfort.Shape.Indexed size) => Data.Array.Comfort.Shape.Indexed (Data.Array.Comfort.Shape.Triangular part size)
+ Data.Array.Comfort.Shape: instance (Data.Array.Comfort.Shape.TriangularPart part, Data.Array.Comfort.Shape.InvIndexed size) => Data.Array.Comfort.Shape.InvIndexed (Data.Array.Comfort.Shape.Triangular part size)
+ Data.Array.Comfort.Shape: instance (GHC.Classes.Eq part, GHC.Classes.Eq size) => GHC.Classes.Eq (Data.Array.Comfort.Shape.Triangular part size)
+ Data.Array.Comfort.Shape: instance (GHC.Enum.Enum n, GHC.Enum.Bounded n) => Data.Array.Comfort.Shape.C (Data.Array.Comfort.Shape.Enumeration n)
+ Data.Array.Comfort.Shape: instance (GHC.Enum.Enum n, GHC.Enum.Bounded n) => Data.Array.Comfort.Shape.Indexed (Data.Array.Comfort.Shape.Enumeration n)
+ Data.Array.Comfort.Shape: instance (GHC.Enum.Enum n, GHC.Enum.Bounded n) => Data.Array.Comfort.Shape.InvIndexed (Data.Array.Comfort.Shape.Enumeration n)
+ Data.Array.Comfort.Shape: instance (GHC.Show.Show part, GHC.Show.Show size) => GHC.Show.Show (Data.Array.Comfort.Shape.Triangular part size)
+ Data.Array.Comfort.Shape: instance Control.DeepSeq.NFData (Data.Array.Comfort.Shape.Enumeration n)
+ Data.Array.Comfort.Shape: instance Control.DeepSeq.NFData n => Control.DeepSeq.NFData (Data.Array.Comfort.Shape.OneBased n)
+ Data.Array.Comfort.Shape: instance Control.DeepSeq.NFData n => Control.DeepSeq.NFData (Data.Array.Comfort.Shape.Range n)
+ Data.Array.Comfort.Shape: instance Control.DeepSeq.NFData n => Control.DeepSeq.NFData (Data.Array.Comfort.Shape.Shifted n)
+ Data.Array.Comfort.Shape: instance Control.DeepSeq.NFData n => Control.DeepSeq.NFData (Data.Array.Comfort.Shape.ZeroBased n)
+ Data.Array.Comfort.Shape: instance Control.DeepSeq.NFData sh => Control.DeepSeq.NFData (Data.Array.Comfort.Shape.Deferred sh)
+ Data.Array.Comfort.Shape: instance Data.Array.Comfort.Shape.C sh => Data.Array.Comfort.Shape.C (Data.Array.Comfort.Shape.Deferred sh)
+ Data.Array.Comfort.Shape: instance Data.Array.Comfort.Shape.C sh => Data.Array.Comfort.Shape.Indexed (Data.Array.Comfort.Shape.Deferred sh)
+ Data.Array.Comfort.Shape: instance Data.Array.Comfort.Shape.C sh => Data.Array.Comfort.Shape.InvIndexed (Data.Array.Comfort.Shape.Deferred sh)
+ Data.Array.Comfort.Shape: instance Data.Array.Comfort.Shape.TriangularPart Data.Array.Comfort.Shape.Lower
+ Data.Array.Comfort.Shape: instance Data.Array.Comfort.Shape.TriangularPart Data.Array.Comfort.Shape.Upper
+ Data.Array.Comfort.Shape: instance Foreign.Storable.Storable (Data.Array.Comfort.Shape.DeferredIndex ix)
+ Data.Array.Comfort.Shape: instance Foreign.Storable.Storable (Data.Array.Comfort.Shape.Enumeration n)
+ Data.Array.Comfort.Shape: instance GHC.Base.Applicative Data.Array.Comfort.Shape.OneBased
+ Data.Array.Comfort.Shape: instance GHC.Base.Applicative Data.Array.Comfort.Shape.ZeroBased
+ Data.Array.Comfort.Shape: instance GHC.Classes.Eq (Data.Array.Comfort.Shape.DeferredIndex ix)
+ Data.Array.Comfort.Shape: instance GHC.Classes.Eq (Data.Array.Comfort.Shape.Enumeration n)
+ Data.Array.Comfort.Shape: instance GHC.Classes.Eq Data.Array.Comfort.Shape.Lower
+ Data.Array.Comfort.Shape: instance GHC.Classes.Eq Data.Array.Comfort.Shape.Upper
+ Data.Array.Comfort.Shape: instance GHC.Classes.Eq sh => GHC.Classes.Eq (Data.Array.Comfort.Shape.Deferred sh)
+ Data.Array.Comfort.Shape: instance GHC.Show.Show (Data.Array.Comfort.Shape.DeferredIndex ix)
+ Data.Array.Comfort.Shape: instance GHC.Show.Show (Data.Array.Comfort.Shape.Enumeration n)
+ Data.Array.Comfort.Shape: instance GHC.Show.Show Data.Array.Comfort.Shape.Lower
+ Data.Array.Comfort.Shape: instance GHC.Show.Show Data.Array.Comfort.Shape.Upper
+ Data.Array.Comfort.Shape: instance GHC.Show.Show sh => GHC.Show.Show (Data.Array.Comfort.Shape.Deferred sh)
+ Data.Array.Comfort.Shape: newtype Deferred sh
+ Data.Array.Comfort.Shape: revealIndex :: (InvIndexed sh, Index sh ~ ix) => sh -> DeferredIndex ix -> ix
+ Data.Array.Comfort.Shape: triangleRoot :: Floating a => a -> a
+ Data.Array.Comfort.Shape: triangleSize :: Int -> Int
+ Data.Array.Comfort.Storable: accumulate :: (Indexed sh, Storable a) => (a -> b -> a) -> Array sh a -> [(Index sh, b)] -> Array sh a
+ Data.Array.Comfort.Storable: fromAssociations :: (Indexed sh, Storable a) => sh -> a -> [(Index sh, a)] -> Array sh a
+ Data.Array.Comfort.Storable: mapShape :: (C sh0, C sh1) => (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
+ Data.Array.Comfort.Storable: mapWithIndex :: (Indexed sh, Index sh ~ ix, Storable a, Storable b) => (ix -> a -> b) -> Array sh a -> Array sh b
+ Data.Array.Comfort.Storable: reshape :: (C sh0, C sh1) => sh1 -> Array sh0 a -> Array sh1 a
+ Data.Array.Comfort.Storable.Internal: accumulate :: (Indexed sh, Storable a) => (a -> b -> a) -> Array sh a -> [(Index sh, b)] -> Array sh a
+ Data.Array.Comfort.Storable.Internal: fromAssociations :: (Indexed sh, Storable a) => sh -> a -> [(Index sh, a)] -> Array sh a
+ Data.Array.Comfort.Storable.Internal: mapWithIndex :: (Indexed sh, Index sh ~ ix, Storable a, Storable b) => (ix -> a -> b) -> Array sh a -> Array sh b
+ Data.Array.Comfort.Storable.Internal.Monadic: unsafeCreate :: (PrimMonad m, C sh, Storable a) => sh -> (Ptr a -> IO ()) -> m (Array sh a)
+ Data.Array.Comfort.Storable.Internal.Monadic: unsafeCreateWithSize :: (PrimMonad m, C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)
+ Data.Array.Comfort.Storable.Internal.Monadic: unsafeCreateWithSizeAndResult :: (PrimMonad m, C sh, Storable a) => sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b)
+ Data.Array.Comfort.Storable.Mutable: fromList :: (PrimMonad m, C sh, Storable a) => sh -> [a] -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable: new :: (PrimMonad m, C sh, Storable a) => sh -> a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable: toList :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m [a]
+ Data.Array.Comfort.Storable.Mutable: type IOArray = Array IO
+ Data.Array.Comfort.Storable.Mutable: type STArray s = Array (ST s)
+ Data.Array.Comfort.Storable.Mutable: update :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> (a -> a) -> m ()
+ Data.Array.Comfort.Storable.Mutable: vectorFromList :: (PrimMonad m, Storable a) => [a] -> m (Array m (ZeroBased Int) a)
+ Data.Array.Comfort.Storable.Mutable.Internal: Array :: sh -> ForeignPtr a -> Array sh a
+ Data.Array.Comfort.Storable.Mutable.Internal: [buffer] :: Array sh a -> ForeignPtr a
+ Data.Array.Comfort.Storable.Mutable.Internal: [shape] :: Array sh a -> sh
+ Data.Array.Comfort.Storable.Mutable.Internal: copy :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: create :: (C sh, Storable a) => sh -> (Ptr a -> IO ()) -> IO (IOArray sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: createWithSize :: (C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> IO (IOArray sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: createWithSizeAndResult :: (C sh, Storable a) => sh -> (Int -> Ptr a -> IO b) -> IO (IOArray sh a, b)
+ Data.Array.Comfort.Storable.Mutable.Internal: data Array (m :: * -> *) sh a
+ Data.Array.Comfort.Storable.Mutable.Internal: freeze :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m (Array sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: fromList :: (PrimMonad m, C sh, Storable a) => sh -> [a] -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: new :: (PrimMonad m, C sh, Storable a) => sh -> a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: read :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> m a
+ Data.Array.Comfort.Storable.Mutable.Internal: thaw :: (PrimMonad m, C sh, Storable a) => Array sh a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: toList :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m [a]
+ Data.Array.Comfort.Storable.Mutable.Internal: type IOArray = Array IO
+ Data.Array.Comfort.Storable.Mutable.Internal: type STArray s = Array (ST s)
+ Data.Array.Comfort.Storable.Mutable.Internal: unsafeCreate :: (PrimMonad m, C sh, Storable a) => sh -> (Ptr a -> IO ()) -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: unsafeCreateWithSize :: (PrimMonad m, C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: unsafeCreateWithSizeAndResult :: (PrimMonad m, C sh, Storable a) => sh -> (Int -> Ptr a -> IO b) -> m (Array m sh a, b)
+ Data.Array.Comfort.Storable.Mutable.Internal: unsafeFreeze :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m (Array sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: unsafeThaw :: (PrimMonad m, C sh, Storable a) => Array sh a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Internal: update :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> (a -> a) -> m ()
+ Data.Array.Comfort.Storable.Mutable.Internal: vectorFromList :: (PrimMonad m, Storable a) => [a] -> m (Array m (ZeroBased Int) a)
+ Data.Array.Comfort.Storable.Mutable.Internal: write :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> a -> m ()
+ Data.Array.Comfort.Storable.Mutable.Private: Array :: sh -> ForeignPtr a -> Array sh a
+ Data.Array.Comfort.Storable.Mutable.Private: [buffer] :: Array sh a -> ForeignPtr a
+ Data.Array.Comfort.Storable.Mutable.Private: [shape] :: Array sh a -> sh
+ Data.Array.Comfort.Storable.Mutable.Private: copy :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Private: create :: (C sh, Storable a) => sh -> (Ptr a -> IO ()) -> IO (IOArray sh a)
+ Data.Array.Comfort.Storable.Mutable.Private: createWithSize :: (C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> IO (IOArray sh a)
+ Data.Array.Comfort.Storable.Mutable.Private: createWithSizeAndResult :: (C sh, Storable a) => sh -> (Int -> Ptr a -> IO b) -> IO (IOArray sh a, b)
+ Data.Array.Comfort.Storable.Mutable.Private: data Array (m :: * -> *) sh a
+ Data.Array.Comfort.Storable.Mutable.Private: fromList :: (PrimMonad m, C sh, Storable a) => sh -> [a] -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Private: new :: (PrimMonad m, C sh, Storable a) => sh -> a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Private: read :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> m a
+ Data.Array.Comfort.Storable.Mutable.Private: show :: (PrimMonad m, C sh, Show sh, Storable a, Show a) => Array m sh a -> m String
+ Data.Array.Comfort.Storable.Mutable.Private: toList :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m [a]
+ Data.Array.Comfort.Storable.Mutable.Private: type IOArray = Array IO
+ Data.Array.Comfort.Storable.Mutable.Private: type STArray s = Array (ST s)
+ Data.Array.Comfort.Storable.Mutable.Private: unsafeArrayIOToPrim :: PrimMonad m => IOArray sh a -> Array m sh a
+ Data.Array.Comfort.Storable.Mutable.Private: unsafeCreate :: (PrimMonad m, C sh, Storable a) => sh -> (Ptr a -> IO ()) -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Private: unsafeCreateWithSize :: (PrimMonad m, C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Mutable.Private: unsafeCreateWithSizeAndResult :: (PrimMonad m, C sh, Storable a) => sh -> (Int -> Ptr a -> IO b) -> m (Array m sh a, b)
+ Data.Array.Comfort.Storable.Mutable.Private: update :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> (a -> a) -> m ()
+ Data.Array.Comfort.Storable.Mutable.Private: vectorFromList :: (PrimMonad m, Storable a) => [a] -> m (Array m (ZeroBased Int) a)
+ Data.Array.Comfort.Storable.Mutable.Private: write :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> a -> m ()
+ Data.Array.Comfort.Storable.Private: (!) :: (Indexed sh, Storable a) => Array sh a -> Index sh -> a
+ Data.Array.Comfort.Storable.Private: (//) :: (Indexed sh, Storable a) => Array sh a -> [(Index sh, a)] -> Array sh a
+ Data.Array.Comfort.Storable.Private: Array :: sh -> ForeignPtr a -> Array sh a
+ Data.Array.Comfort.Storable.Private: [buffer] :: Array sh a -> ForeignPtr a
+ Data.Array.Comfort.Storable.Private: [shape] :: Array sh a -> sh
+ Data.Array.Comfort.Storable.Private: accumulate :: (Indexed sh, Storable a) => (a -> b -> a) -> Array sh a -> [(Index sh, b)] -> Array sh a
+ Data.Array.Comfort.Storable.Private: data Array sh a
+ Data.Array.Comfort.Storable.Private: freeze :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m (Array sh a)
+ Data.Array.Comfort.Storable.Private: fromAssociations :: (Indexed sh, Storable a) => sh -> a -> [(Index sh, a)] -> Array sh a
+ Data.Array.Comfort.Storable.Private: fromList :: (C sh, Storable a) => sh -> [a] -> Array sh a
+ Data.Array.Comfort.Storable.Private: infixl 9 !
+ Data.Array.Comfort.Storable.Private: instance (Data.Array.Comfort.Shape.C sh, GHC.Show.Show sh, Foreign.Storable.Storable a, GHC.Show.Show a) => GHC.Show.Show (Data.Array.Comfort.Storable.Private.Array sh a)
+ Data.Array.Comfort.Storable.Private: instance Control.DeepSeq.NFData sh => Control.DeepSeq.NFData (Data.Array.Comfort.Storable.Private.Array sh a)
+ Data.Array.Comfort.Storable.Private: mapShape :: (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
+ Data.Array.Comfort.Storable.Private: reshape :: sh1 -> Array sh0 a -> Array sh1 a
+ Data.Array.Comfort.Storable.Private: thaw :: (PrimMonad m, C sh, Storable a) => Array sh a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Private: toList :: (C sh, Storable a) => Array sh a -> [a]
+ Data.Array.Comfort.Storable.Private: unsafeFreeze :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m (Array sh a)
+ Data.Array.Comfort.Storable.Private: unsafeThaw :: (PrimMonad m, C sh, Storable a) => Array sh a -> m (Array m sh a)
+ Data.Array.Comfort.Storable.Private: vectorFromList :: Storable a => [a] -> Array (ZeroBased Int) a
- Data.Array.Comfort.Boxed: (!) :: (Indexed sh) => Array sh a -> Index sh -> a
+ Data.Array.Comfort.Boxed: (!) :: Indexed sh => Array sh a -> Index sh -> a
- Data.Array.Comfort.Boxed: fromList :: (C sh) => sh -> [a] -> Array sh a
+ Data.Array.Comfort.Boxed: fromList :: C sh => sh -> [a] -> Array sh a
- Data.Array.Comfort.Boxed: map :: (C sh) => (a -> b) -> Array sh a -> Array sh b
+ Data.Array.Comfort.Boxed: map :: C sh => (a -> b) -> Array sh a -> Array sh b
- Data.Array.Comfort.Boxed: toList :: (C sh) => Array sh a -> [a]
+ Data.Array.Comfort.Boxed: toList :: C sh => Array sh a -> [a]
- Data.Array.Comfort.Shape: data sh0 (:+:) sh1
+ Data.Array.Comfort.Shape: data sh0 :+: sh1
- Data.Array.Comfort.Storable: vectorFromList :: (Storable a) => [a] -> Array (ZeroBased Int) a
+ Data.Array.Comfort.Storable: vectorFromList :: Storable a => [a] -> Array (ZeroBased Int) a
- Data.Array.Comfort.Storable.Internal: vectorFromList :: (Storable a) => [a] -> Array (ZeroBased Int) a
+ Data.Array.Comfort.Storable.Internal: vectorFromList :: Storable a => [a] -> Array (ZeroBased Int) a
- Data.Array.Comfort.Storable.Mutable: data Array sh a
+ Data.Array.Comfort.Storable.Mutable: data Array (m :: * -> *) sh a
- Data.Array.Comfort.Storable.Mutable: freeze :: (Indexed sh, Storable a) => Array sh a -> IO (Array sh a)
+ Data.Array.Comfort.Storable.Mutable: freeze :: (PrimMonad m, C sh, Storable a) => Array m sh a -> m (Array sh a)
- Data.Array.Comfort.Storable.Mutable: read :: (Indexed sh, Storable a) => Array sh a -> Index sh -> IO a
+ Data.Array.Comfort.Storable.Mutable: read :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> m a
- Data.Array.Comfort.Storable.Mutable: shape :: Array sh a -> sh
+ Data.Array.Comfort.Storable.Mutable: shape :: Array m sh a -> sh
- Data.Array.Comfort.Storable.Mutable: thaw :: (Indexed sh, Storable a) => Array sh a -> IO (Array sh a)
+ Data.Array.Comfort.Storable.Mutable: thaw :: (PrimMonad m, C sh, Storable a) => Array sh a -> m (Array m sh a)
- Data.Array.Comfort.Storable.Mutable: write :: (Indexed sh, Storable a) => Array sh a -> Index sh -> a -> IO ()
+ Data.Array.Comfort.Storable.Mutable: write :: (PrimMonad m, Indexed sh, Storable a) => Array m sh a -> Index sh -> a -> m ()

Files

+ Changes.md view
@@ -0,0 +1,20 @@+# Change log for the `comfort-array` package++## 0.2++ * Add a monad parameter to the mutable `Storable` array type+   and generalize functions to `PrimMonad`s.+   This way the mutating functions can also be used in the `ST` monad.++## 0.1.2++ * Add immutable `Boxed` array type and mutable `Storable` array type.++## 0.1++ * Split `Shape.C` into `Shape.C` and `Shape.Indexed`.++## 0.0++ * Initial version featuring the `Shape.C` class with type function `Index`+   and the immutable `Storable` array type.
comfort-array.cabal view
@@ -1,5 +1,5 @@ Name:             comfort-array-Version:          0.1.2+Version:          0.2 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>@@ -51,9 +51,11 @@ Tested-With:      GHC==7.4.2, GHC==7.8.4, GHC==8.2.2 Cabal-Version:    1.14 Build-Type:       Simple+Extra-Source-Files:+  Changes.md  Source-Repository this-  Tag:         0.1.2+  Tag:         0.2   Type:        darcs   Location:    http://hub.darcs.net/thielema/comfort-array/ @@ -66,8 +68,10 @@     primitive >=0.6.4 && <0.7,     guarded-allocation >=0.0 && <0.1,     storable-record >=0.0.1 && <0.1,+    deepseq >=1.3 && <1.5,     QuickCheck >=2 && <3,     transformers >=0.3 && <0.6,+    non-empty >=0.3 && <0.4,     utility-ht >=0.0.10 && <0.1,     base >=4.5 && <5 @@ -79,10 +83,13 @@     Data.Array.Comfort.Shape.Test     Data.Array.Comfort.Storable     Data.Array.Comfort.Storable.Internal+    Data.Array.Comfort.Storable.Internal.Monadic+    Data.Array.Comfort.Storable.Private     Data.Array.Comfort.Storable.Mutable+    Data.Array.Comfort.Storable.Mutable.Internal+    Data.Array.Comfort.Storable.Mutable.Private     Data.Array.Comfort.Boxed   Other-Modules:-    Data.Array.Comfort.Storable.Mutable.Internal     Data.Array.Comfort.Boxed.Internal  Test-Suite comfort-array-test
src/Data/Array/Comfort/Boxed.hs view
@@ -1,16 +1,82 @@-{-# LANGUAGE TypeFamilies #-} module Data.Array.Comfort.Boxed (-   Array.Array,+   Array,    shape,-   (Array.!),+   (!),    Array.toList,+   toAssociations,    Array.fromList,    Array.vectorFromList,     Array.map,+   zipWith,+   (//),+   accumulate,+   fromAssociations,    ) where  import qualified Data.Array.Comfort.Boxed.Internal as Array+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Boxed.Internal (Array(Array)) +import qualified Data.Primitive.Array as Prim++import qualified Control.Monad.Primitive as PrimM+import Control.Monad.ST (runST)+import Control.Applicative ((<$>))++import Data.Foldable (forM_)++import Prelude hiding (zipWith)++ shape :: Array.Array sh a -> sh shape = Array.shape+++infixl 9 !++(!) :: (Shape.Indexed sh) => Array sh a -> Shape.Index sh -> a+(!) (Array sh arr) ix =+   if Shape.inBounds sh ix+      then Prim.indexArray arr $ Shape.offset sh ix+      else error "Array.Comfort.Boxed.!: index out of bounds"+++zipWith ::+   (Shape.C sh, Eq sh) =>+   (a -> b -> c) -> Array sh a -> Array sh b -> Array sh c+zipWith f a b =+   if shape a == shape b+      then Array.zipWith f a b+      else error "zipWith: shapes mismatch"+++(//) ::+   (Shape.Indexed sh) => Array sh a -> [(Shape.Index sh, a)] -> Array sh a+(//) (Array sh arr) xs = runST (do+   marr <- Prim.thawArray arr 0 (Shape.size sh)+   forM_ xs $ \(ix,a) -> Prim.writeArray marr (Shape.offset sh ix) a+   Array sh <$> Prim.unsafeFreezeArray marr)++accumulate ::+   (Shape.Indexed sh) =>+   (a -> b -> a) -> Array sh a -> [(Shape.Index sh, b)] -> Array sh a+accumulate f (Array sh arr) xs = runST (do+   marr <- Prim.thawArray arr 0 (Shape.size sh)+   forM_ xs $ \(ix,b) -> updateArray marr (Shape.offset sh ix) $ flip f b+   Array sh <$> Prim.unsafeFreezeArray marr)++updateArray ::+   PrimM.PrimMonad m =>+   Prim.MutableArray (PrimM.PrimState m) a -> Int -> (a -> a) -> m ()+updateArray marr k f = Prim.writeArray marr k . f =<< Prim.readArray marr k++toAssociations :: (Shape.Indexed sh) => Array sh a -> [(Shape.Index sh, a)]+toAssociations arr = zip (Shape.indices $ shape arr) (Array.toList arr)++fromAssociations ::+   (Shape.Indexed sh) => sh -> a -> [(Shape.Index sh, a)] -> Array sh a+fromAssociations sh a xs = runST (do+   marr <- Prim.newArray (Shape.size sh) a+   forM_ xs $ \(ix,x) -> Prim.writeArray marr (Shape.offset sh ix) x+   Array sh <$> Prim.unsafeFreezeArray marr)
src/Data/Array/Comfort/Boxed/Internal.hs view
@@ -5,7 +5,15 @@ import qualified Data.Primitive.Array as Prim  import qualified Control.Monad.ST.Strict as STStrict+import qualified Control.Monad.Trans.Class as MT+import qualified Control.Monad.Trans.State as MS+import Control.Monad (liftM)+import Control.Applicative ((<$>))+import Control.DeepSeq (NFData, rnf) +import qualified Data.Traversable as Trav+import qualified Data.Foldable as Fold+import qualified Data.List as List import Prelude hiding (map, )  @@ -15,6 +23,33 @@       buffer :: Prim.Array a    } +instance (Shape.C sh, Show sh, Show a) => Show (Array sh a) where+   show arr =+      "BoxedArray.fromList " +++      showsPrec 11 (shape arr) (' ' : show (toListLazy arr))+++instance (Shape.C sh, NFData sh, NFData a) => NFData (Array sh a) where+   rnf a@(Array sh _arr) = rnf (sh, toListLazy a)++instance (Shape.C sh) => Functor (Array sh) where+   fmap = map++instance (Shape.C sh) => Fold.Foldable (Array sh) where+   fold = Fold.fold . buffer+   foldMap f = Fold.foldMap f . buffer+   foldl f a = Fold.foldl f a . buffer+   foldr f a = Fold.foldr f a . buffer+   foldl1 f = Fold.foldl1 f . buffer+   foldr1 f = Fold.foldr1 f . buffer++instance (Shape.C sh) => Trav.Traversable (Array sh) where+   traverse f (Array sh arr) = Array sh <$> Trav.traverse f arr+   sequenceA (Array sh arr) = Array sh <$> Trav.sequenceA arr+   mapM f (Array sh arr) = liftM (Array sh) $ Trav.mapM f arr+   sequence (Array sh arr) = liftM (Array sh) $ Trav.sequence arr++ -- add assertion, at least in an exposed version reshape :: sh1 -> Array sh0 a -> Array sh1 a reshape sh (Array _ arr) = Array sh arr@@ -28,6 +63,10 @@ (!) :: (Shape.Indexed sh) => Array sh a -> Shape.Index sh -> a (!) (Array sh arr) ix = Prim.indexArray arr $ Shape.offset sh ix +toListLazy :: (Shape.C sh) => Array sh a -> [a]+toListLazy (Array sh arr) =+   List.map (Prim.indexArray arr) $ take (Shape.size sh) [0..]+ toList :: (Shape.C sh) => Array sh a -> [a] toList (Array sh arr) =    STStrict.runST (mapM (Prim.indexArrayM arr) $ take (Shape.size sh) [0..])@@ -42,3 +81,17 @@  map :: (Shape.C sh) => (a -> b) -> Array sh a -> Array sh b map f (Array sh arr) = Array sh $ Prim.mapArray' f arr++zipWith ::+   (Shape.C sh) => (a -> b -> c) -> Array sh a -> Array sh b -> Array sh c+zipWith f (Array sha arra) (Array _shb arrb) =+   Array sha $+   STStrict.runST+      (flip MS.evalStateT 0 $+       Prim.traverseArrayP+         (\a -> do+            k <- MS.get+            b <- MT.lift $ Prim.indexArrayM arrb k+            MS.put (k+1)+            return $ f a b)+         arra)
src/Data/Array/Comfort/Shape.hs view
@@ -10,7 +10,11 @@     Range(..),    Shifted(..),+   Enumeration(..),+   Deferred(..), DeferredIndex, deferIndex, revealIndex,+    (:+:)(..),+   Triangular(..), Lower(Lower), Upper(Upper), triangleSize, triangleRoot,    ) where  import qualified Foreign.Storable.Newtype as Store@@ -23,10 +27,14 @@ import qualified Control.Monad.Trans.State as MS import qualified Control.Monad.HT as Monad import qualified Control.Applicative.Backwards as Back-import Control.Applicative (liftA2, liftA3)+import Control.DeepSeq (NFData, rnf)+import Control.Applicative (Applicative, pure, liftA2, liftA3, (<*>))+import Control.Applicative (Const(Const, getConst))  import Text.Printf (printf) +import qualified Data.NonEmpty as NonEmpty+import Data.List.HT (tails) import Data.Tuple.HT (mapFst, mapPair, swap)  @@ -96,6 +104,13 @@ instance Functor ZeroBased where    fmap f (ZeroBased n) = ZeroBased $ f n +instance Applicative ZeroBased where+   pure = ZeroBased+   ZeroBased f <*> ZeroBased n = ZeroBased $ f n++instance (NFData n) => NFData (ZeroBased n) where+   rnf (ZeroBased n) = rnf n+ instance (Storable n) => Storable (ZeroBased n) where    sizeOf = Store.sizeOf zeroBasedSize    alignment = Store.alignment zeroBasedSize@@ -131,6 +146,13 @@ instance Functor OneBased where    fmap f (OneBased n) = OneBased $ f n +instance Applicative OneBased where+   pure = OneBased+   OneBased f <*> OneBased n = OneBased $ f n++instance (NFData n) => NFData (OneBased n) where+   rnf (OneBased n) = rnf n+ instance (Storable n) => Storable (OneBased n) where    sizeOf = Store.sizeOf oneBasedSize    alignment = Store.alignment oneBasedSize@@ -169,6 +191,9 @@ instance Functor Range where    fmap f (Range from to) = Range (f from) (f to) +instance (NFData n) => NFData (Range n) where+   rnf (Range from to) = rnf (from,to)+ instance (Ix.Ix n) => C (Range n) where    size (Range from to) = Ix.rangeSize (from,to)    uncheckedSize (Range from to) = Ix.unsafeRangeSize (from,to)@@ -213,6 +238,9 @@ instance Functor Shifted where    fmap f (Shifted from to) = Shifted (f from) (f to) +instance (NFData n) => NFData (Shifted n) where+   rnf (Shifted from to) = rnf (from,to)+ instance (Integral n) => C (Shifted n) where    size (Shifted _offs len) = fromIntegral len    uncheckedSize (Shifted _offs len) = fromIntegral len@@ -267,6 +295,107 @@   {- |+'Enumeration' denotes a shape of fixed size+that is defined by 'Enum' and 'Bounded' methods.+For correctness it is necessary that the 'Enum' and 'Bounded'+are properly implemented.+Automatically derived instances are fine.+-}+data Enumeration n = Enumeration+   deriving (Eq, Show)++instance NFData (Enumeration n) where+   rnf Enumeration = ()++instance (Enum n, Bounded n) => C (Enumeration n) where+   size = uncheckedSize+   uncheckedSize sh = intFromEnum sh maxBound - intFromEnum sh minBound + 1++instance (Enum n, Bounded n) => Indexed (Enumeration n) where+   type Index (Enumeration n) = n+   indices sh = [asEnumType sh minBound .. asEnumType sh maxBound]+   offset = uncheckedOffset+   uncheckedOffset sh ix = fromEnum ix - intFromEnum sh minBound+   inBounds _sh _ix = True++instance (Enum n, Bounded n) => InvIndexed (Enumeration n) where+   indexFromOffset sh k =+      if 0<=k && k <= intFromEnum sh maxBound - intFromEnum sh minBound+         then uncheckedIndexFromOffset sh k+         else errorIndexFromOffset "Enumeration" k+   uncheckedIndexFromOffset sh k = toEnum $ intFromEnum sh minBound + k++asEnumType :: Enumeration n -> n -> n+asEnumType Enumeration = id++intFromEnum :: (Enum n) => Enumeration n -> n -> Int+intFromEnum Enumeration = fromEnum++instance Storable (Enumeration n) where+   {-# INLINE sizeOf #-}+   {-# INLINE alignment #-}+   {-# INLINE peek #-}+   {-# INLINE poke #-}+   sizeOf ~Enumeration = 0+   alignment ~Enumeration = 1+   poke _p Enumeration = return ()+   peek _p = return Enumeration+++{- |+This data type wraps another array shape.+Its index type is a wrapped 'Int'.+The advantages are:+No conversion forth and back 'Int' and @Index sh@.+You can convert once using 'deferIndex' and 'revealIndex'+whenever you need your application specific index type.+No need for e.g. @Storable (Index sh)@, because 'Int' is already 'Storable'.+-}+newtype Deferred sh = Deferred sh+   deriving (Eq, Show)++newtype DeferredIndex ix = DeferredIndex Int+   deriving (Eq, Show)++instance (NFData sh) => NFData (Deferred sh) where+   rnf (Deferred sh) = rnf sh++instance (C sh) => C (Deferred sh) where+   size (Deferred sh) = size sh+   uncheckedSize (Deferred sh) = uncheckedSize sh++instance (C sh) => Indexed (Deferred sh) where+   type Index (Deferred sh) = DeferredIndex (Index sh)+   indices (Deferred sh) = map DeferredIndex $ take (size sh) [0 ..]+   offset (Deferred sh) (DeferredIndex k) = offset (ZeroBased $ size sh) k+   uncheckedOffset _ (DeferredIndex k) = k+   inBounds (Deferred sh) (DeferredIndex k) =+      inBounds (ZeroBased $ size sh) k++instance (C sh) => InvIndexed (Deferred sh) where+   indexFromOffset sh k =+      DeferredIndex $ indexFromOffset (ZeroBased $ size sh) k+   uncheckedIndexFromOffset _sh = DeferredIndex++deferIndex :: (Indexed sh, Index sh ~ ix) => sh -> ix -> DeferredIndex ix+deferIndex sh ix = DeferredIndex $ offset sh ix++revealIndex :: (InvIndexed sh, Index sh ~ ix) => sh -> DeferredIndex ix -> ix+revealIndex sh (DeferredIndex ix) = indexFromOffset sh ix++instance Storable (DeferredIndex ix) where+   {-# INLINE sizeOf #-}+   {-# INLINE alignment #-}+   {-# INLINE peek #-}+   {-# INLINE poke #-}+   sizeOf (DeferredIndex k) = sizeOf k+   alignment (DeferredIndex k) = alignment k+   poke p (DeferredIndex k) = poke (castPtr p) k+   peek p = fmap DeferredIndex $ peek (castPtr p)++++{- | Row-major composition of two dimensions. -} instance (C sh0, C sh1) => C (sh0,sh1) where@@ -368,10 +497,114 @@   +data Lower = Lower deriving (Eq, Show)+data Upper = Upper deriving (Eq, Show)++class TriangularPart part where+   switchTriangularPart :: f Lower -> f Upper -> f part+instance TriangularPart Lower where switchTriangularPart f _ = f+instance TriangularPart Upper where switchTriangularPart _ f = f++getConstAs :: c -> Const a c -> a+getConstAs _ = getConst++caseTriangularPart :: (TriangularPart part) => part -> a -> a -> a+caseTriangularPart part lo up =+   getConstAs part $ switchTriangularPart (Const lo) (Const up)++data Triangular part size =+   Triangular {+      triangularPart :: part,+      triangularSize :: size+   } deriving (Eq, Show)++-- cf. Data.Bifunctor.Flip+newtype Flip f b a = Flip {getFlip :: f a b}++instance+      (TriangularPart part, NFData size) => NFData (Triangular part size) where+   rnf (Triangular part sz) =+      rnf+         (flip getFlip part $+            switchTriangularPart (Flip $ \Lower -> ()) (Flip $ \Upper -> ()),+          sz)++instance (TriangularPart part, C size) => C (Triangular part size) where+   size (Triangular _part sz) = triangleSize $ size sz+   uncheckedSize (Triangular _part sz) = triangleSize $ uncheckedSize sz++instance+   (TriangularPart part, Indexed size) =>+      Indexed (Triangular part size) where+   type Index (Triangular part size) = (Index size, Index size)++   indices (Triangular part sz) =+      let ixs = indices sz+      in concat $+         caseTriangularPart part+            (zipWith (\cs r -> map ((,) r) cs)+               (NonEmpty.tail $ NonEmpty.inits ixs) ixs)+            (zipWith (\r cs -> map ((,) r) cs) ixs $ tails ixs)++   uncheckedOffset sh ix = snd $ uncheckedSizeOffset sh ix++   sizeOffset sh ix =+      if inBounds sh ix+        then uncheckedSizeOffset sh ix+        else error "Shape.Triangular.sizeOffset: wrong array part"++   uncheckedSizeOffset (Triangular part sz) (rs,cs) =+      let (n,r) = uncheckedSizeOffset sz rs+          c = uncheckedOffset sz cs+      in (triangleSize n,+          caseTriangularPart part+            (triangleSize r + c)+            (triangleSize n - triangleSize (n-r) + c-r))++   inBounds (Triangular part sz) ix@(r,c) =+      inBounds (sz,sz) ix+      &&+      caseTriangularPart part (>=) (<=) (offset sz r) (offset sz c)++instance+   (TriangularPart part, InvIndexed size) =>+      InvIndexed (Triangular part size) where++   indexFromOffset (Triangular part sz) k =+      mapPair (indexFromOffset sz, indexFromOffset sz) $+      caseTriangularPart part+         (let r = floor (triangleRootDouble k)+          in (r, k - triangleSize r))+         (let n = size sz+              triSize = triangleSize n+              rr = ceiling (triangleRootDouble (triSize-k))+              r = n - rr+          in (r, k+r - (triSize - triangleSize rr)))++triangleSize :: Int -> Int+triangleSize n = div (n*(n+1)) 2++{-+n*(n+1)/2 = m+n^2 + n - 2m = 0+n = -1/2 + sqrt(1/4+2m)+  = (sqrt(8m+1) - 1) / 2+-}+triangleRoot :: Floating a => a -> a+triangleRoot sz = (sqrt (8*sz+1)-1)/2++triangleRootDouble :: Int -> Double+triangleRootDouble = triangleRoot . fromIntegral+++ infixr 5 :+:  data sh0:+:sh1 = sh0:+:sh1    deriving (Eq, Show)++instance (NFData sh0, NFData sh1) => NFData (sh0:+:sh1) where+   rnf (sh0:+:sh1) = rnf (sh0,sh1)  instance (C sh0, C sh1) => C (sh0:+:sh1) where    size (sh0:+:sh1) = size sh0 + size sh1
src/Data/Array/Comfort/Storable.hs view
@@ -1,17 +1,85 @@-{-# LANGUAGE TypeFamilies #-} module Data.Array.Comfort.Storable (-   Array.Array,+   Array,    shape,-   (Array.!),+   reshape,+   mapShape,++   (!),    Array.toList,    Array.fromList,    Array.vectorFromList,     Array.map,-   (Array.//),+   Array.mapWithIndex,+   (//),+   accumulate,+   fromAssociations,    ) where +import qualified Data.Array.Comfort.Storable.Mutable.Internal as MutArray import qualified Data.Array.Comfort.Storable.Internal as Array+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Internal (Array) -shape :: Array.Array sh a -> sh+import Foreign.Storable (Storable)++import Control.Monad.ST (runST)++import Data.Foldable (forM_)++import Text.Printf (printf)++import Prelude hiding (map)+++shape :: Array sh a -> sh shape = Array.shape++reshape :: (Shape.C sh0, Shape.C sh1) => sh1 -> Array sh0 a -> Array sh1 a+reshape sh1 arr =+   let n0 = Shape.size $ shape arr+       n1 = Shape.size sh1+   in if n0 == n1+         then Array.reshape sh1 arr+         else error $+              printf+                 ("Array.Comfort.Storable.reshape: " +++                  "different sizes of old (%d) and new (%d) shape")+                 n0 n1++mapShape ::+   (Shape.C sh0, Shape.C sh1) => (sh0 -> sh1) -> Array sh0 a -> Array sh1 a+mapShape f arr = reshape (f $ shape arr) arr+++infixl 9 !++(!) :: (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> a+(!) arr ix = runST (do+   marr <- MutArray.unsafeThaw arr+   MutArray.read marr ix)+++(//) ::+   (Shape.Indexed sh, Storable a) =>+   Array sh a -> [(Shape.Index sh, a)] -> Array sh a+(//) arr xs = runST (do+   marr <- MutArray.thaw arr+   forM_ xs $ uncurry $ MutArray.write marr+   MutArray.unsafeFreeze marr)++accumulate ::+   (Shape.Indexed sh, Storable a) =>+   (a -> b -> a) -> Array sh a -> [(Shape.Index sh, b)] -> Array sh a+accumulate f arr xs = runST (do+   marr <- MutArray.thaw arr+   forM_ xs $ \(ix,b) -> MutArray.update marr ix $ flip f b+   MutArray.unsafeFreeze marr)++fromAssociations ::+   (Shape.Indexed sh, Storable a) =>+   sh -> a -> [(Shape.Index sh, a)] -> Array sh a+fromAssociations sh a xs = runST (do+   marr <- MutArray.new sh a+   forM_ xs $ uncurry $ MutArray.write marr+   MutArray.unsafeFreeze marr)
src/Data/Array/Comfort/Storable/Internal.hs view
@@ -1,90 +1,57 @@ {-# LANGUAGE TypeFamilies #-}+{- |+The functions in this module miss any bound checking.+-} module Data.Array.Comfort.Storable.Internal (-   Array(Array, shape, buffer),-   reshape,-   mapShape,+   Priv.Array(Array, shape, buffer),+   Priv.reshape,+   Priv.mapShape, -   (!),+   (Priv.!),    unsafeCreate,    unsafeCreateWithSize,    unsafeCreateWithSizeAndResult,-   toList,-   fromList,-   vectorFromList,+   Priv.toList,+   Priv.fromList,+   Priv.vectorFromList,     map,-   copyIO,-   (//),--   createIO,-   createWithSizeIO,-   createWithSizeAndResultIO,-   showIO,-   readIO,-   toListIO,-   fromListIO,-   vectorFromListIO,+   mapWithIndex,+   (Priv.//),+   Priv.accumulate,+   Priv.fromAssociations,    ) where +import qualified Data.Array.Comfort.Storable.Internal.Monadic as Monadic+import qualified Data.Array.Comfort.Storable.Private as Priv import qualified Data.Array.Comfort.Shape as Shape--import qualified Foreign.Marshal.Array.Guarded as Alloc-import Foreign.Marshal.Array (copyArray, pokeArray, peekArray, advancePtr, )-import Foreign.Storable (Storable, poke, pokeElemOff, peek, peekElemOff, )-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, )-import Foreign.Ptr (Ptr, )--import System.IO.Unsafe (unsafePerformIO, )--import Control.Applicative ((<$>))--import Data.Tuple.HT (mapFst)--import Prelude hiding (map, readIO, )---data Array sh a =-   Array {-      shape :: sh,-      buffer :: ForeignPtr a-   }+import Data.Array.Comfort.Storable.Private (Array(Array)) -instance (Shape.C sh, Show sh, Storable a, Show a) => Show (Array sh a) where-   show = unsafePerformIO . showIO+import Foreign.Marshal.Array (advancePtr)+import Foreign.Storable (Storable, poke, peek)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Ptr (Ptr) -reshape :: sh1 -> Array sh0 a -> Array sh1 a-reshape sh (Array _ fptr) = Array sh fptr+import Control.Monad.ST (runST) -mapShape :: (sh0 -> sh1) -> Array sh0 a -> Array sh1 a-mapShape f (Array sh fptr) = Array (f sh) fptr+import Prelude hiding (map)  -infixl 9 !- unsafeCreate ::-   (Shape.C sh, Storable a) => sh -> (Ptr a -> IO ()) -> Array sh a-unsafeCreate sh = unsafePerformIO . createIO sh+   (Shape.C sh, Storable a) =>+   sh -> (Ptr a -> IO ()) -> Array sh a+unsafeCreate sh arr = runST (Monadic.unsafeCreate sh arr)  unsafeCreateWithSize ::-   (Shape.C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> Array sh a-unsafeCreateWithSize sh = unsafePerformIO . createWithSizeIO sh+   (Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO ()) -> Array sh a+unsafeCreateWithSize sh arr = runST (Monadic.unsafeCreateWithSize sh arr)  unsafeCreateWithSizeAndResult ::-   (Shape.C sh, Storable a) => sh -> (Int -> Ptr a -> IO b) -> (Array sh a, b)-unsafeCreateWithSizeAndResult sh =-   unsafePerformIO . createWithSizeAndResultIO sh--(!) :: (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> a-(!) arr = unsafePerformIO . readIO arr--toList :: (Shape.C sh, Storable a) => Array sh a -> [a]-toList = unsafePerformIO . toListIO--fromList :: (Shape.C sh, Storable a) => sh -> [a] -> Array sh a-fromList sh = unsafePerformIO . fromListIO sh--vectorFromList :: (Storable a) => [a] -> Array (Shape.ZeroBased Int) a-vectorFromList = unsafePerformIO . vectorFromListIO+   (Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO b) -> (Array sh a, b)+unsafeCreateWithSizeAndResult sh arr =+   runST (Monadic.unsafeCreateWithSizeAndResult sh arr)   map ::@@ -99,61 +66,15 @@          (iterate (flip advancePtr 1) srcPtr)          (iterate (flip advancePtr 1) dstPtr) -copyIO :: (Shape.C sh, Storable a) => Array sh a -> IO (Array sh a)-copyIO (Array sh srcFPtr) =-   withForeignPtr srcFPtr $ \srcPtr ->-   createWithSizeIO sh $ \n dstPtr ->-      copyArray dstPtr srcPtr n--(//) ::-   (Shape.Indexed sh, Storable a) =>-   Array sh a -> [(Shape.Index sh, a)] -> Array sh a-(//) (Array sh fptr) xs =-   unsafeCreateWithSize sh $ \n dstPtr ->-   withForeignPtr fptr $ \srcPtr -> do-      copyArray dstPtr srcPtr n-      mapM_ (\(ix,a) -> pokeElemOff dstPtr (Shape.offset sh ix) a) xs----createIO ::-   (Shape.C sh, Storable a) => sh -> (Ptr a -> IO ()) -> IO (Array sh a)-createIO sh f = createWithSizeIO sh $ const f--createWithSizeIO ::-   (Shape.C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> IO (Array sh a)-createWithSizeIO sh f =-   fst <$> createWithSizeAndResultIO sh f--createWithSizeAndResultIO ::-   (Shape.C sh, Storable a) =>-   sh -> (Int -> Ptr a -> IO b) -> IO (Array sh a, b)-createWithSizeAndResultIO sh f =-   let size = Shape.size sh-   in fmap (mapFst (Array sh)) $ Alloc.create size $ f size--showIO :: (Shape.C sh, Show sh, Storable a, Show a) => Array sh a -> IO String-showIO arr = do-   xs <- toListIO arr-   return $ "fromList " ++ showsPrec 11 (shape arr) (' ' : show xs)--readIO :: (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> IO a-readIO (Array sh fptr) ix =-   withForeignPtr fptr $ flip peekElemOff (Shape.offset sh ix)--toListIO :: (Shape.C sh, Storable a) => Array sh a -> IO [a]-toListIO (Array sh fptr) =-   withForeignPtr fptr $ peekArray (Shape.size sh)--fromListIO ::-   (Shape.C sh, Storable a) =>-   sh -> [a] -> IO (Array sh a)-fromListIO sh xs =-   createWithSizeIO sh $ \size ptr ->-      pokeArray ptr $ take size $-      xs ++-      repeat (error "Array.Comfort.Storable.fromList: list too short for shape")--vectorFromListIO :: (Storable a) => [a] -> IO (Array (Shape.ZeroBased Int) a)-vectorFromListIO xs =-   createIO (Shape.ZeroBased $ length xs) $ flip pokeArray xs+mapWithIndex ::+   (Shape.Indexed sh, Shape.Index sh ~ ix, Storable a, Storable b) =>+   (ix -> a -> b) -> Array sh a -> Array sh b+mapWithIndex f (Array sh a) =+   unsafeCreate sh $ \dstPtr ->+   withForeignPtr a $ \srcPtr ->+   sequence_ $+      zipWith3+         (\ix src dst -> poke dst . f ix =<< peek src)+         (Shape.indices sh)+         (iterate (flip advancePtr 1) srcPtr)+         (iterate (flip advancePtr 1) dstPtr)
+ src/Data/Array/Comfort/Storable/Internal/Monadic.hs view
@@ -0,0 +1,30 @@+module Data.Array.Comfort.Storable.Internal.Monadic where++import qualified Data.Array.Comfort.Storable.Mutable.Private as MutArray+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Private (Array, unsafeFreeze)++import Foreign.Storable (Storable, )+import Foreign.Ptr (Ptr, )++import Control.Monad.Primitive (PrimMonad)+import Control.Monad.HT ((<=<))+++unsafeCreate ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   sh -> (Ptr a -> IO ()) -> m (Array sh a)+unsafeCreate sh = unsafeFreeze <=< MutArray.unsafeCreate sh++unsafeCreateWithSize ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)+unsafeCreateWithSize sh = unsafeFreeze <=< MutArray.unsafeCreateWithSize sh++unsafeCreateWithSizeAndResult ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b)+unsafeCreateWithSizeAndResult sh f = do+   (arr, b) <- MutArray.unsafeCreateWithSizeAndResult sh f+   marr <- unsafeFreeze arr+   return (marr, b)
src/Data/Array/Comfort/Storable/Mutable.hs view
@@ -1,13 +1,67 @@ module Data.Array.Comfort.Storable.Mutable (-   Array.Array,+   Array,+   MutArray.STArray,+   MutArray.IOArray,    shape,-   Array.read,-   Array.write,-   Array.thaw,-   Array.freeze,++   MutArray.new,+   read,+   write,+   update,+   toList,+   fromList,+   vectorFromList,++   MutArray.thaw,+   MutArray.freeze,    ) where -import qualified Data.Array.Comfort.Storable.Mutable.Internal as Array+import qualified Data.Array.Comfort.Storable.Mutable.Internal as MutArray+import qualified Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Storable.Mutable.Internal (Array) -shape :: Array.Array sh a -> sh-shape = Array.shape+import Foreign.Storable (Storable)++import Control.Monad.Primitive (PrimMonad)++import Prelude hiding (read)+++shape :: Array m sh a -> sh+shape = MutArray.shape+++read ::+   (PrimMonad m, Shape.Indexed sh, Storable a) =>+   Array m sh a -> Shape.Index sh -> m a+read arr ix =+   if Shape.inBounds (shape arr) ix+      then MutArray.read arr ix+      else error "Array.Comfort.Storable.Mutable.read: index out of bounds"++write ::+   (PrimMonad m, Shape.Indexed sh, Storable a) =>+   Array m sh a -> Shape.Index sh -> a -> m ()+write arr ix a =+   if Shape.inBounds (shape arr) ix+      then MutArray.write arr ix a+      else error "Array.Comfort.Storable.Mutable.write: index out of bounds"++update ::+   (PrimMonad m, Shape.Indexed sh, Storable a) =>+   Array m sh a -> Shape.Index sh -> (a -> a) -> m ()+update arr ix f =+   if Shape.inBounds (shape arr) ix+      then MutArray.update arr ix f+      else error "Array.Comfort.Storable.Mutable.update: index out of bounds"++toList :: (PrimMonad m, Shape.C sh, Storable a) => Array m sh a -> m [a]+toList = MutArray.toList++fromList ::+   (PrimMonad m, Shape.C sh, Storable a) => sh -> [a] -> m (Array m sh a)+fromList = MutArray.fromList++vectorFromList ::+   (PrimMonad m, Storable a) => [a] -> m (Array m (Shape.ZeroBased Int) a)+vectorFromList = MutArray.vectorFromList
src/Data/Array/Comfort/Storable/Mutable/Internal.hs view
@@ -1,97 +1,28 @@-{-# LANGUAGE TypeFamilies #-}-module Data.Array.Comfort.Storable.Mutable.Internal where--import qualified Data.Array.Comfort.Storable.Internal as Imm-import qualified Data.Array.Comfort.Shape as Shape--import qualified Foreign.Marshal.Array.Guarded as Alloc-import Foreign.Marshal.Array (pokeArray, peekArray, )-import Foreign.Storable (Storable, pokeElemOff, peekElemOff, )-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, )-import Foreign.Ptr (Ptr, )--import System.IO.Unsafe (unsafePerformIO, )--import Control.Applicative ((<$>))-import Control.Monad ((<=<))--import Data.Tuple.HT (mapFst)--import Prelude hiding (map, read, )---data Array sh a =-   Array {-      shape :: sh,-      buffer :: ForeignPtr a-   }--instance (Shape.C sh, Show sh, Storable a, Show a) => Show (Array sh a) where-   show = unsafePerformIO . showIO--reshape :: sh1 -> Array sh0 a -> Array sh1 a-reshape sh (Array _ fptr) = Array sh fptr--mapShape :: (sh0 -> sh1) -> Array sh0 a -> Array sh1 a-mapShape f (Array sh fptr) = Array (f sh) fptr---create ::-   (Shape.C sh, Storable a) => sh -> (Ptr a -> IO ()) -> IO (Array sh a)-create sh f = createWithSize sh $ const f--createWithSize ::-   (Shape.C sh, Storable a) => sh -> (Int -> Ptr a -> IO ()) -> IO (Array sh a)-createWithSize sh f =-   fst <$> createWithSizeAndResult sh f--createWithSizeAndResult ::-   (Shape.C sh, Storable a) =>-   sh -> (Int -> Ptr a -> IO b) -> IO (Array sh a, b)-createWithSizeAndResult sh f =-   let size = Shape.size sh-   in fmap (mapFst (Array sh)) $ Alloc.create size $ f size--showIO :: (Shape.C sh, Show sh, Storable a, Show a) => Array sh a -> IO String-showIO arr = do-   xs <- toList arr-   return $ "fromList " ++ showsPrec 11 (shape arr) (' ' : show xs)--read :: (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> IO a-read (Array sh fptr) ix =-   withForeignPtr fptr $ flip peekElemOff (Shape.offset sh ix)--write ::-   (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> a -> IO ()-write (Array sh fptr) ix a =-   withForeignPtr fptr $ \ptr -> pokeElemOff ptr (Shape.offset sh ix) a--toList :: (Shape.C sh, Storable a) => Array sh a -> IO [a]-toList (Array sh fptr) =-   withForeignPtr fptr $ peekArray (Shape.size sh)--fromList :: (Shape.C sh, Storable a) => sh -> [a] -> IO (Array sh a)-fromList sh xs =-   createWithSize sh $ \size ptr ->-      pokeArray ptr $ take size $-      xs ++-      repeat (error "Array.Comfort.Storable.fromList: list too short for shape")--vectorFromList :: (Storable a) => [a] -> IO (Array (Shape.ZeroBased Int) a)-vectorFromList xs =-   create (Shape.ZeroBased $ length xs) $ flip pokeArray xs---freeze :: (Shape.Indexed sh, Storable a) => Array sh a -> IO (Imm.Array sh a)-freeze = Imm.copyIO <=< unsafeFreeze--thaw :: (Shape.Indexed sh, Storable a) => Imm.Array sh a -> IO (Array sh a)-thaw = unsafeThaw <=< Imm.copyIO+{- |+The functions in this module miss any bound checking.+-}+module Data.Array.Comfort.Storable.Mutable.Internal (+   MutArray.Array(Array, shape, buffer),+   MutArray.STArray,+   MutArray.IOArray,+   MutArray.new,+   MutArray.copy,+   MutArray.create,+   MutArray.createWithSize,+   MutArray.createWithSizeAndResult,+   MutArray.unsafeCreate,+   MutArray.unsafeCreateWithSize,+   MutArray.unsafeCreateWithSizeAndResult,+   MutArray.read,+   MutArray.write,+   MutArray.update,+   MutArray.toList,+   MutArray.fromList,+   MutArray.vectorFromList, -unsafeFreeze ::-   (Shape.Indexed sh, Storable a) => Array sh a -> IO (Imm.Array sh a)-unsafeFreeze (Array sh fptr) = return (Imm.Array sh fptr)+   ImmArray.freeze, ImmArray.unsafeFreeze,+   ImmArray.thaw, ImmArray.unsafeThaw,+   ) where -unsafeThaw ::-   (Shape.Indexed sh, Storable a) => Imm.Array sh a -> IO (Array sh a)-unsafeThaw (Imm.Array sh fptr) = return (Array sh fptr)+import qualified Data.Array.Comfort.Storable.Private as ImmArray+import qualified Data.Array.Comfort.Storable.Mutable.Private as MutArray
+ src/Data/Array/Comfort/Storable/Mutable/Private.hs view
@@ -0,0 +1,131 @@+{-# LANGUAGE TypeFamilies #-}+module Data.Array.Comfort.Storable.Mutable.Private where++import qualified Data.Array.Comfort.Shape as Shape++import qualified Foreign.Marshal.Array.Guarded as Alloc+import Foreign.Marshal.Array (copyArray, pokeArray, peekArray)+import Foreign.Storable (Storable, pokeElemOff, peekElemOff)+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)+import Foreign.Ptr (Ptr)++import Control.Monad.Primitive (PrimMonad, unsafeIOToPrim)+import Control.Monad.ST (ST)+import Control.Monad (liftM)+import Control.Applicative ((<$>))++import Data.Tuple.HT (mapFst)++import qualified Prelude as P+import Prelude hiding (read, show)+++data Array (m :: * -> *) sh a =+   Array {+      shape :: sh,+      buffer :: ForeignPtr a+   }++type STArray s = Array (ST s)+type IOArray = Array IO+++copy ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   Array m sh a -> m (Array m sh a)+copy (Array sh srcFPtr) =+   unsafeCreateWithSize sh $ \n dstPtr ->+   withForeignPtr srcFPtr $ \srcPtr ->+      copyArray dstPtr srcPtr n+++create ::+   (Shape.C sh, Storable a) =>+   sh -> (Ptr a -> IO ()) -> IO (IOArray sh a)+create sh f = createWithSize sh $ const f++createWithSize ::+   (Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO ()) -> IO (IOArray sh a)+createWithSize sh f =+   fst <$> createWithSizeAndResult sh f++createWithSizeAndResult ::+   (Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO b) -> IO (IOArray sh a, b)+createWithSizeAndResult sh f =+   let size = Shape.size sh+   in fmap (mapFst (Array sh)) $ Alloc.create size $ f size+++unsafeCreate ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   sh -> (Ptr a -> IO ()) -> m (Array m sh a)+unsafeCreate sh f = unsafeCreateWithSize sh $ const f++unsafeCreateWithSize ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO ()) -> m (Array m sh a)+unsafeCreateWithSize sh f =+   liftM fst $ unsafeCreateWithSizeAndResult sh f++unsafeCreateWithSizeAndResult ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   sh -> (Int -> Ptr a -> IO b) -> m (Array m sh a, b)+unsafeCreateWithSizeAndResult sh f =+   unsafeIOToPrim $+   fmap (mapFst unsafeArrayIOToPrim) $ createWithSizeAndResult sh f++unsafeArrayIOToPrim :: (PrimMonad m) => IOArray sh a -> Array m sh a+unsafeArrayIOToPrim (Array sh fptr) = Array sh fptr+++show ::+   (PrimMonad m, Shape.C sh, Show sh, Storable a, Show a) =>+   Array m sh a -> m String+show arr = do+   xs <- toList arr+   return $+      "StorableArray.fromList " ++ showsPrec 11 (shape arr) (' ' : P.show xs)++read ::+   (PrimMonad m, Shape.Indexed sh, Storable a) =>+   Array m sh a -> Shape.Index sh -> m a+read (Array sh fptr) ix =+   unsafeIOToPrim $ withForeignPtr fptr $ flip peekElemOff (Shape.offset sh ix)++write ::+   (PrimMonad m, Shape.Indexed sh, Storable a) =>+   Array m sh a -> Shape.Index sh -> a -> m ()+write (Array sh fptr) ix a =+   unsafeIOToPrim $+   withForeignPtr fptr $ \ptr -> pokeElemOff ptr (Shape.offset sh ix) a++update ::+   (PrimMonad m, Shape.Indexed sh, Storable a) =>+   Array m sh a -> Shape.Index sh -> (a -> a) -> m ()+update (Array sh fptr) ix f =+   unsafeIOToPrim $+   let k = Shape.offset sh ix+   in withForeignPtr fptr $ \ptr -> pokeElemOff ptr k . f =<< peekElemOff ptr k++new :: (PrimMonad m, Shape.C sh, Storable a) => sh -> a -> m (Array m sh a)+new sh x =+   unsafeCreateWithSize sh $ \size ptr -> pokeArray ptr $ replicate size x++toList :: (PrimMonad m, Shape.C sh, Storable a) => Array m sh a -> m [a]+toList (Array sh fptr) =+   unsafeIOToPrim $ withForeignPtr fptr $ peekArray (Shape.size sh)++fromList ::+   (PrimMonad m, Shape.C sh, Storable a) => sh -> [a] -> m (Array m sh a)+fromList sh xs =+   unsafeCreateWithSize sh $ \size ptr ->+      pokeArray ptr $ take size $+      xs +++      repeat (error "Array.Comfort.Storable.fromList: list too short for shape")++vectorFromList ::+   (PrimMonad m, Storable a) => [a] -> m (Array m (Shape.ZeroBased Int) a)+vectorFromList xs =+   unsafeCreate (Shape.ZeroBased $ length xs) $ flip pokeArray xs
+ src/Data/Array/Comfort/Storable/Private.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE TypeFamilies #-}+module Data.Array.Comfort.Storable.Private where++import qualified Data.Array.Comfort.Storable.Mutable.Private as MutArray+import qualified Data.Array.Comfort.Shape as Shape++import Foreign.Storable (Storable, )+import Foreign.ForeignPtr (ForeignPtr, )++import Control.DeepSeq (NFData, rnf)+import Control.Monad.Primitive (PrimMonad)+import Control.Monad.ST (runST)+import Control.Monad.HT ((<=<))++import Data.Foldable (forM_)+++data Array sh a =+   Array {+      shape :: sh,+      buffer :: ForeignPtr a+   }++instance (Shape.C sh, Show sh, Storable a, Show a) => Show (Array sh a) where+   show arr = runST (MutArray.show =<< unsafeThaw arr)++instance (NFData sh) => NFData (Array sh a) where+   rnf (Array sh fptr) = seq fptr (rnf sh)++reshape :: sh1 -> Array sh0 a -> Array sh1 a+reshape sh (Array _ fptr) = Array sh fptr++mapShape :: (sh0 -> sh1) -> Array sh0 a -> Array sh1 a+mapShape f arr = reshape (f $ shape arr) arr+++infixl 9 !++(!) :: (Shape.Indexed sh, Storable a) => Array sh a -> Shape.Index sh -> a+(!) arr ix = runST (flip MutArray.read ix =<< unsafeThaw arr)++toList :: (Shape.C sh, Storable a) => Array sh a -> [a]+toList arr = runST (MutArray.toList =<< unsafeThaw arr)++fromList :: (Shape.C sh, Storable a) => sh -> [a] -> Array sh a+fromList sh arr = runST (unsafeFreeze =<< MutArray.fromList sh arr)++vectorFromList :: (Storable a) => [a] -> Array (Shape.ZeroBased Int) a+vectorFromList arr = runST (unsafeFreeze =<< MutArray.vectorFromList arr)+++(//) ::+   (Shape.Indexed sh, Storable a) =>+   Array sh a -> [(Shape.Index sh, a)] -> Array sh a+(//) arr xs = runST (do+   marr <- thaw arr+   forM_ xs $ uncurry $ MutArray.write marr+   unsafeFreeze marr)++accumulate ::+   (Shape.Indexed sh, Storable a) =>+   (a -> b -> a) -> Array sh a -> [(Shape.Index sh, b)] -> Array sh a+accumulate f arr xs = runST (do+   marr <- thaw arr+   forM_ xs $ \(ix,b) -> MutArray.update marr ix $ flip f b+   unsafeFreeze marr)++fromAssociations ::+   (Shape.Indexed sh, Storable a) =>+   sh -> a -> [(Shape.Index sh, a)] -> Array sh a+fromAssociations sh a xs = runST (do+   marr <- MutArray.new sh a+   forM_ xs $ uncurry $ MutArray.write marr+   unsafeFreeze marr)+++freeze ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   MutArray.Array m sh a -> m (Array sh a)+freeze = unsafeFreeze <=< MutArray.copy++thaw ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   Array sh a -> m (MutArray.Array m sh a)+thaw = MutArray.copy <=< unsafeThaw++unsafeFreeze ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   MutArray.Array m sh a -> m (Array sh a)+unsafeFreeze (MutArray.Array sh fptr) = return (Array sh fptr)++unsafeThaw ::+   (PrimMonad m, Shape.C sh, Storable a) =>+   Array sh a -> m (MutArray.Array m sh a)+unsafeThaw (Array sh fptr) = return (MutArray.Array sh fptr)
test/Test/Shape.hs view
@@ -28,6 +28,16 @@       (ShapeTest.tests $        liftA2 Shape.Shifted          (QC.choose (-10,10::Int)) (QC.choose (0,10::Int))) +++   prefix "Enumeration Bool"+      (ShapeTest.tests $+       return (Shape.Enumeration :: Shape.Enumeration Bool)) +++   prefix "Enumeration Ordering"+      (ShapeTest.tests $+       return (Shape.Enumeration :: Shape.Enumeration Ordering)) +++   prefix "Deferred Shifted"+      (ShapeTest.tests $ fmap Shape.Deferred $+       liftA2 Shape.Shifted+         (QC.choose (-10,10::Int)) (QC.choose (0,10::Int))) ++    prefix "Pair"       (ShapeTest.tests $ liftA2 (,) (genZeroBased 10) (genZeroBased 10)) ++    prefix "Triple"@@ -35,4 +45,10 @@        liftA3 (,,) (genZeroBased 10) (genZeroBased 10) (genZeroBased 10)) ++    prefix "Append"       (ShapeTest.tests $ liftA2 (:+:) (genZeroBased 10) (genZeroBased 10)) +++   prefix "Triangular Lower"+      (ShapeTest.tests $+       fmap (Shape.Triangular Shape.Lower) (genZeroBased 10)) +++   prefix "Triangular Upper"+      (ShapeTest.tests $+       fmap (Shape.Triangular Shape.Upper) (genZeroBased 10)) ++    []