Copyright | (c) Christopher Chalmers |
---|---|

License | BSD3 |

Maintainer | Christopher Chalmers |

Stability | experimental |

Portability | non-portable |

Safe Haskell | None |

Language | Haskell2010 |

Contains QuasiQuotes and TemplateHaskell utilities for creating dense arrays, stencils and fixed length vectors.

The parser for the QuasiQuotes is still a work in progress.

- dense :: QuasiQuoter
- v :: QuasiQuoter
- stencil :: QuasiQuoter
- class Shape f => ShapeLift f where
- mkStencilTH :: (ShapeLift f, Lift a) => [(f Int, a)] -> Q Exp
- mkStencilTHBy :: ShapeLift f => (a -> Q Exp) -> [(f Int, a)] -> Q Exp

# Creating dense arrays

dense :: QuasiQuoter Source #

QuasiQuoter for producing a dense arrays using a custom parser.
Values are space separated, while also allowing infix expressions
(like `5/7`

). If you want to apply a function, it should be done in
brackets. Supports 1D, 2D and 3D arrays.

The number of rows/columns must be consistent thought out the array.

### Examples

[`dense`

| 5 -3 1 -3 5 |] :: (`R1`

f,`Vector`

v a,`Num`

a) =>`Array`

v f a

chars ::`UArray`

`V2`

`Char`

chars :: [`dense`

| 'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' |]

- 3D arrays are of the following form. Note the order in which
`dense`

formats the array. The array`a`

is such that`a !`

`V3`

x y z = "xyz"

a ::`BArray`

`V3`

`String`

a = [`dense`

| "000" "100" "200" "010" "110" "210" "020" "120" "220" "001" "101" "201" "011" "111" "211" "021" "121" "221" "002" "102" "202" "012" "112" "212" "022" "122" "222" |]

# Fixed length vector

v :: QuasiQuoter Source #

Type safe `QuasiQuoter`

for fixed length vectors `V`

. Values are
space separated. Can be used as expressions or patterns.

`[v| x y z w q r |] :: ``V`

6 a

Note this requires `DataKinds`

. Also requires `ViewPatterns`

if `v`

is used as a pattern.

### Examples

>>> let a = [v| 1 2 3 4 5 |] >>> :t a a :: Num a => V 5 a >>> a V {toVector = [1,2,3,4,5]} >>> let f [v| a b c d e |] = (a,b,c,d,e) >>> :t f f :: V 5 t -> (t, t, t, t, t) >>> f a (1,2,3,4,5)

Variables and infix expressions are also allowed. Negative values can
be expressed by a leading `-`

with a space before but no space
after.

>>> let b x = [v| 1/x 2 / x (succ x)**2 x-2 x - 3 -x |] >>> b Debug.SimpleReflect.a V {toVector = [1 / a,2 / a,succ a**2,a - 2,a - 3,negate a]}

# Stencils

stencil :: QuasiQuoter Source #

QuasiQuoter for producing a static stencil definition. This is a
versatile parser for 1D, 2D and 3D stencils. The parsing is similar
to `dense`

but `stencil`

also supports `_`

, which means ignore this
element. Also, stencils should have an odd length in all dimensions
so there is always a center element (which is used as `zero`

).

### Examples

- 1D stencils are of the form

[`stencil`

| 5 -3 1 -3 5 |] ::`Num`

a =>`Stencil`

`V1`

a

- 2D stencils are of the form

myStencil2 ::`Num`

a =>`Stencil`

`V2`

a myStencil2 = [`stencil`

| 0 1 0 1 0 1 0 1 0 |]

- 3D stencils have gaps between planes.

myStencil3 ::`Fractional`

a =>`Stencil`

`V3`

a myStencil3 :: [`stencil`

| 1/20 3/10 1/20 3/10 1 3/10 1/20 3/10 1/20 3/10 1 3/10 1 _ 1 3/10 1 3/10 1/20 3/10 1/20 3/10 1 3/10 1/20 3/10 1/20 |]

Variables can also be used

myStencil2' :: a -> a -> a ->`Stencil`

`V2`

a myStencil2' a b c = [`stencil`

| c b c b a b c b c |]

## Stencils from lists

mkStencilTH :: (ShapeLift f, Lift a) => [(f Int, a)] -> Q Exp Source #

Construct a `Stencil`

by unrolling the list at compile time. For
example

`ifoldr`

f b $(`mkStencilTH`

[(`V1`

(-1), 5), (`V1`

0, 3), (`V1`

1, 5)])

will be get turned into

f (`V1`

(-1)) 5 (f (`V1`

0) 3 (f (`V1`

1) 5 b))

at compile time. Since there are no loops and all target indexes are known at compile time, this can lead to more optimisations and faster execution times. This can lead to around a 2x speed up compared to folding over unboxed vectors.

myStencil = $(`mkStencilTH`

(as :: [(f`Int`

, a)])) ::`Stencil`

f a