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]