Safe Haskell | None |
---|---|

Language | Haskell98 |

The indices supplied by this module are static type and value-level linked lists. Since their type gives us information about them, recursion on indices can be unrolled easily.

Indices look like ` x:.y:.Z :: i:.j:.Z `

. The value is the actual index used,
and the type is the upper-bound on that index.

For instance, one index of a 4x4 matrix is ` 2:.2:.Z :: 3:.3:.Z `

, and
another index for a 1024x1024x1024 cube is
` 512:.512:.512:.Z :: 1024:.1024:.1024:.Z `

Parts of this module are alternatively under Static and Runtime headings. Functions under Static headings should be inlined completely, and functions under Runtime will not. If you do not compile with optimisations on, ghc will not inline the "static" functions, which will then perform very poorly compared to their "runtime" counterparts.

- class (Bounded n, Integral n, Show n, Read n, Ix n, Dim n) => Index n
- class Ord n => Dim n where
- class Rank a b where
- setBound :: a -> b

- data a :. b = !Int :. !b
- data Z = Z
- class (Dim n, Range (ToPeano (Size n))) => Ranged n
- class Range n
- data Peano
- type family ToPeano n :: Peano
- type family Size dim :: Nat
- sfoldlRange :: Ranged o => Proxy o -> (b -> o -> b) -> b -> b
- sfoldrRange :: Ranged o => Proxy o -> (o -> b -> b) -> b -> b
- swithRange :: (Applicative m, Ranged o) => Proxy o -> (o -> m ()) -> m ()
- foldlRange :: Dim a => Proxy a -> (b -> a -> b) -> b -> b
- foldrRange :: Dim a => Proxy a -> (a -> b -> b) -> b -> b
- withRange :: (Applicative m, Dim a) => Proxy a -> (a -> m ()) -> m ()
- sfoldlRangeIndices :: Ranged o => Proxy o -> (b -> Int -> b) -> b -> b
- sfoldrRangeIndices :: Ranged o => Proxy o -> (Int -> b -> b) -> b -> b
- swithRangeIndices :: (Applicative m, Ranged o) => Proxy o -> (Int -> m ()) -> m ()
- foldlRangeIndices :: Dim a => Proxy a -> (b -> Int -> b) -> b -> b
- foldrRangeIndices :: Dim a => Proxy a -> (Int -> b -> b) -> b -> b
- withRangeIndices :: (Applicative m, Dim a) => Proxy a -> (Int -> m ()) -> m ()
- bounds :: (Dim a, Bounded a) => Proxy a -> (a, a)
- range :: Dim n => [n]
- srange :: Ranged n => [n]
- dimHead :: KnownNat x => (x :. xs) -> Int
- dimTail :: (x :. xs) -> xs
- pdimHead :: KnownNat x => Proxy (x :. xs) -> Int
- pdimTail :: Proxy (x :. xs) -> Proxy xs
- dim :: QuasiQuoter
- module Data.Proxy

# Core

class (Bounded n, Integral n, Show n, Read n, Ix n, Dim n) => Index n Source

A single class encompassing all the instances an index should have.

class Ord n => Dim n where Source

zero, unit, rank, size, reflect', next, prev, next', prev', toIndex, fromIndex', correct, correctOnce, overHead, lastDim, zipMin

All zeros

All ones

The number of dimensions in an index

The size of the index

Same as `succ`

, but there are no boundary checks, so when `maxBound`

is
hit, it will wrap around to `minBound`

/ `zero`

.

Same as `pred`

, but there are no boundary checks, so when `minBound`

/ `zero`

is hit, it will wrap around to `maxBound`

.

Create an `Int`

index.

Create an index from its `Int`

representation.

Ensure an index is within its bounds.

Get the minimum values of two indices at each dimension

Index constructor, analogous to `:`

The `Applicative`

and `Monad`

instances multiply in their bind operations,
and their 'return'/'pure' creates an index whose first dimension is 1.

KnownNat s => Monad ((:.) Nat s) | |

Functor ((:.) k a) | |

KnownNat s => Applicative ((:.) Nat s) | |

Foldable ((:.) k a) | |

Traversable ((:.) k a) | |

