Packed vectors : use these whenever possible. The generic vector type is is represented at run-time by a linked list of boxed values. Packed types, however, store the vector components sequentially in memory. Vector operations can be defined using the generic types, and the compiler will inline and specialize these definitions for the packed types, avoiding any list cells or unnecessary heap allocations.

Packed vectors are related to their unpacked representations by way of an
associated type. An instance of class

declares that `PackedVec`

v`v`

has
a packed representation, and the type of that is

. The packed
constructors are named `Packed`

v`Vec`

*NT* where *N* is 2, 3 or 4 and *T* is `I`

, `F`

or `D`

for `Int`

, `Float`

or `Double`

. So the expression `Vec3D x y z`

constructs a packed 3-vector of Doubles, the type of which is ```
Packed (Vec3
Double)
```

. The constructor name is also a synonym for the packed type name,
i.e., `type Vec3D = Packed (Vec3 Double)`

, so the packed type acts as if it
had been declared `data Vec3D = Vec3D x y z`

.

`Storable`

, `Num`

, `Fractional`

, `Fold`

, `Map`

, and `ZipWith`

instances are
provided for packed vectors, so some operations do not require pack/unpack.
For example,

does not require pack/unpack because it is defined in
terms of `dot`

and `zipWith`

. However `fold`

, `transpose`

,
`det`

and most others are recursive, and so you'll still need to
use pack/unpack with these. This goes for `gaussElim`

as well because it
uses `multmm`

. Some functions, like `transpose`

, do not need their
arguments to be unpacked, but the result is a polymorphic vector `multmv`

`(:.)`

, so
you will need to pack it again. I admit that this is awkward.

There are also instances for `Access`

, `Take`

, `Drop`

, `Last`

, `Head`

, `Tail`

and
`Snoc`

. These come in handy for things like quaternions and homogenous
coordinates.

- class PackedVec v where
- type Vec2I = Packed (Vec2 Int)
- type Vec3I = Packed (Vec3 Int)
- type Vec4I = Packed (Vec4 Int)
- type Vec2F = Packed (Vec2 Float)
- type Vec3F = Packed (Vec3 Float)
- type Vec4F = Packed (Vec4 Float)
- type Vec2D = Packed (Vec2 Double)
- type Vec3D = Packed (Vec3 Double)
- type Vec4D = Packed (Vec4 Double)
- type Mat22D = Vec2 Vec2D
- type Mat23D = Vec2 Vec3D
- type Mat24D = Vec2 Vec4D
- type Mat33D = Vec3 Vec3D
- type Mat34D = Vec3 Vec4D
- type Mat44D = Vec4 Vec4D
- packMat :: (Map row (Packed row) mat packedMat, PackedVec row) => mat -> packedMat
- unpackMat :: (Map (Packed row) row packedMat mat, PackedVec row) => packedMat -> mat