-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Massiv (Массив) is an Array Library.
--   
--   Multi-dimensional Arrays with fusion, stencils and parallel
--   computation.
@package massiv
@version 0.2.8.0


module Data.Massiv.Core.Index

-- | Another type synonym for 1-dimensional index, i.e. <a>Int</a> and
--   <a>Ix1T</a>. Provided here purely for consistency.
type Ix1 = Int

-- | This is a very handy pattern synonym to indicate that any arbitrary
--   whole number is an <a>Int</a>, i.e. a 1-dimensional index: <tt>(Ix1 i)
--   == (i :: Int)</tt>
pattern Ix1 :: Int -> Ix1

-- | 2-dimensional index. This also a base index for higher dimensions.
data Ix2
(:.) :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> Ix2
infixr 5 :.

-- | 2-dimensional index constructor. Useful when <tt>TypeOperators</tt>
--   extension isn't enabled, or simply infix notation is inconvenient.
--   <tt>(Ix2 i j) == (i :. j)</tt>.
pattern Ix2 :: Int -> Int -> Ix2

-- | 3-dimensional type synonym. Useful as a alternative to enabling
--   <tt>DataKinds</tt> and using type level Nats.
type Ix3 = IxN 3

-- | 3-dimensional index constructor. <tt>(Ix3 i j k) == (i :&gt; j :.
--   k)</tt>.
pattern Ix3 :: Int -> Int -> Int -> Ix3

-- | 4-dimensional type synonym.
type Ix4 = IxN 4

-- | 4-dimensional index constructor. <tt>(Ix4 i j k l) == (i :&gt; j :&gt;
--   k :. l)</tt>.
pattern Ix4 :: Int -> Int -> Int -> Int -> Ix4

-- | 5-dimensional type synonym.
type Ix5 = IxN 5

-- | 5-dimensional index constructor. <tt>(Ix5 i j k l m) = (i :&gt; j
--   :&gt; k :&gt; l :. m)</tt>.
pattern Ix5 :: Int -> Int -> Int -> Int -> Int -> Ix5

