-- 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.1.6.1


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>

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

-- | 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>.

-- | 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>.

-- | 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>.

-- | 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>.

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

-- | Defines n-dimensional index by relating a general <a>IxN</a> with few
--   base cases.

-- | 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

-- | Unboxing of a <a>Ix2</a>.

-- | Unboxing of a <a>IxN</a>.

-- | 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 -> ix -> (ix -> e) -> ix -> e

-- | A way to select Array dimension.
newtype Dim
Dim :: Int -> Dim

-- | 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.

-- | 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 Rank ix :: Nat;
}

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

-- | Total number of elements in an array of this size.
totalElem :: Index ix => 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)

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

-- | Set the value for an index at specified dimension.
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

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

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

-- | Check whether index is within the size.
isSafeIndex :: Index ix => 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 => 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 => ix -> Int -> ix

-- | Compute an index from size and linear index
fromLinearIndex :: (Index ix, Index (Lower ix)) => 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 => 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)) => 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 => 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)) => 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 -> Int -> (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 -> Int -> (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 -> Int -> (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 -> Int -> (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 -> Int -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()

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

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

-- | Checks whether the size is valid.
isSafeSize :: Index ix => ix -> Bool

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

-- | Iterate over N-dimensional space from start to end with accumulator
iterLinearM :: (Index ix, Monad m) => ix -> Int -> Int -> Int -> (Int -> Int -> Bool) -> a -> (Int -> ix -> a -> m a) -> m a
iterLinearM_ :: (Index ix, Monad m) => 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
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><a>Rank</a> ix</tt>.

-- | 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 ()

-- | 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 -> 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 -> Lower 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
data L
L :: L
data LN

-- | 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.

-- | <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


module Data.Massiv.Array.Unsafe

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

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

-- | Create an array in parallel using mutable interface
unsafeGenerateArrayP :: Mutable r ix e => [Int] -> ix -> (ix -> e) -> Array r ix e
unsafeGenerateM :: (Ragged r ix e, Monad m) => Comp -> 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) => ix -> (ix -> ix') -> Array r' ix' e -> Array D ix e
unsafeTraverse :: (Source r1 ix1 e1, Index ix) => ix -> ((ix1 -> e1) -> ix -> e) -> Array r1 ix1 e1 -> Array D ix e
unsafeTraverse2 :: (Source r1 ix1 e1, Source r2 ix2 e2, Index ix) => 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') => 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 -> ix -> Array r ix e -> Array (EltRepr r ix) ix e
unsafeSlice :: Slice r ix e => Array r ix e -> ix -> 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 -> (Lower ix, Int) -> 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) => 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) => 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 ()

-- | 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.
forStencilUnsafe :: (Source r ix e, Manifest r ix e) => Array r ix e -> ix -> ix -> ((ix -> Maybe e) -> a) -> Array DW ix a


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 r1 Ix2 e, Mutable r2 Ix2 e, OuterSlice r1 Ix2 e, OuterSlice r2 Ix2 e, Source (EltRepr r1 Ix2) Ix1 e, Source (EltRepr r2 Ix2) Ix1 e, Num e) => Array r1 Ix2 e -> Array r2 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.Mutable
class Manifest r ix e => Mutable r ix e where {
    data family MArray s r ix e :: *;
}

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

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

-- | Initialize a new mutable array. Negative size will result in an empty
--   array.
new :: (Mutable r ix e, PrimMonad m) => 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)

-- | <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 ()

-- | <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 :: *

-- | 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 ()

-- | <i>O(n)</i> - Generate an array monadically using it's mutable
--   interface. Computation will be done sequentially, regardless of
--   <a>Comp</a> argument.
generateM :: (Monad m, Mutable r ix e) => Comp -> ix -> (ix -> m e) -> m (Array r ix e)

-- | <i>O(n)</i> - Same as <a>generateM</a> but using a flat index.
generateLinearM :: (Monad m, Mutable r ix e) => Comp -> ix -> (Int -> m e) -> m (Array r ix e)

-- | <i>O(n)</i> - Map a monadic action over an Array. This operation will
--   force computation sequentially and will result in a manifest Array.
--   
--   <h4><b>Examples</b></h4>
--   
--   <pre>
--   &gt;&gt;&gt; mapM P (\i -&gt; Just (i*i)) $ range Seq 0 5
--   Just (Array P Seq (5)
--     [ 0,1,4,9,16 ])
--   </pre>
mapM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> (e -> m e') -> Array r ix e -> m (Array r' ix e')

-- | <i>O(n)</i> - Map an index aware monadic action over an Array. This
--   operation will force computation sequentially and will result in a
--   manifest Array.
imapM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> (ix -> e -> m e') -> Array r ix e -> m (Array r' ix e')

-- | <i>O(n)</i> - Same as <a>mapM</a>, but with its arguments flipped.
forM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> Array r ix e -> (e -> m e') -> m (Array r' ix e')

-- | <i>O(n)</i> - Same as <a>imapM</a>, but with its arguments flipped.
iforM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> Array r ix e -> (ix -> e -> m e') -> m (Array r' ix e')

-- | <i>O(n)</i> - Sequence monadic actions in a source Array. This
--   operation will force the computation sequentially and will result in a
--   manifest Array.
sequenceM :: (Monad m, Source r ix (m e), Mutable r' ix e) => r' -> Array r ix (m e) -> m (Array r' ix 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

-- | 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

-- | Delayed Windowed Array representation.
data DW

-- | 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 -> ix -> (ix -> e) -> Array DW 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 -> 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 -> 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

-- | Match array representation to a vector type


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

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

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

-- | 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

-- | 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 originally created array, i.e. various
--   index manipulation functions that do slicing, extracting, etc. have no
--   affect on this pointer.
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


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

-- | 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) => Stencil ix e a -> Array r ix e -> Array DW ix a

-- | 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; Border a -&gt; Stencil Ix2 a a
--   average3x3Stencil b = makeStencil b (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) => Border e -> ix -> ix -> ((ix -> Value e) -> Value a) -> Stencil ix e a

-- | 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; Border e -&gt; Stencil Ix2 e e
--   sobelX b = makeConvolutionStencil b (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) => Border e -> 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) => Border e -> Array r ix e -> Stencil ix e e

-- | Make a <a>cross-correlation</a> stencil.
makeCorrelationStencil :: (Index ix, Num e) => Border e -> 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>makeCorrelationStencil</a> is used, but sometimes we
--   just really don't know the kernel at compile time.
makeCorrelationStencilFromKernel :: (Manifest r ix e, Num e) => Border e -> Array r ix e -> Stencil ix e 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 (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 -> 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 (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 -> 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 -> Ix1 -> (Ix1 -> e) -> Array r Ix1 e

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

-- | 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

-- | 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

-- | <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 :: (Mutable r' ix e, Mutable r ix e, Typeable ix, Typeable 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 :: (Mutable r' ix e, Mutable r ix e, Typeable ix, Typeable 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 -> 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

-- | 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 IO action, over an array in parallel, while discarding the
--   result.
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.
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. 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.
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

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

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

-- | <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) => 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) => 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) => 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 -> 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 -> 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)

-- | 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) => 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) => 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; (rank (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.
--   
--   <b>Note</b>: This function is almost the same (modulo customizable
--   computation strategy) if you would turn on <tt>{--}</tt>. For that
--   reason you can also use <a>fromList</a>.
--   
--   <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.
--   
--   <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 ceonversion 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; toList 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]]]]
