|
1 | 1 | The `vector` package [](https://github.com/haskell/vector/actions?query=branch%3Amaster)
|
2 | 2 | ====================
|
3 | 3 |
|
4 |
| -An efficient implementation of `Int`-indexed arrays (both mutable and immutable), with a powerful loop optimisation framework. |
| 4 | +Vector is a collection of efficient `Int`-indexed array implementations: |
| 5 | +[boxed, unboxed, storable, and primitive vectors](#vectors-available-in-the-package) |
| 6 | +(all can be mutable or immutable). The package features a generic API, |
| 7 | +polymorphic in vector type, and implements [*stream fusion*](#stream-fusion), |
| 8 | +a powerful optimisation framework that can help eliminate intermediate data structures. |
5 | 9 |
|
6 |
| -See [`vector` on Hackage](http://hackage.haskell.org/package/vector) for more information. |
| 10 | +## Table of Contents |
| 11 | + |
| 12 | +<!-- no toc --> |
| 13 | +- [Tutorial](#tutorial) |
| 14 | +- [Vector vs Array](#vector-vs-array) |
| 15 | +- [Vectors Available in the Package](#vectors-available-in-the-package) |
| 16 | +- [Stream Fusion](#stream-fusion) |
| 17 | + |
| 18 | +## Tutorial |
| 19 | + |
| 20 | +A beginner-friendly tutorial for vectors can be found on |
| 21 | +[MMHaskell](https://mmhaskell.com/data-structures/vector). |
| 22 | + |
| 23 | + |
| 24 | +If you have already started your adventure with vectors, |
| 25 | +the tutorial on [Haskell Wiki](https://wiki.haskell.org/Numeric_Haskell:_A_Vector_Tutorial) |
| 26 | +covers more ground. |
| 27 | + |
| 28 | +## Vector vs Array |
| 29 | + |
| 30 | +Arrays are data structures that can store a multitude of elements |
| 31 | +and allow immediate access to every one of them. However, they are |
| 32 | +often seen as legacy constructs that are rarely used in modern Haskell. |
| 33 | +Even though Haskell has a built-in [Data.Array module](https://hackage.haskell.org/package/array-0.5.7.0), |
| 34 | +arrays might be a bit overwhelming to use due to their complex API. |
| 35 | +Conversely, vectors incorporate the array’s *O(1)* access to elements |
| 36 | +with a much friendlier API of lists. Since they allow for framework |
| 37 | +optimisation via loop fusion, vectors emphasise efficiency and keep |
| 38 | +a rich interface. Unless you’re confident with arrays, it’s |
| 39 | +well-advised to use vectors when looking for a similar functionality. |
| 40 | + |
| 41 | +## Vectors Available in the Package |
| 42 | + |
| 43 | +**Lazy boxed vectors** (`Data.Vector`) store each of their elements as a |
| 44 | +pointer to a heap-allocated value. Because of indirection, lazy boxed vectors |
| 45 | +are slower in comparison to unboxed vectors. |
| 46 | + |
| 47 | +**Strict boxed vectors** (`Data.Vector.Strict`) contain elements that are |
| 48 | +[strictly evaluated](https://tech.fpcomplete.com/haskell/tutorial/all-about-strictness/). |
| 49 | + |
| 50 | +**Unboxed vectors** (`Data.Vector.Unboxed`) determine an array's representation |
| 51 | +from its elements' type. For example, vector of primitive types (e.g. `Int`) will be |
| 52 | +backed by primitive array while vector of product types by structure of arrays. |
| 53 | +They are quite efficient due to the unboxed representation they use. |
| 54 | + |
| 55 | +**Storable vectors** (`Data.Vector.Storable`) are backed by pinned memory, i.e., |
| 56 | +they cannot be moved by the garbage collector. Their primary use case is C FFI. |
| 57 | + |
| 58 | +**Primitive vectors** (`Data.Vector.Primitive`) are backed by simple byte array and |
| 59 | +can store only data types that are represented in memory as a sequence of bytes without |
| 60 | +a pointer, i.e., they belong to the `Prim` type class, e.g., `Int`, `Double`, etc. |
| 61 | +It's advised to use unboxed vectors if you're looking for the performance of primitive vectors, |
| 62 | +but more versality. |
| 63 | + |
| 64 | +## Stream Fusion |
| 65 | + |
| 66 | +An optimisation framework used by vectors, stream fusion is a technique that merges |
| 67 | +several functions into one and prevents creation of intermediate data structures. For example, |
| 68 | +the expression `sum . filter g . map f` won't allocate temporary vectors if |
| 69 | +compiled with optimisations. |
0 commit comments