Dim ((:.) k x xs) => Bounded ((:.) k x xs) | |

(Dim ((:.) k x xs), Num xs) => Enum ((:.) k x xs) | |

Eq b => Eq ((:.) k a b) | |

(Integral xs, Dim ((:.) k x xs)) => Integral ((:.) k x xs) | |

(Num xs, Dim ((:.) k x xs)) => Num ((:.) k x xs) | |

Ord b => Ord ((:.) k a b) | |

Read b => Read ((:.) k a b) | |

(Num ((:.) k x xs), Dim ((:.) k x xs)) => Real ((:.) k x xs) | |

Show b => Show ((:.) k a b) | |

(Dim ((:.) k x xs), Num xs) => Ix ((:.) k x xs) | |

Generic ((:.) k a b) | |

(Dim ((:.) k x xs), Monoid xs) => Monoid ((:.) k x xs) | |

(KnownNat x, Dim xs) => Dim ((:.) Nat x xs) | |

Rank xs ys => Rank ((:.) k x xs) ((:.) k y ys) | Rank |

type Rep ((:.) k a b) |

The zero index, used to end indices, just as '[]' ends a list.

# Ranges

class (Dim n, Range (ToPeano (Size n))) => Ranged n Source

Types that support static range operations

swithRange_, sfoldrRange_, sfoldlRange_, swithRangeIndices_, sfoldrRangeIndices_, sfoldlRangeIndices_

## Static

sfoldlRange :: Ranged o => Proxy o -> (b -> o -> b) -> b -> b Source

See `foldlRange`

With optimisations, this compiles to an unrolled loop

sfoldrRange :: Ranged o => Proxy o -> (o -> b -> b) -> b -> b Source

See `foldrRange`

With optimisations, this compiles to an unrolled loop

swithRange :: (Applicative m, Ranged o) => Proxy o -> (o -> m ()) -> m () Source

See `withRange`

With optimisations, this compiles to an unrolled loop

## Runtime

foldlRange :: Dim a => Proxy a -> (b -> a -> b) -> b -> b Source

Eager left fold over a range

`foldlRange`

r f z ==`foldl'`

f z (`asProxyTypeOf`

`range`

r)

foldrRange :: Dim a => Proxy a -> (a -> b -> b) -> b -> b Source

Lazy right fold over a range

`foldrRange`

r f z ==`foldr`

f z (`asProxyTypeOf`

`range`

r)

withRange :: (Applicative m, Dim a) => Proxy a -> (a -> m ()) -> m () Source

Compute something from a range

## Over `Int`

indices

### Static

sfoldlRangeIndices :: Ranged o => Proxy o -> (b -> Int -> b) -> b -> b Source

With optimisations, this compiles to an unrolled loop

sfoldrRangeIndices :: Ranged o => Proxy o -> (Int -> b -> b) -> b -> b Source

With optimisations, this compiles to an unrolled loop

swithRangeIndices :: (Applicative m, Ranged o) => Proxy o -> (Int -> m ()) -> m () Source

See `withRangeIndices`

With optimisations, this compiles to an unrolled loop

### Runtime

foldlRangeIndices :: Dim a => Proxy a -> (b -> Int -> b) -> b -> b Source

Strict left fold over the *raw* indices under a range

foldrRangeIndices :: Dim a => Proxy a -> (Int -> b -> b) -> b -> b Source

Lazy right fold over the *raw* indices under a range

withRangeIndices :: (Applicative m, Dim a) => Proxy a -> (Int -> m ()) -> m () Source

Compute something using the *raw* indices under a range

# Utility

bounds :: (Dim a, Bounded a) => Proxy a -> (a, a) Source

Create a bound for use with e.g. "Data.Array.array"

srange :: Ranged n => [n] Source

Statically generated range of an index

srange = sfoldrRange Proxy (:) []

# Syntax

dim :: QuasiQuoter Source

Expands to a `Proxy`

with the phantom type being the dimension specified
Works in types and expressions.

Examples:

id [dim|3 4 5|] ==> id (Proxy :: Proxy (3:.4:.5:.Z))

Proxy :: [dim|3 4 5|] ==> Proxy :: Proxy (3:.4:.5:.Z)

module Data.Proxy