6. Arrays (vectors)

haskus-binary supports vectors: a fixed amount of Storable data correctly aligned. You can define a vector as follows:

{-# LANGUAGE DataKinds #-}

import Haskus.Format.Binary.Vector as V

v :: Vector 5 Word16

Vectors are storable, so you can peek and poke them from memory. Alternatively, you can create them from a list:

Just v = fromList [1,2,3,4,5]
Just v = fromList [1,2,3,4,5,6] -- this fails dynamically
Just v = fromList [1,2,3,4]     -- this fails dynamically

-- take at most 5 elements then fill with 0: v = [1,2,3,4,5]
v = fromFilledList 0 [1,2,3,4,5,6]

-- take at most 5 elements then fill with 7: v = [1,2,3,7,7]
v = fromFilledList 7 [1,2,3]

-- take at most 4 (!) elements then fill with 0: v = [1,2,3,0,0]
v = fromFilledListZ 0 [1,2,3]

-- useful for zero-terminal strings: s = "too long \NUL"
s :: Vector 10 CChar
s = fromFilledListZ 0 (fmap castCharToCChar "too long string")

You can concatenate several vectors into a single one:

import Haskus.Utils.HList

x = fromFilledList 0 [1,2,3,4] :: Vector 4 Int
y = fromFilledList 0 [5,6]     :: Vector 2 Int
z = fromFilledList 0 [7,8,9]   :: Vector 3 Int

v = V.concat (x `HCons` y `HCons` z `HCons` HNil)

>:t v
v :: Vector 9 Int

> v
fromList [1,2,3,4,5,6,7,8,9]

You can also safely drop or take elements in a vector. You can also index into a vector:

import Haskus.Format.Binary.Vector as V

v :: Vector 5 Int
v = fromFilledList 0 [1,2,3,4,5,6]

-- v2 = [1,2]
v2 = V.take @2 v

-- won't compile (8 > 5)
v2 = V.take @8 v

-- v2 = [3,4,5]
v2 = V.drop @2 v

-- x = 3
x = V.index @2 v

Finally, you can obtain a list of the values

> V.toList v
[1,2,3,4,5]