fleet-array
Copyright(c) Jaro Reinders 2025
LicenseBSD-3-Clause
Maintainerjaro.reinders@gmail.com
Stabilityexperimental
PortabilityPortable
Safe HaskellSafe-Inferred
LanguageGHC2021

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

data Array a Source #

Fleet arrays.

Instances

Instances details
Show a => Show (Array a) Source # 
Instance details

Defined in Fleet.Array

Methods

showsPrec :: Int -> Array a -> ShowS #

show :: Array a -> String #

showList :: [Array a] -> ShowS #

fromList :: [a] -> Array a Source #

Convert a list into an array. O(n)

replicate :: Int -> a -> Array a Source #

toList :: Array a -> [a] Source #

Converting an array into a list. O(n)

(!) :: 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 the tag 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)

copy :: Array a -> Array a Source #

Copy an array. O(n) This detaches any future updates from old versions of the array. Use this when you know you will be updating a large part of an array.

swap :: Int -> Int -> Array a -> Array a Source #

Swap two elements in an array. O(1)