Copyright | (c) Jaro Reinders 2025 |
---|---|
License | BSD-3-Clause |
Maintainer | jaro.reinders@gmail.com |
Stability | experimental |
Portability | Portable |
Safe Haskell | Safe-Inferred |
Language | GHC2021 |
Fleet.Array
Description
This module defines fleet arrays and their basic interface.
All the asymptotic complexities listed in this module assume you are modifying the latest version of the array. Otherwise the performance regresses to O(k), where k is the number of changes between the version you are accessing and the latest version.
Synopsis
Documentation
Fleet arrays.
(!) :: Array a -> Int -> a Source #
Indexing an array. O(1)
WARNING: If you were to write your own swap
function. You might be
tempted to write it like this:
swap :: Int -> Int -> Array a -> Array a swap !i !j !xs = set i (xs ! j) (set j (xs ! i) xs)
Unfortunately, this leaves the order between the reads and writes undefined.
And in practice, GHC picks the wrong order. To enforce that reads happen
before writes, you can use tag
. See its documentation for more info.
index :: Int -> Array a -> (a, Token) Source #
Indexing an array. O(1)
The tuple and Token
serve two purposes:
- You can now separately force the evaluation of the tuple and the actual array element
- You can use the
Token
to with thetag
function on an array to force the indexing to happen before the array can be written to.
tag :: Token -> Array a -> Array a Source #
This is a no-op, but can be used to enforce an ordering between indexing and other array operations, to avoid the overhead of indexing from older versions of the array.
For example, swapping two elements in an array by using index
and set
can be done like this:
swap :: Int -> Int -> Array a -> Array a swap i j xs = let (x, t1) = index i xs (y, t2) = index j xs in set i y (set j x (tag t1 (tag t2 xs)))
This ensures the indexing happens before the setting.
set :: Int -> a -> Array a -> Array a Source #
Update the array element at a given position to a new value. O(1)