-- | n-dimensional index. Needs a base case, which is the <a>Ix2</a>.
data IxN (n :: Nat)
(:>) :: {-# UNPACK #-} !Int -> !Ix (n - 1) -> IxN
infixr 5 :>

-- | Defines n-dimensional index by relating a general <a>IxN</a> with few
--   base cases.
type family Ix (n :: Nat) = r | r -> n

-- | Convert a <a>Int</a> tuple to <a>Ix2</a>
toIx2 :: Ix2T -> Ix2

-- | Convert an <a>Ix2</a> to <a>Int</a> tuple
fromIx2 :: Ix2 -> Ix2T

-- | Convert a <a>Int</a> 3-tuple to <a>Ix3</a>
toIx3 :: Ix3T -> Ix3

-- | Convert an <a>Ix3</a> to <a>Int</a> 3-tuple
fromIx3 :: Ix3 -> Ix3T

-- | Convert a <a>Int</a> 4-tuple to <a>Ix4</a>
toIx4 :: Ix4T -> Ix4

-- | Convert an <a>Ix4</a> to <a>Int</a> 4-tuple
fromIx4 :: Ix4 -> Ix4T

-- | Convert a <a>Int</a> 5-tuple to <a>Ix5</a>
toIx5 :: Ix5T -> Ix5

-- | Convert an <a>Ix5</a> to <a>Int</a> 5-tuple
fromIx5 :: Ix5 -> Ix5T

-- | Stride provides a way to ignore elements of an array if an index is
--   divisible by a corresponding value in a stride. So, for a <tt>Stride
--   (i :. j)</tt> only elements with indices will be kept around:
--   
--   <pre>
--   ( 0 :. 0) ( 0 :. j) ( 0 :. 2j) ( 0 :. 3j) ...
--   ( i :. 0) ( i :. j) ( i :. 2j) ( i :. 3j) ...
--   (2i :. 0) (2i :. j) (2i :. 2j) (2i :. 3j) ...
--   ...
--   </pre>
--   
--   Only positive strides make sense, so <a>Stride</a> pattern synonym
--   constructor will prevent a user from creating a stride with negative
--   or zero values, thus promoting safety of the library.
--   
--   <h4><b>Examples:</b></h4>
--   
--   <ul>
--   <li>Default and minimal stride of <tt><a>Stride</a> (<a>pureIndex</a>
--   1)</tt> will have no affect and all elements will kept.</li>
--   </ul>
--   
--   <ul>
--   <li>If stride is <tt><a>Stride</a> 2</tt>, then every 2nd element
--   (i.e. with index 1, 3, 5, ..) will be skipped and only elemnts with
--   indices divisible by 2 will be kept around.</li>
--   <li>In case of two dimensions, if what you want is to keep all rows
--   divisible by 5, but keep every column intact then you'd use <tt>Stride
--   (5 :. 1)</tt>.</li>
--   </ul>
data Stride ix

-- | A safe bidirectional pattern synonym for <a>Stride</a> construction
--   that will make sure stride elements are always positive.
pattern Stride :: Index ix => ix -> Stride ix

-- | Just a helper function for unwrapping <a>Stride</a>.
unStride :: Stride ix -> ix

-- | Compute an index with stride using the original size and index
toLinearIndexStride :: Index ix => Stride ix -> ix -> ix -> Int

-- | Adjust strating index according to the stride
strideStart :: Index ix => Stride ix -> ix -> ix

-- | Adjust size according to the stride.
strideSize :: Index ix => Stride ix -> Sz ix -> ix

-- | A default stride of <tt>1</tt>, where all elements are kept
oneStride :: Index ix => Stride ix

-- | Approach to be used near the borders during various transformations.
--   Whenever a function needs information not only about an element of
--   interest, but also about it's neighbors, it will go out of bounds near
--   the array edges, hence is this set of approaches that specify how to
--   handle such situation.
data Border e

-- | Fill in a constant element.
--   
--   <pre>
--              outside |  Array  | outside
--   (<a>Fill</a> 0) : 0 0 0 0 | 1 2 3 4 | 0 0 0 0
--   </pre>
Fill :: e -> Border e

-- | Wrap around from the opposite border of the array.
--   
--   <pre>
--              outside |  Array  | outside
--   <a>Wrap</a> :     1 2 3 4 | 1 2 3 4 | 1 2 3 4
--   </pre>
Wrap :: Border e

-- | Replicate the element at the edge.
--   
--   <pre>
--              outside |  Array  | outside
--   <a>Edge</a> :     1 1 1 1 | 1 2 3 4 | 4 4 4 4
--   </pre>
Edge :: Border e

-- | Mirror like reflection.
--   
--   <pre>
--              outside |  Array  | outside
--   <a>Reflect</a> :  4 3 2 1 | 1 2 3 4 | 4 3 2 1
--   </pre>
Reflect :: Border e

-- | Also mirror like reflection, but without repeating the edge element.
--   
--   <pre>
--              outside |  Array  | outside
--   <a>Continue</a> : 1 4 3 2 | 1 2 3 4 | 3 2 1 4
--   </pre>
Continue :: Border e

-- | Apply a border resolution technique to an index
handleBorderIndex :: Index ix => Border e -> Sz ix -> (ix -> e) -> ix -> e

-- | Helpful type synonym for migrating to newer version <tt>0.3</tt>
type Sz ix = ix

-- | Helpful pattern synonym for migrating to newer version <tt>0.3</tt>
pattern Sz :: ix -> Sz ix
type Sz1 = Sz Int
pattern Sz1 :: Int -> Int

-- | A way to select Array dimension at a value level.
newtype Dim
Dim :: Int -> Dim

-- | A way to select Array dimension at a type level.
data Dimension (n :: Nat)
[Dim1] :: Dimension 1
[Dim2] :: Dimension 2
[Dim3] :: Dimension 3
[Dim4] :: Dimension 4
[Dim5] :: Dimension 5
[DimN] :: (6 <= n, KnownNat n) => Dimension n

-- | A type level constraint that ensures index is indeed valid and that
--   supplied dimension can be safely used with it.
type IsIndexDimension ix n = (1 <= n, n <= Dimensions ix, Index ix, KnownNat n)

-- | Zero-dimension, i.e. a scalar. Can't really be used directly as there
--   are no instances of <a>Index</a> for it, and is included for
--   completeness.
data Ix0
Ix0 :: Ix0

-- | 1-dimensional index. Synonym for <a>Int</a> and <a>Ix1</a>.
type Ix1T = Int

-- | 2-dimensional index as tuple of <a>Int</a>s.
type Ix2T = (Int, Int)

-- | 3-dimensional index as 3-tuple of <a>Int</a>s.
type Ix3T = (Int, Int, Int)

-- | 4-dimensional index as 4-tuple of <a>Int</a>s.
type Ix4T = (Int, Int, Int, Int)

-- | 5-dimensional index as 5-tuple of <a>Int</a>s.
type Ix5T = (Int, Int, Int, Int, Int)

-- | This type family will always point to a type for a dimension that is
--   one lower than the type argument.
type family Lower ix :: *

-- | This is bread and butter of multi-dimensional array indexing. It is
--   unlikely that any of the functions in this class will be useful to a
--   regular user, unless general algorithms are being implemented that do
--   span multiple dimensions.
class (Eq ix, Ord ix, Show ix, NFData ix) => Index ix where {
    type family Dimensions ix :: Nat;
}

-- | Dimensions of an array that has this index type, i.e. what is the
--   dimensionality.
dimensions :: Index ix => ix -> Dim

-- | Total number of elements in an array of this size.
totalElem :: Index ix => Sz ix -> Int

-- | Prepend a dimension to the index
consDim :: Index ix => Int -> Lower ix -> ix

-- | Take a dimension from the index from the outside
unconsDim :: Index ix => ix -> (Int, Lower ix)

-- | Apppend a dimension to the index
snocDim :: Index ix => Lower ix -> Int -> ix

-- | Take a dimension from the index from the inside
unsnocDim :: Index ix => ix -> (Lower ix, Int)

-- | Remove a dimension from the index
dropDim :: Index ix => ix -> Dim -> Maybe (Lower ix)

-- | Pull out value at specified dimension from the index, thus also
--   lowering it dimensionality.
pullOutDim :: Index ix => ix -> Dim -> Maybe (Int, Lower ix)

-- | Insert a dimension into the index
insertDim :: Index ix => Lower ix -> Dim -> Int -> Maybe ix

-- | Extract the value index has at specified dimension.
getDim :: Index ix => ix -> Dim -> Maybe Int

-- | Set the value for an index at specified dimension.
setDim :: Index ix => ix -> Dim -> Int -> Maybe ix

-- | Extract the value index has at specified dimension. To be deprecated.

-- | <i>Deprecated: In favor of <a>getDim</a></i>
getIndex :: Index ix => ix -> Dim -> Maybe Int

-- | Set the value for an index at specified dimension. To be deprecated.

-- | <i>Deprecated: In favor of <a>setDim</a></i>
setIndex :: Index ix => ix -> Dim -> Int -> Maybe ix

-- | Lift an <a>Int</a> to any index by replicating the value as many times
--   as there are dimensions.
pureIndex :: Index ix => Int -> ix

-- | Zip together two indices with a function
liftIndex2 :: Index ix => (Int -> Int -> Int) -> ix -> ix -> ix

-- | Map a function over an index
liftIndex :: Index ix => (Int -> Int) -> ix -> ix
foldlIndex :: Index ix => (a -> Int -> a) -> a -> ix -> a
foldlIndex :: (Index ix, Index (Lower ix)) => (a -> Int -> a) -> a -> ix -> a

-- | Check whether index is within the size.
isSafeIndex :: Index ix => Sz ix -> ix -> Bool

-- | Check whether index is within the size.
isSafeIndex :: (Index ix, Index (Lower ix)) => ix -> ix -> Bool

-- | Convert linear index from size and index
toLinearIndex :: Index ix => Sz ix -> ix -> Int

-- | Convert linear index from size and index
toLinearIndex :: (Index ix, Index (Lower ix)) => ix -> ix -> Int

-- | Convert linear index from size and index with an accumulator.
--   Currently is useless and will likley be removed in future versions.
toLinearIndexAcc :: Index ix => Int -> ix -> ix -> Int

-- | Convert linear index from size and index with an accumulator.
--   Currently is useless and will likley be removed in future versions.
toLinearIndexAcc :: (Index ix, Index (Lower ix)) => Int -> ix -> ix -> Int

-- | Compute an index from size and linear index
fromLinearIndex :: Index ix => Sz ix -> Int -> ix

-- | Compute an index from size and linear index
fromLinearIndex :: (Index ix, Index (Lower ix)) => Sz ix -> Int -> ix

-- | Compute an index from size and linear index using an accumulator, thus
--   trying to optimize for tail recursion while getting the index
--   computed.
fromLinearIndexAcc :: Index ix => Sz ix -> Int -> (Int, ix)

-- | Compute an index from size and linear index using an accumulator, thus
--   trying to optimize for tail recursion while getting the index
--   computed.
fromLinearIndexAcc :: (Index ix, Index (Lower ix)) => Sz ix -> Int -> (Int, ix)

-- | A way to make sure index is withing the bounds for the supplied size.
--   Takes two functions that will be invoked whenever index (2nd arg) is
--   outsize the supplied size (1st arg)
repairIndex :: Index ix => Sz ix -> ix -> (Int -> Int -> Int) -> (Int -> Int -> Int) -> ix

-- | A way to make sure index is withing the bounds for the supplied size.
--   Takes two functions that will be invoked whenever index (2nd arg) is
--   outsize the supplied size (1st arg)
repairIndex :: (Index ix, Index (Lower ix)) => Sz ix -> ix -> (Int -> Int -> Int) -> (Int -> Int -> Int) -> ix

-- | Iterator for the index. Same as <a>iterM</a>, but pure.
iter :: Index ix => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a

-- | This function is what makes it possible to iterate over an array of
--   any dimension.
iterM :: (Index ix, Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a

-- | This function is what makes it possible to iterate over an array of
--   any dimension.
iterM :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a

-- | Same as <a>iterM</a>, but don't bother with accumulator and return
--   value.
iterM_ :: (Index ix, Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()

-- | Same as <a>iterM</a>, but don't bother with accumulator and return
--   value.
iterM_ :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()

-- | Helper function for throwing out of bounds errors
errorIx :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a

-- | Helper function for throwing error when sizes do not match
errorSizeMismatch :: (Show ix, Show ix') => String -> Sz ix -> ix' -> a

-- | Index with all zeros
zeroIndex :: Index ix => ix

-- | Checks whether the size is valid.
--   
--   <b>Note</b> Will be removed in <i>massiv-0.3.0</i>
isSafeSize :: Index ix => Sz ix -> Bool

-- | Checks whether array with this size can hold at least one element.
isNonEmpty :: Index ix => Sz ix -> Bool
headDim :: Index ix => ix -> Int
tailDim :: Index ix => ix -> Lower ix
lastDim :: Index ix => ix -> Int
initDim :: Index ix => ix -> Lower ix

-- | To be deprecated in favor of <a>getDim'</a>.

-- | <i>Deprecated: In favor of <a>getDim'</a></i>
getIndex' :: Index ix => ix -> Dim -> Int

-- | To be deprecated in favor of <a>setDim'</a>.

-- | <i>Deprecated: In favor of <a>setDim'</a></i>
setIndex' :: Index ix => ix -> Dim -> Int -> ix
getDim' :: Index ix => ix -> Dim -> Int
setDim' :: Index ix => ix -> Dim -> Int -> ix
dropDim' :: Index ix => ix -> Dim -> Lower ix
pullOutDim' :: Index ix => ix -> Dim -> (Int, Lower ix)
insertDim' :: Index ix => Lower ix -> Dim -> Int -> ix
fromDimension :: KnownNat n => Dimension n -> Dim

-- | Type safe way to extract value of index at a particular dimension.
getDimension :: IsIndexDimension ix n => ix -> Dimension n -> Int

-- | Type safe way to set value of index at a particular dimension.
setDimension :: IsIndexDimension ix n => ix -> Dimension n -> Int -> ix

-- | Type safe way of dropping a particular dimension, thus lowering index
--   dimensionality.
dropDimension :: IsIndexDimension ix n => ix -> Dimension n -> Lower ix

-- | Type safe way of pulling out a particular dimension, thus lowering
--   index dimensionality and returning the value at specified dimension.
pullOutDimension :: IsIndexDimension ix n => ix -> Dimension n -> (Int, Lower ix)

-- | Type safe way of inserting a particular dimension, thus raising index
--   dimensionality.
insertDimension :: IsIndexDimension ix n => Lower ix -> Dimension n -> Int -> ix

-- | Iterate over N-dimensional space lenarly from start to end in
--   row-major fashion with an accumulator
iterLinearM :: (Index ix, Monad m) => Sz ix -> Int -> Int -> Int -> (Int -> Int -> Bool) -> a -> (Int -> ix -> a -> m a) -> m a

-- | Same as <a>iterLinearM</a>, except without an accumulator.
iterLinearM_ :: (Index ix, Monad m) => Sz ix -> Int -> Int -> Int -> (Int -> Int -> Bool) -> (Int -> ix -> m ()) -> m ()

-- | Efficient loop with an accumulator
loop :: Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> a) -> a

-- | Very efficient monadic loop with an accumulator
loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a

-- | Efficient monadic loop. Result of each iteration is discarded.
loopM_ :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()

-- | Less efficient monadic loop with an accumulator that reverses the
--   direction of action application
loopDeepM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a
splitLinearly :: Int -> Int -> (Int -> Int -> a) -> a
splitLinearlyWith_ :: Monad m => Int -> (m () -> m a) -> Int -> (Int -> b) -> (Int -> b -> m ()) -> m a

-- | Interator tha can be used to split computation jobs
splitLinearlyWithM_ :: Monad m => Int -> (m () -> m a) -> Int -> (Int -> m b) -> (Int -> b -> m c) -> m a
instance GHC.Show.Show e => GHC.Show.Show (Data.Massiv.Core.Index.Border e)
instance GHC.Classes.Eq e => GHC.Classes.Eq (Data.Massiv.Core.Index.Border e)
instance Control.DeepSeq.NFData e => Control.DeepSeq.NFData (Data.Massiv.Core.Index.Border e)


module Data.Massiv.Core.Scheduler
data Scheduler a
numWorkers :: Scheduler a -> Int

-- | Helper function that allows scheduling work to be done in parallel.
--   Use <a>withScheduler</a> to be able to get to a <a>Scheduler</a>.
scheduleWork :: Scheduler a -> IO a -> IO ()

-- | Run arbitrary computations in parallel. A pool of workers is
--   initialized, unless Worker Stations list is empty and a global worker
--   pool is currently available. All of those workers will be stealing
--   work that you can schedule using <a>scheduleWork</a>. The order in
--   which work is scheduled will be the same as the order of the resuts of
--   those computations, stored withing the resulting array. Size of the
--   array, which is also the first element in the returned tuple, will
--   match the number of times <a>scheduleWork</a> has been invoked. This
--   function blocks until all of the submitted jobs has finished or one of
--   them resulted in an exception, which will be re-thrown here.
--   
--   <b>Important</b>: In order to get work done truly in parallel, program
--   needs to be compiled with <tt>-threaded</tt> GHC flag and executed
--   with <tt>+RTS -N</tt>.
withScheduler :: [Int] -> (Scheduler a -> IO b) -> IO (Int, Array a)

-- | Just like <a>withScheduler</a>, but returns computed results in a
--   list, instead of an array.
withScheduler' :: [Int] -> (Scheduler a -> IO b) -> IO [a]

-- | Just like <a>withScheduler</a>, but discards the results.
withScheduler_ :: [Int] -> (Scheduler a -> IO b) -> IO ()

-- | Linearly (row-major first) and equally divide work among available
--   workers. Submit function will receive a <a>Scheduler</a>, length of
--   each chunk, total number of elements, as well as where chunks end and
--   slack begins. Slack work will get picked up by the first worker, that
--   has finished working on his chunk. Returns list with results in the
--   same order that work was submitted
divideWork :: Index ix => [Int] -> ix -> (Scheduler a -> Int -> Int -> Int -> IO b) -> IO [a]

-- | Same as <a>divideWork</a>, but discard the result.
divideWork_ :: Index ix => [Int] -> ix -> (Scheduler a -> Int -> Int -> Int -> IO b) -> IO ()


module Data.Massiv.Core

-- | The array family. Representations <tt>r</tt> describes how data is
--   arranged or computed. All arrays have a common property that each
--   index <tt>ix</tt> always maps to the same unique element, even if that
--   element does not exist in memory and has to be computed upon lookup.
--   Data is always arranged in a nested fasion, depth of which is
--   controlled by <tt><tt>Rank</tt> ix</tt>.
data family Array r ix e :: *
type family Elt r ix e :: *
type family EltRepr r ix :: *

-- | Array types that can be constructed.
class (Typeable r, Index ix) => Construct r ix e

-- | Arrays that can be used as source to practically any manipulation
--   function.
class Size r ix e => Source r ix e

-- | Any array that can be computed
class Size r ix e => Load r ix e

-- | Load an array into memory sequentially
loadS :: (Load r ix e, Monad m) => Array r ix e -> (Int -> m e) -> (Int -> e -> m ()) -> m ()

-- | Load an array into memory in parallel
loadP :: Load r ix e => [Int] -> Array r ix e -> (Int -> IO e) -> (Int -> e -> IO ()) -> IO ()

-- | Load an array into memory with stride. Default implementation can only
--   handle the sequential case and only if there is an instance of
--   <a>Source</a>.
loadArrayWithStride :: (Load r ix e, Monad m) => Int -> (m () -> m ()) -> Stride ix -> Sz ix -> Array r ix e -> (Int -> m e) -> (Int -> e -> m ()) -> m ()

-- | Load an array into memory with stride. Default implementation can only
--   handle the sequential case and only if there is an instance of
--   <a>Source</a>.
loadArrayWithStride :: (Load r ix e, Source r ix e, Monad m) => Int -> (m () -> m ()) -> Stride ix -> Sz ix -> Array r ix e -> (Int -> m e) -> (Int -> e -> m ()) -> m ()

-- | Load an array into memory. Default implementation will respect the
--   scheduler and use <a>Source</a> instance to do loading in row-major
--   fashion in parallel as well as sequentially.
loadArray :: (Load r ix e, Monad m) => Int -> (m () -> m ()) -> Array r ix e -> (Int -> m e) -> (Int -> e -> m ()) -> m ()

-- | Load an array into memory. Default implementation will respect the
--   scheduler and use <a>Source</a> instance to do loading in row-major
--   fashion in parallel as well as sequentially.
loadArray :: (Load r ix e, Source r ix e, Monad m) => Int -> (m () -> m ()) -> Array r ix e -> (Int -> m e) -> (Int -> e -> m ()) -> m ()

-- | An array that contains size information. They can be resized and new
--   arrays extracted from it in constant time.
class Construct r ix e => Size r ix e
class Size r ix e => Slice r ix e
class OuterSlice r ix e
outerLength :: OuterSlice r ix e => Array r ix e -> Int
outerLength :: (OuterSlice r ix e, Size r ix e) => Array r ix e -> Int
class Size r ix e => InnerSlice r ix e

-- | Manifest arrays are backed by actual memory and values are looked up
--   versus computed as it is with delayed arrays. Because of this fact
--   indexing functions <tt>(<a>!</a>)</tt>, <tt>(<a>!?</a>)</tt>, etc. are
--   constrained to manifest arrays only.
class Source r ix e => Manifest r ix e
class Manifest r ix e => Mutable r ix e
class Construct r ix e => Ragged r ix e
empty :: Ragged r ix e => Comp -> Array r ix e
isNull :: Ragged r ix e => Array r ix e -> Bool
cons :: Ragged r ix e => Elt r ix e -> Array r ix e -> Array r ix e
uncons :: Ragged r ix e => Array r ix e -> Maybe (Elt r ix e, Array r ix e)
edgeSize :: Ragged r ix e => Array r ix e -> Sz ix
flatten :: Ragged r ix e => Array r ix e -> Array r Ix1 e
loadRagged :: Ragged r ix e => (IO () -> IO ()) -> (Int -> e -> IO a) -> Int -> Int -> ix -> Array r ix e -> IO ()
raggedFormat :: Ragged r ix e => (e -> String) -> String -> Array r ix e -> String
class Nested r ix e
fromNested :: Nested r ix e => NestedStruct r ix e -> Array r ix e
toNested :: Nested r ix e => Array r ix e -> NestedStruct r ix e
type family NestedStruct r ix e :: *
data L
L :: L
data LN
type family ListItem ix e :: *

-- | Computation type to use.
data Comp

-- | Sequential computation
Seq :: Comp

-- | Use <a>Par</a> instead to use your CPU to the fullest. Also don't
--   forget to compile the program with <tt>-threaded</tt> flag.
--   
--   Parallel computation with a list of capabilities to run computation
--   on. Specifying an empty list (<tt>ParOn []</tt>) or using <a>Par</a>
--   will result in utilization of all available capabilities, which are
--   set at runtime by <tt>+RTS -Nx</tt> or at compile time by GHC flag
--   <tt>-with-rtsopts=-Nx</tt>, where <tt>x</tt> is the number of
--   capabilities. Ommiting <tt>x</tt> in above flags defaults to number
--   available cores.
ParOn :: [Int] -> Comp

-- | Parallel computation using all available cores.
pattern Par :: Comp

-- | Parallel computation using all available cores.
pattern Par :: Comp


module Data.Massiv.Array.Unsafe

-- | Construct an array. No size validation is performed.
unsafeMakeArray :: Construct r ix e => Comp -> Sz ix -> (ix -> e) -> Array r ix e

-- | Create an array sequentially using mutable interface
unsafeGenerateArray :: Mutable r ix e => Sz ix -> (ix -> e) -> Array r ix e

-- | Create an array in parallel using mutable interface
unsafeGenerateArrayP :: Mutable r ix e => [Int] -> Sz ix -> (ix -> e) -> Array r ix e
unsafeGenerateM :: (Ragged r ix e, Monad m) => Comp -> Sz ix -> (ix -> m e) -> m (Array r ix e)

-- | Lookup element in the array. No bounds check is performed and access
--   of arbitrary memory is possible when invalid index is supplied.
unsafeIndex :: Source r ix e => Array r ix e -> ix -> e

-- | Lookup element in the array using flat index in a row-major fasion. No
--   bounds check is performed
unsafeLinearIndex :: Source r ix e => Array r ix e -> Int -> e
unsafeLinearIndexM :: Manifest r ix e => Array r ix e -> Int -> e
unsafeBackpermute :: (Source r' ix' e, Index ix) => Sz ix -> (ix -> ix') -> Array r' ix' e -> Array D ix e
unsafeTraverse :: (Source r1 ix1 e1, Index ix) => Sz ix -> ((ix1 -> e1) -> ix -> e) -> Array r1 ix1 e1 -> Array D ix e
unsafeTraverse2 :: (Source r1 ix1 e1, Source r2 ix2 e2, Index ix) => Sz ix -> ((ix1 -> e1) -> (ix2 -> e2) -> ix -> e) -> Array r1 ix1 e1 -> Array r2 ix2 e2 -> Array D ix e

-- | <i>O(1)</i> - Change the size of an array. New size is not validated.
unsafeResize :: (Size r ix e, Index ix') => Sz ix' -> Array r ix e -> Array r ix' e

-- | <i>O(1)</i> - Extract a portion of an array. Staring index and new
--   size are not validated.
unsafeExtract :: Size r ix e => ix -> Sz ix -> Array r ix e -> Array (EltRepr r ix) ix e
unsafeSlice :: Slice r ix e => Array r ix e -> ix -> Sz ix -> Dim -> Maybe (Elt r ix e)

-- | <i>O(1)</i> - Take a slice out of an array from the outside
unsafeOuterSlice :: OuterSlice r ix e => Array r ix e -> Int -> Elt r ix e
unsafeInnerSlice :: InnerSlice r ix e => Array r ix e -> (Sz (Lower ix), Sz1) -> Int -> Elt r ix e
unsafeThaw :: (Mutable r ix e, PrimMonad m) => Array r ix e -> m (MArray (PrimState m) r ix e)
unsafeFreeze :: (Mutable r ix e, PrimMonad m) => Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)

-- | Create new mutable array, leaving it's elements uninitialized. Size
--   isn't validated either.
unsafeNew :: (Mutable r ix e, PrimMonad m) => Sz ix -> m (MArray (PrimState m) r ix e)

-- | Create new mutable array, leaving it's elements uninitialized. Size
--   isn't validated either.
unsafeNewZero :: (Mutable r ix e, PrimMonad m) => Sz ix -> m (MArray (PrimState m) r ix e)

-- | Read an array element
unsafeRead :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> m e
unsafeLinearRead :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> Int -> m e

-- | Write an element into array
unsafeWrite :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> e -> m ()
unsafeLinearWrite :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> Int -> e -> m ()


module Data.Massiv.Array.Mutable

-- | <i>O(1)</i> - Lookup an element in the mutable array. Return
--   <a>Nothing</a> when index is out of bounds.
read :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> m (Maybe e)

-- | <i>O(1)</i> - Same as <a>read</a>, but throws an error if index is out
--   of bounds.
read' :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> m e

-- | <i>O(1)</i> - Write an element into the cell of a mutable array.
--   Returns <a>False</a> when index is out of bounds.
write :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> e -> m Bool

-- | <i>O(1)</i> - Same as <a>write</a>, but throws an error if index is
--   out of bounds.
write' :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> e -> m ()

-- | <i>O(1)</i> - Modify an element in the cell of a mutable array with a
--   supplied function. Returns <a>False</a> when index is out of bounds.
modify :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> (e -> e) -> ix -> m Bool

-- | <i>O(1)</i> - Same as <a>modify</a>, but throws an error if index is
--   out of bounds.
modify' :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> (e -> e) -> ix -> m ()

-- | <i>O(1)</i> - Swap two elements in a mutable array by supplying their
--   indices. Returns <a>False</a> when either one of the indices is out of
--   bounds.
swap :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> ix -> m Bool

-- | <i>O(1)</i> - Same as <a>swap</a>, but throws an error if index is out
--   of bounds.
swap' :: (Mutable r ix e, PrimMonad m) => MArray (PrimState m) r ix e -> ix -> ix -> m ()
class Manifest r ix e => Mutable r ix e
data family MArray s r ix e :: *

-- | Get the size of a mutable array.
msize :: Mutable r ix e => MArray s r ix e -> Sz ix

-- | Initialize a new mutable array. Negative size will result in an empty
--   array.
new :: (Mutable r ix e, PrimMonad m) => Sz ix -> m (MArray (PrimState m) r ix e)

-- | <i>O(n)</i> - Yield a mutable copy of the immutable array
thaw :: (Mutable r ix e, PrimMonad m) => Array r ix e -> m (MArray (PrimState m) r ix e)

-- | <i>O(n)</i> - Yield an immutable copy of the mutable array
freeze :: (Mutable r ix e, PrimMonad m) => Comp -> MArray (PrimState m) r ix e -> m (Array r ix e)

-- | Create a new array by supplying an action that will fill the new blank
--   mutable array. Use <a>createArray</a> if you'd like to keep the result
--   of the filling function.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; createArray_ Seq (Sz1 2) (\ marr -&gt; write marr 0 10 &gt;&gt; write marr 1 11) :: IO (Array P Ix1 Int)
--   (Array P Seq (2)
--     [ 10,11 ])
--   </pre>
createArray_ :: (Mutable r ix e, PrimMonad m) => Comp -> Sz ix -> (MArray (PrimState m) r ix e -> m a) -> m (Array r ix e)

-- | Just like <a>createArray_</a>, but together with <a>Array</a> it
--   returns the result of the filling action.
createArray :: (Mutable r ix e, PrimMonad m) => Comp -> Sz ix -> (MArray (PrimState m) r ix e -> m a) -> m (a, Array r ix e)

-- | Just like <a>createArray_</a>, but restricted to <a>ST</a>.
createArrayST_ :: Mutable r ix e => Comp -> Sz ix -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e

-- | Just like <a>createArray</a>, but restricted to <a>ST</a>.
createArrayST :: Mutable r ix e => Comp -> Sz ix -> (forall s. MArray s r ix e -> ST s a) -> (a, Array r ix e)

-- | Sequentially generate a pure array. Much like <a>makeArray</a> creates
--   a pure array this function will use <a>Mutable</a> interface to
--   generate a pure <a>Array</a> in the end, except that computation
--   strategy is ignored. Element producing function no longer has to be
--   pure but is a stateful action, since it is restricted to
--   <a>PrimMonad</a> and allows for sharing the state between computation
--   of each element, which could be arbitrary effects if that monad is
--   <a>IO</a>.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; import Data.IORef
--   
--   &gt;&gt;&gt; ref &lt;- newIORef (0 :: Int)
--   
--   &gt;&gt;&gt; generateArray Seq (Sz1 6) (\ i -&gt; modifyIORef' ref (+i) &gt;&gt; print i &gt;&gt; pure i) :: IO (Array U Ix1 Int)
--   0
--   1
--   2
--   3
--   4
--   5
--   (Array U Seq (6)
--     [ 0,1,2,3,4,5 ])
--   
--   &gt;&gt;&gt; readIORef ref
--   15
--   </pre>
generateArray :: (Mutable r ix e, PrimMonad m) => Comp -> Sz ix -> (ix -> m e) -> m (Array r ix e)

-- | Just like <a>generateArray</a>, except this generator <b>will</b>
--   respect the supplied computation strategy, and for that reason it is
--   restricted to <a>IO</a>.
generateArrayIO :: Mutable r ix e => Comp -> Sz ix -> (ix -> IO e) -> IO (Array r ix e)

-- | Sequentially unfold an array from the left.
--   
--   <h4><b>Examples</b></h4>
--   
--   Create an array with Fibonacci numbers while performing and <a>IO</a>
--   action on the accumulator for each element of the array.
--   
--   <pre>
--   &gt;&gt;&gt; unfoldlPrim_ Seq  (Ix1 10) (\a@(f0, f1) _ -&gt; let fn = f0 + f1 in print a &gt;&gt; return ((f1, fn), f0)) (0, 1) :: IO (Array P Ix1 Int)
--   (0,1)
--   (1,1)
--   (1,2)
--   (2,3)
--   (3,5)
--   (5,8)
--   (8,13)
--   (13,21)
--   (21,34)
--   (34,55)
--   (Array P Seq (10)
--     [ 0,1,1,2,3,5,8,13,21,34 ])
--   </pre>
unfoldlPrim_ :: (Mutable r ix e, PrimMonad m) => Comp -> Sz ix -> (a -> ix -> m (a, e)) -> a -> m (Array r ix e)

-- | Just like <a>unfoldlPrim_</a>, but also returns the final value of the
--   accumulator.
unfoldlPrim :: (Mutable r ix e, PrimMonad m) => Comp -> Sz ix -> (a -> ix -> m (a, e)) -> a -> m (a, Array r ix e)

-- | Create a copy of a pure array, mutate it in place and return its
--   frozen version.
withMArray :: (Mutable r ix e, PrimMonad m) => Array r ix e -> (MArray (PrimState m) r ix e -> m a) -> m (Array r ix e)

-- | Same as <a>withMArray</a> but in <a>ST</a>.
withMArrayST :: Mutable r ix e => Array r ix e -> (forall s. MArray s r ix e -> ST s a) -> Array r ix e

-- | <tt>RealWorld</tt> is deeply magical. It is <i>primitive</i>, but it
--   is not <i>unlifted</i> (hence <tt>ptrArg</tt>). We never manipulate
--   values of type <tt>RealWorld</tt>; it's only used in the type system,
--   to parameterise <tt>State#</tt>.
data RealWorld :: Type

-- | Compute an Array while loading the results into the supplied mutable
--   target array. Sizes of both arrays must agree, otherwise error.
computeInto :: (Load r' ix e, Mutable r ix e) => MArray RealWorld r ix e -> Array r' ix e -> IO ()


module Data.Massiv.Array.Numeric
(.+) :: (Source r1 ix e, Source r2 ix e, Num e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 6 .+
(.-) :: (Source r1 ix e, Source r2 ix e, Num e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 6 .-
(.*) :: (Source r1 ix e, Source r2 ix e, Num e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 7 .*
(.^) :: (Source r ix e, Num e, Integral b) => Array r ix e -> b -> Array D ix e
infixr 8 .^

-- | Perform matrix multiplication. Inner dimensions must agree, otherwise
--   error.
(|*|) :: (Mutable r Ix2 e, Source r' Ix2 e, OuterSlice r Ix2 e, Source (EltRepr r Ix2) Ix1 e, Num e) => Array r Ix2 e -> Array r' Ix2 e -> Array r Ix2 e

-- | It is quite often that second matrix gets transposed before
--   multiplication (eg. A * A'), but due to layout of data in memory it is
--   more efficient to transpose the second array again.
multiplyTransposed :: (Manifest r Ix2 e, OuterSlice r Ix2 e, Source (EltRepr r Ix2) Ix1 e, Num e) => Array r Ix2 e -> Array r Ix2 e -> Array D Ix2 e
negateA :: (Source r ix e, Num e) => Array r ix e -> Array D ix e
absA :: (Source r ix e, Num e) => Array r ix e -> Array D ix e
signumA :: (Source r ix e, Num e) => Array r ix e -> Array D ix e
fromIntegerA :: (Index ix, Num e) => Integer -> Array D ix e
quotA :: (Source r1 ix e, Source r2 ix e, Integral e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 7 `quotA`
remA :: (Source r1 ix e, Source r2 ix e, Integral e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 7 `remA`
divA :: (Source r1 ix e, Source r2 ix e, Integral e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 7 `divA`
modA :: (Source r1 ix e, Source r2 ix e, Integral e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 7 `modA`
quotRemA :: (Source r1 ix e, Source r2 ix e, Integral e) => Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)
divModA :: (Source r1 ix e, Source r2 ix e, Integral e) => Array r1 ix e -> Array r2 ix e -> (Array D ix e, Array D ix e)
(./) :: (Source r1 ix e, Source r2 ix e, Fractional e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
infixl 7 ./
(.^^) :: (Source r ix e, Fractional e, Integral b) => Array r ix e -> b -> Array D ix e
infixr 8 .^^
recipA :: (Source r ix e, Fractional e) => Array r ix e -> Array D ix e
fromRationalA :: (Index ix, Fractional e) => Rational -> Array D ix e
piA :: (Index ix, Floating e) => Array D ix e
expA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
logA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
sqrtA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
(.**) :: (Source r1 ix e, Source r2 ix e, Floating e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
logBaseA :: (Source r1 ix e, Source r2 ix e, Floating e) => Array r1 ix e -> Array r2 ix e -> Array D ix e
sinA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
cosA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
tanA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
asinA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
acosA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
atanA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
sinhA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
coshA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
tanhA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
asinhA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
acoshA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
atanhA :: (Source r ix e, Floating e) => Array r ix e -> Array D ix e
truncateA :: (Source r ix a, RealFrac a, Integral b) => Array r ix a -> Array D ix b
roundA :: (Source r ix a, RealFrac a, Integral b) => Array r ix a -> Array D ix b
ceilingA :: (Source r ix a, RealFrac a, Integral b) => Array r ix a -> Array D ix b
floorA :: (Source r ix a, RealFrac a, Integral b) => Array r ix a -> Array D ix b
atan2A :: (Source r ix e, RealFloat e) => Array r ix e -> Array r ix e -> Array D ix e


module Data.Massiv.Array.Manifest.Vector

-- | In case when resulting array representation matches the one of
--   vector's it will do a <i>O(1)</i> - conversion using
--   <a>castFromVector</a>, otherwise Vector elements will be copied into a
--   new array. Will throw an error if length of resulting array doesn't
--   match the source vector length.
fromVector :: (Typeable v, Vector v a, Mutable (ARepr v) ix a, Mutable r ix a) => Comp -> Sz ix -> v a -> Array r ix a

-- | <i>O(1)</i> - conversion from vector to an array with a corresponding
--   representation. Will return <a>Nothing</a> if there is a size
--   mismatch, vector has been sliced before or if some non-standard vector
--   type is supplied.
castFromVector :: forall v r ix e. (Vector v e, Typeable v, Mutable r ix e, ARepr v ~ r) => Comp -> Sz ix -> v e -> Maybe (Array r ix e)

-- | Convert an array into a vector. Will perform a cast if resulting
--   vector is of compatible representation, otherwise memory copy will
--   occur.
--   
--   <h4><b>Examples</b></h4>
--   
--   In this example a <a>S</a>torable Array is created and then casted
--   into a Storable <a>Vector</a> in costant time:
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Data.Vector.Storable as VS
--   
--   &gt;&gt;&gt; toVector (makeArrayR S Par (5 :. 6) (\(i :. j) -&gt; i + j)) :: VS.Vector Int
--   [0,1,2,3,4,5,1,2,3,4,5,6,2,3,4,5,6,7,3,4,5,6,7,8,4,5,6,7,8,9]
--   </pre>
--   
--   While in this example <a>S</a>torable Array will first be converted
--   into <a>U</a>nboxed representation in <a>Par</a>allel and only after
--   that will be coverted into Unboxed <a>Vector</a> in constant time.
--   
--   <pre>
--   &gt;&gt;&gt; import qualified Data.Vector.Unboxed as VU
--   
--   &gt;&gt;&gt; toVector (makeArrayR S Par (5 :. 6) (\(i :. j) -&gt; i + j)) :: VU.Vector Int
--   [0,1,2,3,4,5,1,2,3,4,5,6,2,3,4,5,6,7,3,4,5,6,7,8,4,5,6,7,8,9]
--   </pre>
toVector :: forall r ix e v. (Manifest r ix e, Mutable (ARepr v) ix e, Vector v e, VRepr (ARepr v) ~ v) => Array r ix e -> v e

-- | <i>O(1)</i> - conversion from <a>Mutable</a> array to a corresponding
--   vector. Will return <a>Nothing</a> only if source array representation
--   was not one of <a>B</a>, <a>N</a>, <a>P</a>, <a>S</a> or <a>U</a>.
castToVector :: forall v r ix e. (Vector v e, Mutable r ix e, VRepr r ~ v) => Array r ix e -> Maybe (v e)

-- | Match vector type to array representation
type family ARepr (v :: * -> *) :: *

-- | Match array representation to a vector type
type family VRepr r :: * -> *


module Data.Massiv.Array.Manifest

-- | Manifest arrays are backed by actual memory and values are looked up
--   versus computed as it is with delayed arrays. Because of this fact
--   indexing functions <tt>(<a>!</a>)</tt>, <tt>(<a>!?</a>)</tt>, etc. are
--   constrained to manifest arrays only.
class Source r ix e => Manifest r ix e

-- | <i>O(1)</i> - Conversion of <a>Manifest</a> arrays to <a>M</a>
--   representation.
toManifest :: Manifest r ix e => Array r ix e -> Array M ix e

-- | General Manifest representation
data M

-- | Array representation for Boxed elements. This structure is element and
--   spine strict, but elements are strict to Weak Head Normal Form (WHNF)
--   only.
data B
B :: B

-- | Array representation for Boxed elements. This structure is element and
--   spine strict, and elements are always in Normal Form (NF), therefore
--   <a>NFData</a> instance is required.
data N
N :: N

-- | An error that gets thrown when an unitialized element of a boxed array
--   gets accessed. Can only happen when array was constructed with
--   <a>unsafeNew</a>.
data Uninitialized
Uninitialized :: Uninitialized

-- | <i>O(1)</i> - Unwrap boxed array.
unwrapArray :: Array B ix e -> Array e

-- | <i>O(n)</i> - Wrap a boxed array and evaluate all elements to a WHNF.
evalArray :: Comp -> Array e -> Array B Ix1 e

-- | <i>O(1)</i> - Unwrap mutable boxed array.
unwrapMutableArray :: MArray s B ix e -> MutableArray s e

-- | <i>O(n)</i> - Wrap mutable boxed array and evaluate all elements to
--   WHNF.
evalMutableArray :: PrimMonad m => MutableArray (PrimState m) e -> m (MArray (PrimState m) B Ix1 e)

-- | <i>O(1)</i> - Unwrap a fully evaluated boxed array.
unwrapNormalFormArray :: Array N ix e -> Array e

-- | <i>O(n)</i> - Wrap a boxed array and evaluate all elements to a Normal
--   Form (NF).
evalNormalFormArray :: NFData e => Comp -> Array e -> Array N Ix1 e

-- | <i>O(1)</i> - Unwrap a fully evaluated mutable boxed array.
unwrapNormalFormMutableArray :: MArray s N ix e -> MutableArray s e

-- | <i>O(n)</i> - Wrap mutable boxed array and evaluate all elements to
--   NF.
evalNormalFormMutableArray :: (PrimMonad m, NFData e) => MutableArray (PrimState m) e -> m (MArray (PrimState m) N Ix1 e)

-- | Representation for <a>Prim</a>itive elements
data P
P :: P

-- | Class of types supporting primitive array operations
class Prim a

-- | <i>O(1)</i> - Extract the internal <a>ByteArray</a>.
toByteArray :: Array P ix e -> ByteArray

-- | <i>O(1)</i> - Construct a primitive array from the <a>ByteArray</a>.
--   Will return <a>Nothing</a> if number of elements doesn't match.
fromByteArray :: (Index ix, Prim e) => Comp -> ix -> ByteArray -> Maybe (Array P ix e)

-- | <i>O(1)</i> - Extract the internal <a>MutableByteArray</a>.
toMutableByteArray :: MArray s P ix e -> MutableByteArray s

-- | <i>O(1)</i> - Construct a primitive mutable array from the
--   <a>MutableByteArray</a>. Will return <a>Nothing</a> if number of
--   elements doesn't match.
fromMutableByteArray :: (Index ix, Prim e) => ix -> MutableByteArray s -> Maybe (MArray s P ix e)

-- | Representation for <tt>Storable</tt> elements
data S
S :: S

-- | The member functions of this class facilitate writing values of
--   primitive types to raw memory (which may have been allocated with the
--   above mentioned routines) and reading values from blocks of raw
--   memory. The class, furthermore, includes support for computing the
--   storage requirements and alignment restrictions of storable types.
--   
--   Memory addresses are represented as values of type <tt><a>Ptr</a>
--   a</tt>, for some <tt>a</tt> which is an instance of class
--   <a>Storable</a>. The type argument to <a>Ptr</a> helps provide some
--   valuable type safety in FFI code (you can't mix pointers of different
--   types without an explicit cast), while helping the Haskell type system
--   figure out which marshalling method is needed for a given pointer.
--   
--   All marshalling between Haskell and a foreign language ultimately
--   boils down to translating Haskell data structures into the binary
--   representation of a corresponding data structure of the foreign
--   language and vice versa. To code this marshalling in Haskell, it is
--   necessary to manipulate primitive data types stored in unstructured
--   memory blocks. The class <a>Storable</a> facilitates this manipulation
--   on all types for which it is instantiated, which are the standard
--   basic types of Haskell, the fixed size <tt>Int</tt> types
--   (<a>Int8</a>, <a>Int16</a>, <a>Int32</a>, <a>Int64</a>), the fixed
--   size <tt>Word</tt> types (<a>Word8</a>, <a>Word16</a>, <a>Word32</a>,
--   <a>Word64</a>), <a>StablePtr</a>, all types from
--   <a>Foreign.C.Types</a>, as well as <a>Ptr</a>.
class Storable a

-- | <i>O(1)</i> - Unwrap storable array and pull out the underlying
--   storable vector.
toStorableVector :: Array S ix e -> Vector e

-- | <i>O(1)</i> - Unwrap storable mutable array and pull out the
--   underlying storable mutable vector.
toStorableMVector :: MArray s S ix e -> MVector s e

-- | A pointer to the beginning of the mutable array.
withPtr :: (Index ix, Storable a) => MArray RealWorld S ix a -> (Ptr a -> IO b) -> IO b

-- | A pointer to the beginning of the storable array. It is unsafe since
--   it can break referential transparency.
unsafeWithPtr :: Storable a => Array S ix a -> (Ptr a -> IO b) -> IO b

-- | Representation for <tt>Unbox</tt>ed elements
data U
U :: U
class (Vector Vector a, MVector MVector a) => Unbox a

-- | <i>O(1)</i> - Unwrap unboxed array and pull out the underlying unboxed
--   vector.
toUnboxedVector :: Array U ix e -> Vector e

-- | <i>O(1)</i> - Unwrap unboxed mutable array and pull out the underlying
--   unboxed mutable vector.
toUnboxedMVector :: MArray s U ix e -> MVector s e

-- | <i>O(1)</i> - Convert a strict ByteString into a manifest array. Will
--   return <a>Nothing</a> if length doesn't match the total number of
--   elements of new array.
fromByteString :: Comp -> ByteString -> Array M Ix1 Word8

-- | <i>O(n)</i> - For now only sequentially convert an array into a strict
--   ByteString
toByteString :: Source r ix Word8 => Array r ix Word8 -> ByteString

-- | <i>O(n)</i> - Conversion of array monoidally into a string Builder.
toBuilder :: Source r ix e => (e -> Builder) -> Array r ix e -> Builder


module Data.Massiv.Array.Stencil.Unsafe

-- | This is an unsafe version of the stencil computation. There are no
--   bounds check further from the border, so if you make sure you don't go
--   outside the size of the stencil, you will be safe, but this is not
--   enforced.
--   
--   <b><i>Note</i></b> - Still experimental and subject to change
forStencilUnsafe :: (Source r ix e, Manifest r ix e) => Array r ix e -> Sz ix -> ix -> ((ix -> Maybe e) -> a) -> Array DW ix a


module Data.Massiv.Array.Stencil

-- | Stencil is abstract description of how to handle elements in the
--   neighborhood of every array cell in order to compute a value for the
--   cells in the new array. Use <a>makeStencil</a> and
--   <a>makeConvolutionStencil</a> in order to create a stencil.
data Stencil ix e a

-- | This is a simple wrapper for value of an array cell. It is used in
--   order to improve safety of <a>Stencil</a> mapping. Using various class
--   instances, such as <a>Num</a> and <a>Functor</a> for example, make it
--   possible to manipulate the value, without having direct access to it.
data Value e

-- | Construct a stencil from a function, which describes how to calculate
--   the value at a point while having access to neighboring elements with
--   a function that accepts idices relative to the center of stencil.
--   Trying to index outside the stencil box will result in a runtime error
--   upon stencil creation.
--   
--   <h4><b>Example</b></h4>
--   
--   Below is an example of creating a <a>Stencil</a>, which, when mapped
--   over a 2-dimensional array, will compute an average of all elements in
--   a 3x3 square for each element in that array. <i>Note:</i> Make sure to
--   add <tt>INLINE</tt> pragma, otherwise performance will be terrible.
--   
--   <pre>
--   average3x3Stencil :: (Default a, Fractional a) =&gt; Stencil Ix2 a a
--   average3x3Stencil = makeStencil (3 :. 3) (1 :. 1) $ \ get -&gt;
--     (  get (-1 :. -1) + get (-1 :. 0) + get (-1 :. 1) +
--        get ( 0 :. -1) + get ( 0 :. 0) + get ( 0 :. 1) +
--        get ( 1 :. -1) + get ( 1 :. 0) + get ( 1 :. 1)   ) / 9
--   {-# INLINE average3x3Stencil #-}
--   </pre>
makeStencil :: (Index ix, Default e) => ix -> ix -> ((ix -> Value e) -> Value a) -> Stencil ix e a

-- | Same as <a>makeStencil</a>, but with ability to specify default value
--   for stencil validation.
makeStencilDef :: Index ix => e -> Sz ix -> ix -> ((ix -> Value e) -> Value a) -> Stencil ix e a

-- | Map a constructed stencil over an array. Resulting array must be
--   <tt>compute</tt>d in order to be useful.
mapStencil :: (Source r ix e, Manifest r ix e) => Border e -> Stencil ix e a -> Array r ix e -> Array DW ix a
dimapStencil :: (c -> d) -> (a -> b) -> Stencil ix d a -> Stencil ix c b
lmapStencil :: (c -> d) -> Stencil ix d a -> Stencil ix c a
rmapStencil :: (a -> b) -> Stencil ix e a -> Stencil ix e b

-- | Create a convolution stencil by specifying border resolution technique
--   and an accumulator function.
--   
--   <h4><b>Examples</b></h4>
--   
--   Here is how to create a 2D horizontal Sobel Stencil:
--   
--   <pre>
--   sobelX :: Num e =&gt; Stencil Ix2 e e
--   sobelX = makeConvolutionStencil (Sz2 3 3) (1 :. 1) $
--              \f -&gt; f (-1 :. -1) (-1) . f (-1 :. 1) 1 .
--                    f ( 0 :. -1) (-2) . f ( 0 :. 1) 2 .
--                    f ( 1 :. -1) (-1) . f ( 1 :. 1) 1
--   {-# INLINE sobelX #-}
--   </pre>
makeConvolutionStencil :: (Index ix, Num e) => Sz ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e

-- | Make a stencil out of a Kernel Array. This <a>Stencil</a> will be
--   slower than if <a>makeConvolutionStencil</a> is used, but sometimes we
--   just really don't know the kernel at compile time.
makeConvolutionStencilFromKernel :: (Manifest r ix e, Num e) => Array r ix e -> Stencil ix e e

-- | Make a <a>cross-correlation</a> stencil
makeCorrelationStencil :: (Index ix, Num e) => Sz ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e

-- | Make a <a>cross-correlation</a> stencil out of a Kernel Array. This
--   <a>Stencil</a> will be slower than if <a>makeCorrelationStencil</a> is
--   used, but sometimes we just really don't know the kernel at compile
--   time.
makeCorrelationStencilFromKernel :: (Manifest r ix e, Num e) => Array r ix e -> Stencil ix e e


module Data.Massiv.Array.Delayed

-- | Delayed representation.
data D
D :: D

-- | <i>O(1)</i> Conversion from a source array to <a>D</a> representation.
delay :: Source r ix e => Array r ix e -> Array D ix e

-- | Delayed array that will be loaded in an interleaved fasion during
--   parallel computation.
data DI
DI :: DI

-- | Convert a source array into an array that, when computed, will have
--   its elemets evaluated out of order (interleaved amoungs cores), hence
--   making unbalanced computation better parallelizable.
toInterleaved :: Source r ix e => Array r ix e -> Array DI ix e

-- | <i>O(1)</i> - Unwrap the interleved array.
fromInterleaved :: Array DI ix e -> Array D ix e

-- | Delayed Windowed Array representation.
data DW
DW :: DW
data Window ix e
Window :: !ix -> !ix -> (ix -> e) -> Window ix e

-- | Index of where window will start at.
[windowStart] :: Window ix e -> !ix

-- | Size of the window
[windowSize] :: Window ix e -> !ix

-- | Indexing function for the window
[windowIndex] :: Window ix e -> ix -> e

-- | Get the <a>Window</a> from the Windowed array.
getWindow :: Array DW ix e -> Maybe (Window ix e)

-- | Supply a separate generating function for interior of an array. This
--   is very usful for stencil mapping, where interior function does not
--   perform boundary checks, thus significantly speeding up computation
--   process.
makeWindowedArray :: Source r ix e => Array r ix e -> ix -> Sz ix -> (ix -> e) -> Array DW ix e

module Data.Massiv.Array.Numeric.Integral

-- | Use midpoint rule to approximate an integral.
midpointRule :: (Fractional e, Load DW ix e, Mutable r ix e) => Comp -> r -> ((Int -> e) -> ix -> e) -> e -> e -> Sz ix -> Int -> Array M ix e

-- | <b>Midpoint Rule</b>
--   
--   &lt;math&gt;
midpointStencil :: (Fractional e, Index ix) => e -> Dim -> Int -> Stencil ix e e

-- | Use trapezoid rule to approximate an integral.
trapezoidRule :: (Fractional e, Load DW ix e, Mutable r ix e) => Comp -> r -> ((Int -> e) -> ix -> e) -> e -> e -> Sz ix -> Int -> Array M ix e

-- | <b>Trapezoid Rule</b>
--   
--   &lt;math&gt;
trapezoidStencil :: (Fractional e, Index ix) => e -> Dim -> Int -> Stencil ix e e

-- | Use Simpson's rule to approximate an integral.
simpsonsRule :: (Fractional e, Load DW ix e, Mutable r ix e) => Comp -> r -> ((Int -> e) -> ix -> e) -> e -> e -> Sz ix -> Int -> Array M ix e

-- | <b>Simpson's Rule</b>
--   
--   &lt;math&gt;
simpsonsStencil :: (Fractional e, Index ix) => e -> Dim -> Int -> Stencil ix e e

-- | Integrate with a stencil along a particular dimension.
integrateWith :: (Fractional e, Load DW ix e, Mutable r ix e) => (Dim -> Int -> Stencil ix e e) -> Dim -> Int -> Array r ix e -> Array r ix e

-- | Compute an approximation of integral using a supplied rule in a form
--   of <a>Stencil</a>.
integralApprox :: (Fractional e, Load DW ix e, Mutable r ix e) => (e -> Dim -> Int -> Stencil ix e e) -> e -> Sz ix -> Int -> Array r ix e -> Array M ix e

-- | Create an array from a function with sample points at the edges
--   
--   <pre>
--   &gt;&gt;&gt; fromFunction Seq (\ scale (i :. j) -&gt; scale i + scale j) (-2) 1 (4 :. 4) 2
--   (Array D Seq (9 :. 9)
--     [ [ -4.0,-3.5,-3.0,-2.5,-2.0,-1.5,-1.0,-0.5,0.0 ]
--     , [ -3.5,-3.0,-2.5,-2.0,-1.5,-1.0,-0.5,0.0,0.5 ]
--     , [ -3.0,-2.5,-2.0,-1.5,-1.0,-0.5,0.0,0.5,1.0 ]
--     , [ -2.5,-2.0,-1.5,-1.0,-0.5,0.0,0.5,1.0,1.5 ]
--     , [ -2.0,-1.5,-1.0,-0.5,0.0,0.5,1.0,1.5,2.0 ]
--     , [ -1.5,-1.0,-0.5,0.0,0.5,1.0,1.5,2.0,2.5 ]
--     , [ -1.0,-0.5,0.0,0.5,1.0,1.5,2.0,2.5,3.0 ]
--     , [ -0.5,0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5 ]
--     , [ 0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0 ]
--     ])
--   </pre>
fromFunction :: (Index ix, Fractional a) => Comp -> ((Int -> a) -> ix -> e) -> a -> a -> Sz ix -> Int -> Array D ix e

-- | Similar to <a>fromFunction</a>, but will create an array from a
--   function with sample points in the middle of cells.
--   
--   <pre>
--   &gt;&gt;&gt; fromFunctionMidpoint Seq (\ scale (i :. j) -&gt; scale i + scale j) (-2) 1 (4 :. 4) 2
--   (Array D Seq (8 :. 8)
--     [ [ -3.5,-3.0,-2.5,-2.0,-1.5,-1.0,-0.5,0.0 ]
--     , [ -3.0,-2.5,-2.0,-1.5,-1.0,-0.5,0.0,0.5 ]
--     , [ -2.5,-2.0,-1.5,-1.0,-0.5,0.0,0.5,1.0 ]
--     , [ -2.0,-1.5,-1.0,-0.5,0.0,0.5,1.0,1.5 ]
--     , [ -1.5,-1.0,-0.5,0.0,0.5,1.0,1.5,2.0 ]
--     , [ -1.0,-0.5,0.0,0.5,1.0,1.5,2.0,2.5 ]
--     , [ -0.5,0.0,0.5,1.0,1.5,2.0,2.5,3.0 ]
--     , [ 0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5 ]
--     ])
--   </pre>
fromFunctionMidpoint :: (Index ix, Fractional a) => Comp -> ((Int -> a) -> ix -> e) -> a -> a -> ix -> Int -> Array D ix e


-- | Massiv is a library, that allows creation and manipulation of arrays
--   in parallel and sequentially. Depending on the representation
--   (<tt><b>r</b></tt>), an <tt><b><a>Array</a> r ix e</b></tt> will have
--   certain properties that are unique to that particular representation,
--   but all of them will share the same trait, that an array is simply a
--   mapping from an index (<tt><b>ix</b></tt>) of an arbitrary dimension
--   to an element (<tt><b>e</b></tt>) of some value. Which means that some
--   of the array types are pretty classic and are represented by a
--   contiguous chunk of memory reserved for the elements, namely arrays
--   with <a>Manifest</a> representations:
--   
--   <ul>
--   <li><a>B</a> - The most basic type of array that can hold any type of
--   element in a boxed form, i.e. each element is a pointer to the actual
--   value, therefore it is also the slowest representation. Elements are
--   kept in a Weak Head Normal Form (WHNF).</li>
--   <li><a>N</a> - Similar to <a>B</a>, is also a boxed type, except it's
--   elements are always kept in a Normal Form (NF). This property is very
--   useful for parallel processing, i.e. when calling <a>compute</a> you
--   do want all of your elements to be fully evaluated.</li>
--   <li><a>S</a> - Is a type of array that is backed by pinned memory,
--   therefore pointers to those arrays can be passed to FFI calls, because
--   Garbage Collector (GC) is guaranteed not to move it. Elements must be
--   an instance of <a>Storable</a> class. It is just as efficient as
--   <a>P</a> and <a>U</a> arrays, except it is subject to
--   fragmentation.</li>
--   <li><a>U</a> - Unboxed representation. Elements must be an instance of
--   <a>Unbox</a> class.</li>
--   <li><a>P</a> - Array that can hold Haskell primitives, such as
--   <a>Int</a>, <a>Word</a>, <a>Double</a>, etc. Any element must be an
--   instance of <a>Prim</a> class.</li>
--   <li><a>M</a> - General manifest array type, that any of the above
--   representations can be converted to in constant time using
--   <a>toManifest</a>.</li>
--   </ul>
--   
--   While at the same time, there are arrays that only describe how values
--   for it's elements can be computed, and have no memory overhead on
--   their own.
--   
--   <ul>
--   <li><a>D</a> - delayed array that is a mere function from an index to
--   an element. Crucial representation for fusing computation. Use
--   <a>computeAs</a> in order to load array into <a>Manifest</a>
--   representation.</li>
--   <li><a>DI</a> - delayed interleaved array. Same as <a>D</a>, but
--   performced better with unbalanced computation, when evaluation one
--   element takes much longer than it's neighbor.</li>
--   <li><a>DW</a> - delayed windowed array. This peculiar representation
--   allows for very fast <a>Stencil</a> computation.</li>
--   </ul>
--   
--   Other Array types:
--   
--   <ul>
--   <li><a>L</a> and <a>LN</a> - those types aren't particularly useful on
--   their own, but because of their unique ability to be converted to and
--   from nested lists in constant time, provide an amazing intermediary
--   for list/array conversion.</li>
--   </ul>
--   
--   Most of the <a>Manifest</a> arrays are capable of in-place mutation.
--   Check out <a>Data.Massiv.Array.Mutable</a> module for available
--   functionality.
--   
--   Many of the function names exported by this package will clash with
--   the ones from <a>Prelude</a>, hence it can be more convenient to
--   import like this:
--   
--   <pre>
--   import Prelude as P
--   import Data.Massiv.Array as A
--   </pre>
module Data.Massiv.Array

-- | Create an Array. Resulting type either has to be unambiguously
--   inferred or restricted manually, like in the example below.
--   
--   <pre>
--   &gt;&gt;&gt; makeArray Seq (Sz (3 :. 4)) (\ (i :. j) -&gt; if i == j then i else 0) :: Array D Ix2 Int
--   (Array D Seq (3 :. 4)
--   [ [ 0,0,0,0 ]
--   , [ 0,1,0,0 ]
--   , [ 0,0,2,0 ]
--   ])
--   </pre>
makeArray :: Construct r ix e => Comp -> Sz ix -> (ix -> e) -> Array r ix e

-- | Just like <a>makeArray</a> but with ability to specify the result
--   representation as an argument. Note the <a>U</a>nboxed type
--   constructor in the below example.
--   
--   <pre>
--   &gt;&gt;&gt; makeArrayR U Par (Sz (2 :&gt; 3 :. 4)) (\ (i :&gt; j :. k) -&gt; i * i + j * j == k * k)
--   (Array U Par (2 :&gt; 3 :. 4)
--     [ [ [ True,False,False,False ]
--       , [ False,True,False,False ]
--       , [ False,False,True,False ]
--       ]
--     , [ [ False,True,False,False ]
--       , [ False,False,False,False ]
--       , [ False,False,False,False ]
--       ]
--     ])
--   </pre>
makeArrayR :: Construct r ix e => r -> Comp -> Sz ix -> (ix -> e) -> Array r ix e

-- | Same as <a>makeArrayR</a>, but restricted to 1-dimensional arrays.
makeVectorR :: Construct r Ix1 e => r -> Comp -> Sz1 -> (Ix1 -> e) -> Array r Ix1 e

-- | Create an Array with a single element.
singleton :: Construct r ix e => Comp -> e -> Array r ix e

-- | Similar to <a>makeArray</a>, but construct the array sequentially
--   using an <a>Applicative</a> interface disregarding the supplied
--   <a>Comp</a>.
makeArrayA :: (Mutable r ix b, Applicative f) => Comp -> Sz ix -> (ix -> f b) -> f (Array r ix b)

-- | Same as <a>makeArrayA</a>, but with ability to supply result array
--   representation.
makeArrayAR :: (Mutable r ix b, Applicative f) => r -> Comp -> Sz ix -> (ix -> f b) -> f (Array r ix b)

-- | Create a vector with a range of <tt>Int</tt>s incremented by 1.
--   <tt>range k0 k1 == rangeStep k0 k1 1</tt>
--   
--   <pre>
--   &gt;&gt;&gt; range Seq 1 6
--   (Array D Seq (5)
--     [ 1,2,3,4,5 ])
--   
--   &gt;&gt;&gt; range Seq (-2) 3
--   (Array D Seq (5)
--     [ -2,-1,0,1,2 ])
--   </pre>
range :: Comp -> Int -> Int -> Array D Ix1 Int

-- | Same as <a>range</a>, but with a custom step.
--   
--   <pre>
--   &gt;&gt;&gt; rangeStep Seq 1 2 6
--   (Array D Seq (3)
--     [ 1,3,5 ])
--   </pre>
rangeStep :: Comp -> Int -> Int -> Int -> Array D Ix1 Int

-- | Same as <a>enumFromStepN</a> with step <tt>delta = 1</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; enumFromN Seq (5 :: Double) 3
--   (Array D Seq (3)
--     [ 5.0,6.0,7.0 ])
--   </pre>
enumFromN :: Num e => Comp -> e -> Int -> Array D Ix1 e

-- | Create a vector with length <tt>n</tt> that has it's 0th value set to
--   <tt>x</tt> and gradually increasing with <tt>step</tt> delta until the
--   end. Similar to: <tt><a>fromList'</a> <a>Seq</a> $ <a>take</a> n [x, x
--   + delta ..]</tt>. Major difference is that <tt>fromList</tt>
--   constructs an <a>Array</a> with manifest representation, while
--   <a>enumFromStepN</a> is delayed.
--   
--   <pre>
--   &gt;&gt;&gt; enumFromStepN Seq 1 (0.1 :: Double) 5
--   (Array D Seq (5)
--     [ 1.0,1.1,1.2,1.3,1.4 ])
--   </pre>
enumFromStepN :: Num e => Comp -> e -> e -> Int -> Array D Ix1 e

-- | Function that expands an array to one with a higher dimension.
--   
--   This is useful for constructing arrays where there is shared
--   computation between multiple cells. The makeArray method of
--   constructing arrays:
--   
--   <pre>
--   makeArray :: Construct r ix e =&gt; Comp -&gt; ix -&gt; (ix -&gt; e) -&gt; Array r ix e
--   </pre>
--   
--   ...runs a function <tt>ix -&gt; e</tt> at every array index. This is
--   inefficient if there is a substantial amount of repeated computation
--   that could be shared while constructing elements on the same
--   dimension. The expand functions make this possible. First you
--   construct an <tt>Array r (Lower ix) a</tt> of one fewer dimensions
--   where <tt>a</tt> is something like <tt><a>Array</a> r <a>Ix1</a>
--   a</tt> or <tt><a>Array</a> r <a>Ix2</a> a</tt>. Then you use
--   <a>expandWithin</a> and a creation function <tt>a -&gt; Int -&gt;
--   b</tt> to create an <tt><a>Array</a> <a>D</a> <a>Ix2</a> b</tt> or
--   <tt><a>Array</a> <a>D</a> <a>Ix3</a> b</tt> respectfully.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; a = makeArrayR U Seq (Ix1 6) (+10) -- Imagine (+10) is some expensive function
--   
--   &gt;&gt;&gt; a
--   (Array U Seq (6)
--     [ 10,11,12,13,14,15 ])
--   
--   &gt;&gt;&gt; expandWithin Dim1 5 (\ e j -&gt; (j + 1) * 100 + e) a :: Array D Ix2 Int
--   (Array D Seq (6 :. 5)
--     [ [ 110,210,310,410,510 ]
--     , [ 111,211,311,411,511 ]
--     , [ 112,212,312,412,512 ]
--     , [ 113,213,313,413,513 ]
--     , [ 114,214,314,414,514 ]
--     , [ 115,215,315,415,515 ]
--     ])
--   
--   &gt;&gt;&gt; expandWithin Dim2 5 (\ e j -&gt; (j + 1) * 100 + e) a :: Array D Ix2 Int
--   (Array D Seq (5 :. 6)
--     [ [ 110,111,112,113,114,115 ]
--     , [ 210,211,212,213,214,215 ]
--     , [ 310,311,312,313,314,315 ]
--     , [ 410,411,412,413,414,415 ]
--     , [ 510,511,512,513,514,515 ]
--     ])
--   </pre>
expandWithin :: (IsIndexDimension ix n, Manifest r (Lower ix) a) => Dimension n -> Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b

-- | Similar to <a>expandWithin</a>, except that dimension is specified at
--   a value level, which means it will throw an exception on an invalid
--   dimension.
expandWithin' :: (Index ix, Manifest r (Lower ix) a) => Dim -> Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b

-- | Similar to <a>expandWithin</a>, except it uses the outermost
--   dimension.
expandOuter :: (Index ix, Manifest r (Lower ix) a) => Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b

-- | Similar to <a>expandWithin</a>, except it uses the innermost
--   dimension.
expandInner :: (Index ix, Manifest r (Lower ix) a) => Int -> (a -> Int -> b) -> Array r (Lower ix) a -> Array D ix b

-- | Get computation strategy of this array
getComp :: Construct r ix e => Array r ix e -> Comp

-- | Set computation strategy for this array
setComp :: Construct r ix e => Comp -> Array r ix e -> Array r ix e

-- | Ensure that Array is computed, i.e. represented with concrete elements
--   in memory, hence is the <a>Mutable</a> type class restriction. Use
--   <a>setComp</a> if you'd like to change computation strategy before
--   calling <tt>compute</tt>
compute :: (Load r' ix e, Mutable r ix e) => Array r' ix e -> Array r ix e

-- | Just as <a>compute</a>, but let's you supply resulting representation
--   type as an argument.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; computeAs P $ range Seq 0 10
--   (Array P Seq (10)
--     [ 0,1,2,3,4,5,6,7,8,9 ])
--   </pre>
computeAs :: (Load r' ix e, Mutable r ix e) => r -> Array r' ix e -> Array r ix e

-- | Same as <a>compute</a> and <a>computeAs</a>, but let's you supply
--   resulting representation type as a proxy argument.
--   
--   <h4><b>Examples</b></h4>
--   
--   Useful for cases when representation constructor isn't available for
--   some reason:
--   
--   <pre>
--   &gt;&gt;&gt; computeProxy (Nothing :: Maybe P) $ range Seq 0 10
--   (Array P Seq (10)
--     [ 0,1,2,3,4,5,6,7,8,9 ])
--   </pre>
computeProxy :: (Load r' ix e, Mutable r ix e) => proxy r -> Array r' ix e -> Array r ix e

-- | This is just like <a>compute</a>, but can be applied to <a>Source</a>
--   arrays and will be a noop if resulting type is the same as the input.
computeSource :: forall r' r ix e. (Source r' ix e, Mutable r ix e) => Array r' ix e -> Array r ix e

-- | Same as <a>compute</a>, but with <a>Stride</a>.
computeWithStride :: (Load r' ix e, Mutable r ix e) => Stride ix -> Array r' ix e -> Array r ix e

-- | Same as <a>computeWithStride</a>, but with ability to specify
--   resulting array representation.
computeWithStrideAs :: (Load r' ix e, Mutable r ix e) => r -> Stride ix -> Array r' ix e -> Array r ix e

-- | <i>O(n)</i> - Make an exact immutable copy of an Array.
clone :: Mutable r ix e => Array r ix e -> Array r ix e

-- | <i>O(n)</i> - conversion between manifest types, except when source
--   and result arrays are of the same representation, in which case it is
--   an <i>O(1)</i> operation.
convert :: (Manifest r' ix e, Mutable r ix e) => Array r' ix e -> Array r ix e

-- | Same as <a>convert</a>, but let's you supply resulting representation
--   type as an argument.
convertAs :: (Manifest r' ix e, Mutable r ix e) => r -> Array r' ix e -> Array r ix e

-- | Same as <a>convert</a> and <a>convertAs</a>, but let's you supply
--   resulting representation type as a proxy argument.
convertProxy :: (Manifest r' ix e, Mutable r ix e) => proxy r -> Array r' ix e -> Array r ix e

-- | Convert a ragged array into a usual rectangular shaped one.
fromRaggedArray :: (Ragged r' ix e, Mutable r ix e) => Array r' ix e -> Either ShapeError (Array r ix e)

-- | Same as <a>fromRaggedArray</a>, but will throw an error if its shape
--   is not rectangular.
fromRaggedArray' :: (Ragged r' ix e, Mutable r ix e) => Array r' ix e -> Array r ix e

-- | <i>O(1)</i> - Get the size of an array
size :: Size r ix e => Array r ix e -> Sz ix

-- | <i>O(1)</i> - Get the number of elements in the array
elemsCount :: Size r ix e => Array r ix e -> Int

-- | <i>O(1)</i> - Check if array has no elements.
isEmpty :: Size r ix e => Array r ix e -> Bool

-- | Infix version of <a>index</a>.
(!?) :: Manifest r ix e => Array r ix e -> ix -> Maybe e
infixl 4 !?

-- | Infix version of <a>index'</a>.
(!) :: Manifest r ix e => Array r ix e -> ix -> e
infixl 4 !

-- | <i>O(1)</i> - Lookup an element in the array, where array can itself
--   be <a>Nothing</a>. This operator is useful when used together with
--   slicing or other functions that return <a>Maybe</a> array:
--   
--   <pre>
--   &gt;&gt;&gt; (fromList Seq [[[1,2,3]],[[4,5,6]]] :: Maybe (Array U Ix3 Int)) ??&gt; 1 ?? (0 :. 2)
--   Just 6
--   </pre>
(??) :: Manifest r ix e => Maybe (Array r ix e) -> ix -> Maybe e
infixl 4 ??

-- | <i>O(1)</i> - Lookup an element in the array. Returns <a>Nothing</a>,
--   when index is out of bounds, <a>Just</a> element otherwise.
index :: Manifest r ix e => Array r ix e -> ix -> Maybe e

-- | <i>O(1)</i> - Lookup an element in the array. Throw an error if index
--   is out of bounds.
index' :: Manifest r ix e => Array r ix e -> ix -> e

-- | <i>O(1)</i> - Lookup an element in the array, while using default
--   element when index is out of bounds.
defaultIndex :: Manifest r ix e => e -> Array r ix e -> ix -> e

-- | <i>O(1)</i> - Lookup an element in the array. Use a border resolution
--   technique when index is out of bounds.
borderIndex :: Manifest r ix e => Border e -> Array r ix e -> ix -> e

-- | This is just like <a>index'</a> function, but it allows getting values
--   from delayed arrays as well as manifest. As the name suggests,
--   indexing into a delayed array at the same index multiple times will
--   cause evaluation of the value each time and can destroy the performace
--   if used without care.
evaluateAt :: Source r ix e => Array r ix e -> ix -> e

-- | Map a function over an array
map :: Source r ix e' => (e' -> e) -> Array r ix e' -> Array D ix e

-- | Map an index aware function over an array
imap :: Source r ix e' => (ix -> e' -> e) -> Array r ix e' -> Array D ix e

-- | Traverse with an <a>Applicative</a> action over an array sequentially.
traverseA :: (Source r' ix a, Mutable r ix b, Applicative f) => (a -> f b) -> Array r' ix a -> f (Array r ix b)

-- | Traverse with an <a>Applicative</a> index aware action over an array
--   sequentially.
itraverseA :: (Source r' ix a, Mutable r ix b, Applicative f) => (ix -> a -> f b) -> Array r' ix a -> f (Array r ix b)

-- | Same as <a>traverseA</a>, except with ability to specify
--   representation.
traverseAR :: (Source r' ix a, Mutable r ix b, Applicative f) => r -> (a -> f b) -> Array r' ix a -> f (Array r ix b)

-- | Same as <a>itraverseA</a>, except with ability to specify
--   representation.
itraverseAR :: (Source r' ix a, Mutable r ix b, Applicative f) => r -> (ix -> a -> f b) -> Array r' ix a -> f (Array r ix b)

-- | Map a monadic action over an array sequentially.
mapM :: (Source r' ix a, Mutable r ix b, Monad m) => (a -> m b) -> Array r' ix a -> m (Array r ix b)

-- | Same as <a>mapM</a>, except with ability to specify result
--   representation.
mapMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> (a -> m b) -> Array r' ix a -> m (Array r ix b)

-- | Same as <a>mapM</a> except with arguments flipped.
forM :: (Source r' ix a, Mutable r ix b, Monad m) => Array r' ix a -> (a -> m b) -> m (Array r ix b)

-- | Same as <a>forM</a>, except with ability to specify result
--   representation.
forMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> Array r' ix a -> (a -> m b) -> m (Array r ix b)

-- | Map a monadic action over an array sequentially.
imapM :: (Source r' ix a, Mutable r ix b, Monad m) => (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)

-- | Same as <a>imapM</a>, except with ability to specify result
--   representation.
imapMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)

-- | Same as <a>forM</a>, except map an index aware action.
iforM :: (Source r' ix a, Mutable r ix b, Monad m) => (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)

-- | Same as <a>iforM</a>, except with ability to specify result
--   representation.
iforMR :: (Source r' ix a, Mutable r ix b, Monad m) => r -> (ix -> a -> m b) -> Array r' ix a -> m (Array r ix b)

-- | Map a monadic function over an array sequentially, while discarding
--   the result.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; mapM_ print $ rangeStep 10 12 60
--   10
--   22
--   34
--   46
--   58
--   </pre>
mapM_ :: (Source r ix a, Monad m) => (a -> m b) -> Array r ix a -> m ()

-- | Just like <a>mapM_</a>, except with flipped arguments.
--   
--   <h4><b>Examples</b></h4>
--   
--   Here is a common way of iterating N times using a for loop in an
--   imperative language with mutation being an obvious side effect:
--   
--   <pre>
--   &gt;&gt;&gt; :m + Data.IORef
--   
--   &gt;&gt;&gt; var &lt;- newIORef 0 :: IO (IORef Int)
--   
--   &gt;&gt;&gt; forM_ (range 0 1000) $ \ i -&gt; modifyIORef' var (+i)
--   
--   &gt;&gt;&gt; readIORef var
--   499500
--   </pre>
forM_ :: (Source r ix a, Monad m) => Array r ix a -> (a -> m b) -> m ()

-- | Map a monadic index aware function over an array sequentially, while
--   discarding the result.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; imapM_ (curry print) $ range 10 15
--   (0,10)
--   (1,11)
--   (2,12)
--   (3,13)
--   (4,14)
--   </pre>
imapM_ :: (Source r ix a, Monad m) => (ix -> a -> m b) -> Array r ix a -> m ()

-- | Just like <a>imapM_</a>, except with flipped arguments.
iforM_ :: (Source r ix a, Monad m) => Array r ix a -> (ix -> a -> m b) -> m ()

-- | Map an <a>IO</a> action over an <a>Array</a>. Underlying computation
--   strategy is respected and will be parallelized when requested.
--   Unfortunately no fusion is possible and new array will be create upon
--   each call.
mapIO :: (Source r' ix a, Mutable r ix b) => (a -> IO b) -> Array r' ix a -> IO (Array r ix b)

-- | Similar to <a>mapIO</a>, but ignores the result of mapping action and
--   does not create a resulting array, therefore it is faster. Use this
--   instead of <a>mapIO</a> when result is irrelevant.
mapIO_ :: Source r b e => (e -> IO a) -> Array r b e -> IO ()

-- | Same as <a>mapIO</a> but map an index aware action instead.
imapIO :: (Source r' ix a, Mutable r ix b) => (ix -> a -> IO b) -> Array r' ix a -> IO (Array r ix b)

-- | Same as <a>mapIO_</a>, but map an index aware action instead.
imapIO_ :: Source r ix e => (ix -> e -> IO a) -> Array r ix e -> IO ()

-- | Same as <a>mapIO</a> but with arguments flipped.
forIO :: (Source r' ix a, Mutable r ix b) => Array r' ix a -> (a -> IO b) -> IO (Array r ix b)

-- | Same as <a>mapIO_</a> but with arguments flipped.
forIO_ :: Source r ix e => Array r ix e -> (e -> IO a) -> IO ()

-- | Same as <a>imapIO</a> but with arguments flipped.
iforIO :: (Source r' ix a, Mutable r ix b) => Array r' ix a -> (ix -> a -> IO b) -> IO (Array r ix b)

-- | Same as <a>imapIO_</a> but with arguments flipped.
iforIO_ :: Source r ix a => Array r ix a -> (ix -> a -> IO b) -> IO ()

-- | Map an IO action, over an array in parallel, while discarding the
--   result.

-- | <i>Deprecated: In favor of <a>mapIO_</a></i>
mapP_ :: Source r ix a => (a -> IO b) -> Array r ix a -> IO ()

-- | Map an index aware IO action, over an array in parallel, while
--   discarding the result.

-- | <i>Deprecated: In favor of <a>imapIO_</a></i>
imapP_ :: Source r ix a => (ix -> a -> IO b) -> Array r ix a -> IO ()

-- | Zip two arrays
zip :: (Source r1 ix e1, Source r2 ix e2) => Array r1 ix e1 -> Array r2 ix e2 -> Array D ix (e1, e2)

-- | Zip three arrays
zip3 :: (Source r1 ix e1, Source r2 ix e2, Source r3 ix e3) => Array r1 ix e1 -> Array r2 ix e2 -> Array r3 ix e3 -> Array D ix (e1, e2, e3)

-- | Unzip two arrays
unzip :: Source r ix (e1, e2) => Array r ix (e1, e2) -> (Array D ix e1, Array D ix e2)

-- | Unzip three arrays
unzip3 :: Source r ix (e1, e2, e3) => Array r ix (e1, e2, e3) -> (Array D ix e1, Array D ix e2, Array D ix e3)

-- | Zip two arrays with a function. Resulting array will be an
--   intersection of source arrays in case their dimensions do not match.
zipWith :: (Source r1 ix e1, Source r2 ix e2) => (e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e

-- | Just like <a>zipWith</a>, except zip three arrays with a function.
zipWith3 :: (Source r1 ix e1, Source r2 ix e2, Source r3 ix e3) => (e1 -> e2 -> e3 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array r3 ix e3 -> Array D ix e

-- | Just like <a>zipWith</a>, except with an index aware function.
izipWith :: (Source r1 ix e1, Source r2 ix e2) => (ix -> e1 -> e2 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array D ix e

-- | Just like <a>zipWith3</a>, except with an index aware function.
izipWith3 :: (Source r1 ix e1, Source r2 ix e2, Source r3 ix e3) => (ix -> e1 -> e2 -> e3 -> e) -> Array r1 ix e1 -> Array r2 ix e2 -> Array r3 ix e3 -> Array D ix e

-- | Similar to <a>zipWith</a>, except dimensions of both arrays either
--   have to be the same, or at least one of the two array must be a
--   singleton array, in which case it will behave as a <a>map</a>.
liftArray2 :: (Source r1 ix a, Source r2 ix b) => (a -> b -> e) -> Array r1 ix a -> Array r2 ix b -> Array D ix e

-- | <i>O(n)</i> - Unstructured fold of an array.
fold :: Source r ix e => (e -> e -> e) -> e -> Array r ix e -> e

-- | <i>O(n)</i> - Monoidal fold over an array with an index aware
--   function. Also known as reduce.
ifoldMono :: (Source r ix e, Monoid m) => (ix -> e -> m) -> Array r ix e -> m

-- | <i>O(n)</i> - Monoidal fold over an array. Also known as reduce.
foldMono :: (Source r ix e, Monoid m) => (e -> m) -> Array r ix e -> m

-- | <i>O(n)</i> - Semigroup fold over an array with an index aware
--   function.
ifoldSemi :: (Source r ix e, Semigroup m) => (ix -> e -> m) -> m -> Array r ix e -> m

-- | <i>O(n)</i> - Semigroup fold over an array.
foldSemi :: (Source r ix e, Semigroup m) => (e -> m) -> m -> Array r ix e -> m

-- | <i>O(n)</i> - Compute minimum of all elements.
minimum :: (Source r ix e, Ord e) => Array r ix e -> e

-- | <i>O(n)</i> - Compute maximum of all elements.
maximum :: (Source r ix e, Ord e) => Array r ix e -> e

-- | <i>O(n)</i> - Compute sum of all elements.
sum :: (Source r ix e, Num e) => Array r ix e -> e

-- | <i>O(n)</i> - Compute product of all elements.
product :: (Source r ix e, Num e) => Array r ix e -> e

-- | <i>O(n)</i> - Compute conjunction of all elements.
and :: Source r ix Bool => Array r ix Bool -> Bool

-- | <i>O(n)</i> - Compute disjunction of all elements.
or :: Source r ix Bool => Array r ix Bool -> Bool

-- | <i>O(n)</i> - Determines whether all element of the array satisfy the
--   predicate.
all :: Source r ix e => (e -> Bool) -> Array r ix e -> Bool

-- | <i>O(n)</i> - Determines whether any element of the array satisfies
--   the predicate.
any :: Source r ix e => (e -> Bool) -> Array r ix e -> Bool

-- | Left fold over the inner most dimension with index aware function.
ifoldlInner :: (Index (Lower ix), Source r ix e) => (ix -> a -> e -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Left fold over the inner most dimension.
foldlInner :: (Index (Lower ix), Source r ix e) => (a -> e -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Right fold over the inner most dimension with index aware function.
ifoldrInner :: (Index (Lower ix), Source r ix e) => (ix -> e -> a -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Right fold over the inner most dimension.
foldrInner :: (Index (Lower ix), Source r ix e) => (e -> a -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Left fold along a specified dimension with an index aware function.
ifoldlWithin :: (Index (Lower ix), IsIndexDimension ix n, Source r ix e) => Dimension n -> (ix -> a -> e -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Left fold along a specified dimension.
--   
--   <h4><b>Example</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (2 :. 5) (toLinearIndex (2 :. 5))
--   
--   &gt;&gt;&gt; arr
--   (Array U Seq (2 :. 5)
--     [ [ 0,1,2,3,4 ]
--     , [ 5,6,7,8,9 ]
--     ])
--   
--   &gt;&gt;&gt; foldlWithin Dim1 (flip (:)) [] arr
--   (Array D Seq (2)
--     [ [4,3,2,1,0],[9,8,7,6,5] ])
--   
--   &gt;&gt;&gt; foldlWithin Dim2 (flip (:)) [] arr
--   (Array D Seq (5)
--     [ [5,0],[6,1],[7,2],[8,3],[9,4] ])
--   </pre>
foldlWithin :: (Index (Lower ix), IsIndexDimension ix n, Source r ix e) => Dimension n -> (a -> e -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Right fold along a specified dimension with an index aware function.
ifoldrWithin :: (Index (Lower ix), IsIndexDimension ix n, Source r ix e) => Dimension n -> (ix -> e -> a -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Right fold along a specified dimension.
foldrWithin :: (Index (Lower ix), IsIndexDimension ix n, Source r ix e) => Dimension n -> (e -> a -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Similar to <a>ifoldlWithin</a>, except that dimension is specified at
--   a value level, which means it will throw an exception on an invalid
--   dimension.
ifoldlWithin' :: (Index (Lower ix), Source r ix e) => Dim -> (ix -> a -> e -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Similar to <a>foldlWithin</a>, except that dimension is specified at a
--   value level, which means it will throw an exception on an invalid
--   dimension.
foldlWithin' :: (Index (Lower ix), Source r ix e) => Dim -> (a -> e -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Similar to <a>ifoldrWithin</a>, except that dimension is specified at
--   a value level, which means it will throw an exception on an invalid
--   dimension.
ifoldrWithin' :: (Index (Lower ix), Source r ix e) => Dim -> (ix -> e -> a -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | Similar to <a>foldrWithin</a>, except that dimension is specified at a
--   value level, which means it will throw an exception on an invalid
--   dimension.
foldrWithin' :: (Index (Lower ix), Source r ix e) => Dim -> (e -> a -> a) -> a -> Array r ix e -> Array D (Lower ix) a

-- | <i>O(n)</i> - Left fold, computed sequentially.
foldlS :: Source r ix e => (a -> e -> a) -> a -> Array r ix e -> a

-- | <i>O(n)</i> - Right fold, computed sequentially.
foldrS :: Source r ix e => (e -> a -> a) -> a -> Array r ix e -> a

-- | <i>O(n)</i> - Left fold with an index aware function, computed
--   sequentially.
ifoldlS :: Source r ix e => (a -> ix -> e -> a) -> a -> Array r ix e -> a

-- | <i>O(n)</i> - Right fold with an index aware function, computed
--   sequentially.
ifoldrS :: Source r ix e => (ix -> e -> a -> a) -> a -> Array r ix e -> a

-- | <i>O(n)</i> - Monadic left fold.
foldlM :: (Source r ix e, Monad m) => (a -> e -> m a) -> a -> Array r ix e -> m a

-- | <i>O(n)</i> - Monadic right fold.
foldrM :: (Source r ix e, Monad m) => (e -> a -> m a) -> a -> Array r ix e -> m a

-- | <i>O(n)</i> - Monadic left fold, that discards the result.
foldlM_ :: (Source r ix e, Monad m) => (a -> e -> m a) -> a -> Array r ix e -> m ()

-- | <i>O(n)</i> - Monadic right fold, that discards the result.
foldrM_ :: (Source r ix e, Monad m) => (e -> a -> m a) -> a -> Array r ix e -> m ()

-- | <i>O(n)</i> - Monadic left fold with an index aware function.
ifoldlM :: (Source r ix e, Monad m) => (a -> ix -> e -> m a) -> a -> Array r ix e -> m a

-- | <i>O(n)</i> - Monadic right fold with an index aware function.
ifoldrM :: (Source r ix e, Monad m) => (ix -> e -> a -> m a) -> a -> Array r ix e -> m a

-- | <i>O(n)</i> - Monadic left fold with an index aware function, that
--   discards the result.
ifoldlM_ :: (Source r ix e, Monad m) => (a -> ix -> e -> m a) -> a -> Array r ix e -> m ()

-- | <i>O(n)</i> - Monadic right fold with an index aware function, that
--   discards the result.
ifoldrM_ :: (Source r ix e, Monad m) => (ix -> e -> a -> m a) -> a -> Array r ix e -> m ()

-- | Version of foldr that supports <tt>foldr/build</tt> list fusion
--   implemented by GHC.
foldrFB :: Source r ix e => (e -> b -> b) -> b -> Array r ix e -> b

-- | <i>O(n)</i> - Left fold, computed sequentially with lazy accumulator.
lazyFoldlS :: Source r ix e => (a -> e -> a) -> a -> Array r ix e -> a

-- | <i>O(n)</i> - Right fold, computed sequentially with lazy accumulator.
lazyFoldrS :: Source r ix e => (e -> a -> a) -> a -> Array r ix e -> a

-- | <i>O(n)</i> - Left fold, computed in parallel. Parallelization of
--   folding is implemented in such a way that an array is split into a
--   number of chunks of equal length, plus an extra one for the left over.
--   Number of chunks is the same as number of available cores
--   (capabilities) plus one, and each chunk is individually folded by a
--   separate core with a function <tt>g</tt>. Results from folding each
--   chunk are further folded with another function <tt>f</tt>, thus
--   allowing us to use information about the structure of an array during
--   folding.
--   
--   <h3><b>Examples</b></h3>
--   
--   <pre>
--   &gt;&gt;&gt; foldlP (flip (:)) [] (flip (:)) [] $ makeArrayR U Seq (Ix1 11) id
--   [[10,9,8,7,6,5,4,3,2,1,0]]
--   </pre>
--   
--   And this is how the result would look like if the above computation
--   would be performed in a program executed with <tt>+RTS -N3</tt>, i.e.
--   with 3 capabilities:
--   
--   <pre>
--   &gt;&gt;&gt; foldlOnP [1,2,3] (flip (:)) [] (flip (:)) [] $ makeArrayR U Seq (Ix1 11) id
--   [[10,9],[8,7,6],[5,4,3],[2,1,0]]
--   </pre>
foldlP :: Source r ix e => (a -> e -> a) -> a -> (b -> a -> b) -> b -> Array r ix e -> IO b

-- | <i>O(n)</i> - Right fold, computed in parallel. Same as <a>foldlP</a>,
--   except directed from the last element in the array towards beginning.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; foldrP (++) [] (:) [] $ makeArray2D (3,4) id
--   [(0,0),(0,1),(0,2),(0,3),(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3)]
--   </pre>
foldrP :: Source r ix e => (e -> a -> a) -> a -> (a -> b -> b) -> b -> Array r ix e -> IO b

-- | <i>O(n)</i> - Left fold with an index aware function, computed in
--   parallel. Just like <a>foldlP</a>, except that folding function will
--   receive an index of an element it is being applied to.
ifoldlP :: Source r ix e => (a -> ix -> e -> a) -> a -> (b -> a -> b) -> b -> Array r ix e -> IO b

-- | Just like <a>ifoldrOnP</a>, but allows you to specify which cores to
--   run computation on.
ifoldrP :: Source r ix e => (ix -> e -> a -> a) -> a -> (a -> b -> b) -> b -> Array r ix e -> IO b

-- | Just like <a>foldlP</a>, but allows you to specify which cores
--   (capabilities) to run computation on. The order in which chunked
--   results will be supplied to function <tt>f</tt> is guaranteed to be
--   consecutive and aligned with the folding direction.
foldlOnP :: Source r ix e => [Int] -> (a -> e -> a) -> a -> (b -> a -> b) -> b -> Array r ix e -> IO b

-- | Parallel left fold.
ifoldlIO :: Source r ix e => [Int] -> (a -> ix -> e -> IO a) -> a -> (b -> a -> IO b) -> b -> Array r ix e -> IO b

-- | Just like <a>foldrP</a>, but allows you to specify which cores to run
--   computation on.
--   
--   <h4><b>Examples</b></h4>
--   
--   Number of wokers dictate the result structure:
--   
--   <pre>
--   &gt;&gt;&gt; foldrOnP [1,2,3] (:) [] (:) [] $ makeArray1D 9 id
--   [[0,1,2],[3,4,5],[6,7,8]]
--   
--   &gt;&gt;&gt; foldrOnP [1,2,3] (:) [] (:) [] $ makeArray1D 10 id
--   [[0,1,2],[3,4,5],[6,7,8],[9]]
--   
--   &gt;&gt;&gt; foldrOnP [1,2,3] (:) [] (:) [] $ makeArray1D 12 id
--   [[0,1,2,3],[4,5,6,7],[8,9,10,11]]
--   </pre>
--   
--   But most of the time that structure is of no importance:
--   
--   <pre>
--   &gt;&gt;&gt; foldrOnP [1,2,3] (++) [] (:) [] $ makeArray1D 10 id
--   [0,1,2,3,4,5,6,7,8,9]
--   </pre>
--   
--   Same as <a>foldlOnP</a>, order is guaranteed to be consecutive and in
--   proper direction:
--   
--   <pre>
--   &gt;&gt;&gt; fmap snd $ foldrOnP [1,2,3] (\x (i, acc) -&gt; (i + 1, (i, x):acc)) (1, []) (:) [] $ makeArray1D 11 id
--   [(4,[0,1,2]),(3,[3,4,5]),(2,[6,7,8]),(1,[9,10])]
--   
--   &gt;&gt;&gt; fmap (P.zip [4,3..]) &lt;$&gt; foldrOnP [1,2,3] (:) [] (:) [] $ makeArray1D 11 id
--   [(4,[0,1,2]),(3,[3,4,5]),(2,[6,7,8]),(1,[9,10])]
--   </pre>
foldrOnP :: Source r ix e => [Int] -> (e -> a -> a) -> a -> (a -> b -> b) -> b -> Array r ix e -> IO b

-- | Just like <a>ifoldlP</a>, but allows you to specify which cores to run
--   computation on.
ifoldlOnP :: Source r ix e => [Int] -> (a -> ix -> e -> a) -> a -> (b -> a -> b) -> b -> Array r ix e -> IO b

-- | <i>O(n)</i> - Right fold with an index aware function, computed in
--   parallel. Same as <a>ifoldlP</a>, except directed from the last
--   element in the array towards beginning.
ifoldrOnP :: Source r ix e => [Int] -> (ix -> e -> a -> a) -> a -> (a -> b -> b) -> b -> Array r ix e -> IO b

-- | Parallel right fold. Differs from <a>ifoldrP</a> in that it accepts
--   <a>IO</a> actions instead of the usual pure functions as arguments.
ifoldrIO :: Source r ix e => [Int] -> (ix -> e -> a -> IO a) -> a -> (a -> b -> IO b) -> b -> Array r ix e -> IO b

-- | Transpose a 2-dimensional array
--   
--   <h3><b>Examples</b></h3>
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (2 :. 3) (toLinearIndex (2 :. 3))
--   
--   &gt;&gt;&gt; arr
--   (ArrayU Seq (2 :. 3)
--     [ [ 0,1,2 ]
--     , [ 3,4,5 ]
--     ])
--   
--   &gt;&gt;&gt; transpose arr
--   (Array D Seq (3 :. 2)
--     [ [ 0,3 ]
--     , [ 1,4 ]
--     , [ 2,5 ]
--     ])
--   </pre>
transpose :: Source r Ix2 e => Array r Ix2 e -> Array D Ix2 e

-- | Transpose inner two dimensions of at least rank-2 array.
--   
--   <h3><b>Examples</b></h3>
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (2 :&gt; 3 :. 4) fromIx3
--   
--   &gt;&gt;&gt; arr
--   (Array U Seq (2 :&gt; 3 :. 4)
--     [ [ [ (0,0,0),(0,0,1),(0,0,2),(0,0,3) ]
--       , [ (0,1,0),(0,1,1),(0,1,2),(0,1,3) ]
--       , [ (0,2,0),(0,2,1),(0,2,2),(0,2,3) ]
--       ]
--     , [ [ (1,0,0),(1,0,1),(1,0,2),(1,0,3) ]
--       , [ (1,1,0),(1,1,1),(1,1,2),(1,1,3) ]
--       , [ (1,2,0),(1,2,1),(1,2,2),(1,2,3) ]
--       ]
--     ])
--   
--   &gt;&gt;&gt; transposeInner arr
--   (Array D Seq (3 :&gt; 2 :. 4)
--     [ [ [ (0,0,0),(0,0,1),(0,0,2),(0,0,3) ]
--       , [ (1,0,0),(1,0,1),(1,0,2),(1,0,3) ]
--       ]
--     , [ [ (0,1,0),(0,1,1),(0,1,2),(0,1,3) ]
--       , [ (1,1,0),(1,1,1),(1,1,2),(1,1,3) ]
--       ]
--     , [ [ (0,2,0),(0,2,1),(0,2,2),(0,2,3) ]
--       , [ (1,2,0),(1,2,1),(1,2,2),(1,2,3) ]
--       ]
--     ])
--   </pre>
transposeInner :: (Index (Lower ix), Source r' ix e) => Array r' ix e -> Array D ix e

-- | Transpose outer two dimensions of at least rank-2 array.
--   
--   <h3><b>Examples</b></h3>
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (2 :&gt; 3 :. 4) fromIx3
--   
--   &gt;&gt;&gt; arr
--   (Array U Seq (2 :&gt; 3 :. 4)
--     [ [ [ (0,0,0),(0,0,1),(0,0,2),(0,0,3) ]
--       , [ (0,1,0),(0,1,1),(0,1,2),(0,1,3) ]
--       , [ (0,2,0),(0,2,1),(0,2,2),(0,2,3) ]
--       ]
--     , [ [ (1,0,0),(1,0,1),(1,0,2),(1,0,3) ]
--       , [ (1,1,0),(1,1,1),(1,1,2),(1,1,3) ]
--       , [ (1,2,0),(1,2,1),(1,2,2),(1,2,3) ]
--       ]
--     ])
--   
--   &gt;&gt;&gt; transposeOuter arr
--   (Array D Seq (2 :&gt; 4 :. 3)
--     [ [ [ (0,0,0),(0,1,0),(0,2,0) ]
--       , [ (0,0,1),(0,1,1),(0,2,1) ]
--       , [ (0,0,2),(0,1,2),(0,2,2) ]
--       , [ (0,0,3),(0,1,3),(0,2,3) ]
--       ]
--     , [ [ (1,0,0),(1,1,0),(1,2,0) ]
--       , [ (1,0,1),(1,1,1),(1,2,1) ]
--       , [ (1,0,2),(1,1,2),(1,2,2) ]
--       , [ (1,0,3),(1,1,3),(1,2,3) ]
--       ]
--     ])
--   </pre>
transposeOuter :: (Index (Lower ix), Source r' ix e) => Array r' ix e -> Array D ix e

-- | Rearrange elements of an array into a new one.
--   
--   <h3><b>Examples</b></h3>
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (2 :&gt; 3 :. 4) fromIx3
--   
--   &gt;&gt;&gt; arr
--   (Array U Seq (2 :&gt; 3 :. 4)
--     [ [ [ (0,0,0),(0,0,1),(0,0,2),(0,0,3) ]
--       , [ (0,1,0),(0,1,1),(0,1,2),(0,1,3) ]
--       , [ (0,2,0),(0,2,1),(0,2,2),(0,2,3) ]
--       ]
--     , [ [ (1,0,0),(1,0,1),(1,0,2),(1,0,3) ]
--       , [ (1,1,0),(1,1,1),(1,1,2),(1,1,3) ]
--       , [ (1,2,0),(1,2,1),(1,2,2),(1,2,3) ]
--       ]
--     ])
--   
--   &gt;&gt;&gt; backpermute (4 :. 3) (\(i :. j) -&gt; 0 :&gt; j :. i) arr
--   (Array D Seq (4 :. 3)
--     [ [ (0,0,0),(0,1,0),(0,2,0) ]
--     , [ (0,0,1),(0,1,1),(0,2,1) ]
--     , [ (0,0,2),(0,1,2),(0,2,2) ]
--     , [ (0,0,3),(0,1,3),(0,2,3) ]
--     ])
--   </pre>
backpermute :: (Source r' ix' e, Index ix) => Sz ix -> (ix -> ix') -> Array r' ix' e -> Array D ix e

-- | <i>O(1)</i> - Changes the shape of an array. Returns <a>Nothing</a> if
--   total number of elements does not match the source array.
resize :: (Index ix', Size r ix e) => Sz ix' -> Array r ix e -> Maybe (Array r ix' e)

-- | Same as <a>resize</a>, but will throw an error if supplied dimensions
--   are incorrect.
resize' :: (Index ix', Size r ix e) => Sz ix' -> Array r ix e -> Array r ix' e

-- | Extract a sub-array from within a larger source array. Array that is
--   being extracted must be fully encapsulated in a source array,
--   otherwise <a>Nothing</a> is returned,
extract :: Size r ix e => ix -> Sz ix -> Array r ix e -> Maybe (Array (EltRepr r ix) ix e)

-- | Same as <a>extract</a>, but will throw an error if supplied dimensions
--   are incorrect.
extract' :: Size r ix e => ix -> Sz ix -> Array r ix e -> Array (EltRepr r ix) ix e

-- | Similar to <a>extract</a>, except it takes starting and ending index.
--   Result array will not include the ending index.
extractFromTo :: Size r ix e => ix -> ix -> Array r ix e -> Maybe (Array (EltRepr r ix) ix e)

-- | Same as <a>extractFromTo</a>, but throws an error on invalid indices.
extractFromTo' :: Size r ix e => ix -> ix -> Array r ix e -> Array (EltRepr r ix) ix e

-- | Append two arrays together along a particular dimension. Sizes of both
--   arrays must match, with an allowed exception of the dimension they are
--   being appended along, otherwise <a>Nothing</a> is returned.
--   
--   <h3><b>Examples</b></h3>
--   
--   Append two 2D arrays along both dimensions. Note that they have the
--   same shape.
--   
--   <pre>
--   &gt;&gt;&gt; let arrA = makeArrayR U Seq (2 :. 3) (\(i :. j) -&gt; ('A', i, j))
--   
--   &gt;&gt;&gt; let arrB = makeArrayR U Seq (2 :. 3) (\(i :. j) -&gt; ('B', i, j))
--   
--   &gt;&gt;&gt; append 1 arrA arrB
--   Just (Array D Seq (2 :. 6)
--     [ [ ('A',0,0),('A',0,1),('A',0,2),('B',0,0),('B',0,1),('B',0,2) ]
--     , [ ('A',1,0),('A',1,1),('A',1,2),('B',1,0),('B',1,1),('B',1,2) ]
--     ])
--   
--   &gt;&gt;&gt; append 2 arrA arrB
--   Just (Array D Seq (4 :. 3)
--     [ [ ('A',0,0),('A',0,1),('A',0,2) ]
--     , [ ('A',1,0),('A',1,1),('A',1,2) ]
--     , [ ('B',0,0),('B',0,1),('B',0,2) ]
--     , [ ('B',1,0),('B',1,1),('B',1,2) ]
--     ])
--   </pre>
--   
--   Now appending arrays with different sizes:
--   
--   <pre>
--   &gt;&gt;&gt; let arrC = makeArrayR U Seq (2 :. 4) (\(i :. j) -&gt; ('C', i, j))
--   
--   &gt;&gt;&gt; append 1 arrA arrC
--   Just (Array D Seq (2 :. 7)
--     [ [ ('A',0,0),('A',0,1),('A',0,2),('C',0,0),('C',0,1),('C',0,2),('C',0,3) ]
--     , [ ('A',1,0),('A',1,1),('A',1,2),('C',1,0),('C',1,1),('C',1,2),('C',1,3) ]
--     ])
--   
--   &gt;&gt;&gt; append 2 arrA arrC
--   Nothing
--   </pre>
append :: (Source r1 ix e, Source r2 ix e) => Dim -> Array r1 ix e -> Array r2 ix e -> Maybe (Array D ix e)

-- | Same as <a>append</a>, but will throw an error instead of returning
--   <a>Nothing</a> on mismatched sizes.
append' :: (Source r1 ix e, Source r2 ix e) => Dim -> Array r1 ix e -> Array r2 ix e -> Array D ix e

-- | <i>O(1)</i> - Split an array at an index along a specified dimension.
splitAt :: (Size r ix e, r' ~ EltRepr r ix) => Dim -> Int -> Array r ix e -> Maybe (Array r' ix e, Array r' ix e)

-- | Same as <a>splitAt</a>, but will throw an error instead of returning
--   <a>Nothing</a> on wrong dimension and index out of bounds.
splitAt' :: (Size r ix e, r' ~ EltRepr r ix) => Dim -> Int -> Array r ix e -> (Array r' ix e, Array r' ix e)

-- | Create an array by traversing a source array.
traverse :: (Source r1 ix1 e1, Index ix) => Sz ix -> ((ix1 -> e1) -> ix -> e) -> Array r1 ix1 e1 -> Array D ix e

-- | Create an array by traversing two source arrays.
traverse2 :: (Source r1 ix1 e1, Source r2 ix2 e2, Index ix) => Sz ix -> ((ix1 -> e1) -> (ix2 -> e2) -> ix -> e) -> Array r1 ix1 e1 -> Array r2 ix2 e2 -> Array D ix e

-- | <i>O(1)</i> - Slices the array from the outside. For 2-dimensional
--   array this will be equivalent of taking a row. Throws an error when
--   index is out of bounds.
--   
--   <h3><b>Examples</b></h3>
--   
--   You could say that slicing from outside is synonymous to slicing from
--   the end or slicing at the highermost dimension. For example with
--   rank-3 arrays outer slice would be equivalent to getting a page:
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (3 :&gt; 2 :. 4) fromIx3
--   
--   &gt;&gt;&gt; arr
--   (Array U Seq (3 :&gt; 2 :. 4)
--     [ [ [ (0,0,0),(0,0,1),(0,0,2),(0,0,3) ]
--       , [ (0,1,0),(0,1,1),(0,1,2),(0,1,3) ]
--       ]
--     , [ [ (1,0,0),(1,0,1),(1,0,2),(1,0,3) ]
--       , [ (1,1,0),(1,1,1),(1,1,2),(1,1,3) ]
--       ]
--     , [ [ (2,0,0),(2,0,1),(2,0,2),(2,0,3) ]
--       , [ (2,1,0),(2,1,1),(2,1,2),(2,1,3) ]
--       ]
--     ])
--   
--   &gt;&gt;&gt; arr !&gt; 2
--   (Array M Seq (2 :. 4)
--     [ [ (2,0,0),(2,0,1),(2,0,2),(2,0,3) ]
--     , [ (2,1,0),(2,1,1),(2,1,2),(2,1,3) ]
--     ])
--   </pre>
--   
--   There is nothing wrong with chaining, mixing and matching slicing
--   operators, or even using them to index arrays:
--   
--   <pre>
--   &gt;&gt;&gt; arr !&gt; 2 !&gt; 0 !&gt; 3
--   (2,0,3)
--   
--   &gt;&gt;&gt; arr !&gt; 2 &lt;! 3 ! 0
--   (2,0,3)
--   
--   &gt;&gt;&gt; arr !&gt; 2 !&gt; 0 !&gt; 3 == arr ! 2 :&gt; 0 :. 3
--   True
--   </pre>
(!>) :: OuterSlice r ix e => Array r ix e -> Int -> Elt r ix e
infixl 4 !>

-- | <i>O(1)</i> - Just like <a>!&gt;</a> slices the array from the
--   outside, but returns <a>Nothing</a> when index is out of bounds.
(!?>) :: OuterSlice r ix e => Array r ix e -> Int -> Maybe (Elt r ix e)
infixl 4 !?>

-- | <i>O(1)</i> - Safe slicing continuation from the outside. Similarly to
--   (<a>!&gt;</a>) slices the array from the outside, but takes
--   <a>Maybe</a> array as input and returns <a>Nothing</a> when index is
--   out of bounds.
--   
--   <h3><b>Examples</b></h3>
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (3 :&gt; 2 :. 4) fromIx3
--   
--   &gt;&gt;&gt; arr !?&gt; 2 ??&gt; 0 ??&gt; 3
--   Just (2,0,3)
--   
--   &gt;&gt;&gt; arr !?&gt; 2 ??&gt; 0 ??&gt; -1
--   Nothing
--   
--   &gt;&gt;&gt; arr !?&gt; -2 ??&gt; 0 ?? 1
--   Nothing
--   </pre>
(??>) :: OuterSlice r ix e => Maybe (Array r ix e) -> Int -> Maybe (Elt r ix e)
infixl 4 ??>

-- | <i>O(1)</i> - Similarly to (<a>!&gt;</a>) slice an array from an
--   opposite direction.
(<!) :: InnerSlice r ix e => Array r ix e -> Int -> Elt r ix e
infixl 4 <!

-- | <i>O(1)</i> - Safe slice from the inside
(<!?) :: InnerSlice r ix e => Array r ix e -> Int -> Maybe (Elt r ix e)
infixl 4 <!?

-- | <i>O(1)</i> - Safe slicing continuation from the inside
(<??) :: InnerSlice r ix e => Maybe (Array r ix e) -> Int -> Maybe (Elt r ix e)
infixl 4 <??

-- | <i>O(1)</i> - Slices the array in any available dimension. Throws an
--   error when index is out of bounds or dimensions is invalid.
--   
--   <pre>
--   arr !&gt; i == arr &lt;!&gt; (dimensions (size arr), i)
--   </pre>
--   
--   <pre>
--   arr &lt;! i == arr &lt;!&gt; (1,i)
--   </pre>
(<!>) :: Slice r ix e => Array r ix e -> (Dim, Int) -> Elt r ix e
infixl 4 <!>

-- | <i>O(1)</i> - Same as (<a>&lt;!&gt;</a>), but fails gracefully with a
--   <a>Nothing</a>, instead of an error
(<!?>) :: Slice r ix e => Array r ix e -> (Dim, Int) -> Maybe (Elt r ix e)
infixl 4 <!?>

-- | <i>O(1)</i> - Safe slicing continuation from within.
(<??>) :: Slice r ix e => Maybe (Array r ix e) -> (Dim, Int) -> Maybe (Elt r ix e)
infixl 4 <??>

-- | Convert a flat list into a vector
fromList :: (Nested LN Ix1 e, Nested L Ix1 e, Ragged L Ix1 e, Mutable r Ix1 e) => Comp -> [e] -> Array r Ix1 e

-- | <i>O(n)</i> - Convert a nested list into an array. Nested list must be
--   of a rectangular shape, otherwise a runtime error will occur. Also,
--   nestedness must match the rank of resulting array, which should be
--   specified through an explicit type signature.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; fromLists Seq [[1,2],[3,4]] :: Maybe (Array U Ix2 Int)
--   Just (Array U Seq (2 :. 2)
--     [ [ 1,2 ]
--     , [ 3,4 ]
--     ])
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; fromLists Par [[[1,2,3]],[[4,5,6]]] :: Maybe (Array U Ix3 Int)
--   Just (Array U Par (2 :&gt; 1 :. 3)
--     [ [ [ 1,2,3 ]
--       ]
--     , [ [ 4,5,6 ]
--       ]
--     ])
--   </pre>
--   
--   Elements of a boxed array could be lists themselves if necessary, but
--   cannot be ragged:
--   
--   <pre>
--   &gt;&gt;&gt; fromLists Seq [[[1,2,3]],[[4,5]]] :: Maybe (Array B Ix2 [Int])
--   Just (Array B Seq (2 :. 1)
--     [ [ [1,2,3] ]
--     , [ [4,5] ]
--     ])
--   
--   &gt;&gt;&gt; fromLists Seq [[[1,2,3]],[[4,5]]] :: Maybe (Array B Ix3 Int)
--   Nothing
--   </pre>
fromLists :: (Nested LN ix e, Nested L ix e, Ragged L ix e, Mutable r ix e) => Comp -> [ListItem ix e] -> Maybe (Array r ix e)

-- | Same as <a>fromLists</a>, but will throw an error on irregular shaped
--   lists.
--   
--   <b>Note</b>: This function is the same as if you would turn on <tt>{-#
--   LANGUAGE OverloadedLists #-}</tt> extension. For that reason you can
--   also use <a>fromList</a>.
--   
--   <pre>
--   fromLists' Seq xs == fromList xs
--   </pre>
--   
--   <h3><b>Examples</b></h3>
--   
--   Convert a list of lists into a 2D Array
--   
--   <pre>
--   &gt;&gt;&gt; fromLists' Seq [[1,2],[3,4]] :: Array U Ix2 Int
--   (Array U Seq (2 :. 2)
--     [ [ 1,2 ]
--     , [ 3,4 ]
--     ])
--   </pre>
--   
--   Above example implemented using GHC's <tt>OverloadedLists</tt>
--   extension:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedLists
--   
--   &gt;&gt;&gt; [[1,2],[3,4]] :: Array U Ix2 Int
--   (Array U Seq (2 :. 2)
--     [ [ 1,2 ]
--     , [ 3,4 ]
--     ])
--   </pre>
--   
--   Example of failure on conversion of an irregular nested list.
--   
--   <pre>
--   &gt;&gt;&gt; fromLists' Seq [[1],[3,4]] :: Array U Ix2 Int
--   (Array U *** Exception: Too many elements in a row
--   </pre>
fromLists' :: (Nested LN ix e, Nested L ix e, Ragged L ix e, Mutable r ix e) => Comp -> [ListItem ix e] -> Array r ix e

-- | Convert any array to a flat list.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; toList $ makeArrayR U Seq (2 :. 3) fromIx2
--   [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2)]
--   </pre>
toList :: Source r ix e => Array r ix e -> [e]

-- | <i>O(n)</i> - Convert an array into a nested list. Array rank and list
--   nestedness will always match, but you can use <a>toList</a>,
--   <a>toLists2</a>, etc. if flattening of inner dimensions is desired.
--   
--   <b>Note</b>: This function is almost the same as <a>toList</a>.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; let arr = makeArrayR U Seq (2 :&gt; 1 :. 3) fromIx3
--   
--   &gt;&gt;&gt; print arr
--   (Array U Seq (2 :&gt; 1 :. 3)
--     [ [ [ (0,0,0),(0,0,1),(0,0,2) ]
--       ]
--     , [ [ (1,0,0),(1,0,1),(1,0,2) ]
--       ]
--     ])
--   
--   &gt;&gt;&gt; toLists arr
--   [[[(0,0,0),(0,0,1),(0,0,2)]],[[(1,0,0),(1,0,1),(1,0,2)]]]
--   </pre>
toLists :: (Nested LN ix e, Nested L ix e, Construct L ix e, Source r ix e) => Array r ix e -> [ListItem ix e]

-- | Convert an array with at least 2 dimensions into a list of lists.
--   Inner dimensions will get flattened.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; toList2 $ makeArrayR U Seq (2 :. 3) fromIx2
--   [[(0,0),(0,1),(0,2)],[(1,0),(1,1),(1,2)]]
--   
--   &gt;&gt;&gt; toList2 $ makeArrayR U Seq (2 :&gt; 1 :. 3) fromIx3
--   [[(0,0,0),(0,0,1),(0,0,2)],[(1,0,0),(1,0,1),(1,0,2)]]
--   </pre>
toLists2 :: (Source r ix e, Index (Lower ix)) => Array r ix e -> [[e]]

-- | Convert an array with at least 3 dimensions into a 3 deep nested list.
--   Inner dimensions will get flattened.
toLists3 :: (Index (Lower (Lower ix)), Index (Lower ix), Source r ix e) => Array r ix e -> [[[e]]]

-- | Convert an array with at least 4 dimensions into a 4 deep nested list.
--   Inner dimensions will get flattened.
toLists4 :: (Index (Lower (Lower (Lower ix))), Index (Lower (Lower ix)), Index (Lower ix), Source r ix e) => Array r ix e -> [[[[e]]]]
