Monoidal array builder which should have much better performance than pure concatenation because it mutates the underling array.
Please be aware that
JS engines are generaly optimized for
snoc) operation - O(1) vs
cons) operation - O(n). We have here characteristic which is opposite to the
Use it for relatively small arrays (length < 10000) otherwise you can get
build... or just a crash (call stack overflow) in the case of
Let me start with imports. This README is a part of the test suite so we need them.
module Test.README where import Prelude -- We are working with constant sized arrays -- here so `unsafeBuild` is actually pretty safe ;-) import Data.Array ((..)) import Data.Array.Builder (cons, consArray, snoc, snocArray, unsafeBuild, (:>), (+>), (<:), (<+), build) import Data.Foldable (foldMap) import Data.Maybe (Maybe(..)) import Data.Monoid as Monoid import Effect (Effect) import Test.Assert (assert)
<> is right associative so it works in practice as follows:
suite ∷ Effect Unit suite = do assert $ unsafeBuild (cons 8 <> cons 9 <> cons 10 <> mempty) == [8, 9, 10]
assert $ unsafeBuild (snoc 8 <> snoc 9 <> snoc 10 <> mempty) == [10, 9, 8]
I'm not a huge fun of custom operators but in the case of
Array constructors I feel that
they are pretty useful. So we have right (
consArray) and left (
associative operators provided by the lib which "should" behave as you would expect when mixed:
assert $ unsafeBuild (-3 :> [-2, -1] +> 0 :> mempty <: 1 <+ [2, 3] <: 4) == -3..4
this API works nicely with tools like
foldMap etc. because we have a "pretty" performant
let b = snoc 5 -- | It could be `foldMap snoc [3, 4]` as well -- | but `snocArray` is a single `push`. <> Monoid.guard true (snocArray [3, 4]) <> snoc 2 <> foldMap snoc (Just 1) <> Monoid.guard false (cons 0) assert (unsafeBuild b == (1..5))
The above example uses consistently more performant
snoc* operations - mixing
<> can be tricky sometimes
because we have to think about the order of the actual operations...
So I prefer my fancy operators. Everyones loves their own lovely, clean and consistent operators and...
not like the others ugly, unkown and unreadable operators ;-)
"And now for something completely different..." Let's blow up the stack:
assert $ build (foldMap snoc (1..20000)) == Nothing
$ npm test