lue-bird/elm-typesafe-array - version: 34.0.1

for more information visit the package's GitHub page

Package contains the following modules:

elm typesafe array

Knowing more about the length of an Array at compile-time to help you access elements safely

ticTacToeBoard
    |> ArraySized.element ( Up, n2 )
    |> ArraySized.element ( Up, n1 )

gives the element, no Maybe if ticTacToeBoard's type proves it contains enough elements. Such a type could be:

type alias TicTacToeBoard =
    -- 3 by 3
    ArraySized (ArraySized Field (Exactly (On N3))) (Exactly (On N3))

type Field
    = Empty
    | X
    | O

ticTacToeBoard : TicTacToeBoard
ticTacToeBoard =
    ArraySized.l3
        (ArraySized.l3 Empty Empty O)
        (ArraySized.l3 Empty O Empty)
        (ArraySized.l3 O Empty Empty)

ticTacToeBoard
    |> ArraySized.element ( Up, n2 )
    |> ArraySized.element ( Up, n1 )
--→ Empty (indexes start with 1)

We & the compiler knew there were enough elements in ticTacToeBoard

🧩

just a quick look will be fine. You can always come back to understand types etc. deeper

Let's define & use operations for all kinds of ranges ↓

a minimum length?

import Linear exposing (Direction(..)) -- .. = Up, Down
import N exposing (In, On, Add1)
import ArraySized exposing (ArraySized)

last :
    ArraySized element (In (On (Add1 minFrom1_)) max_)
    -> element
last =
    ArraySized.element ( Down, n1 ) -- indexes start with 1

greatest :
    ArraySized comparable (In (On (Add1 minFrom1_)) max_)
    -> comparable
greatest =
    ArraySized.fold Up max

first ArraySized.empty -- compile-time error
greatest ArraySized.empty -- compile-time error

ArraySized ... (In (On (Add1 minFrom1_)) max_) means what exactly? → It constrains the length of possible ArraySizeds:

length is In a range - the minimum length constraint is, without adding anything, on 1 + a variable (1 + 0 | 1 + 1 | 1 + ...) → On (Add1 minFrom1_) - any maximum length constraint is allowed (even no maximum at all) → max_

The types are explained in more detail in bounded-nat

an exact length?

Like in the tic-tac-toe example

import Linear exposing (Direction(..))
import N exposing (n2, n4, n7, n8, N8, Exactly, On)
import ArraySized exposing (ArraySized)

type alias ChessBoard =
    -- 8 by 8
    ArraySized (ArraySized Field (Exactly (On N8))) (Exactly (On N8))

type Field
    = Empty
    | Piece PieceKind Color

type PieceKind
    = Pawn
    | Other --...

type Color
    = Black
    | White

initialChessBoard : ChessBoard
initialChessBoard =
    let
        pawnRow color =
            ArraySized.repeat (Piece Pawn color) n8
        firstRow color =
            ArraySized.repeat (Piece Other color) n8
    in
    ArraySized.empty
        |> ArraySized.push (firstRow White)
        |> ArraySized.push (pawnRow White)
        |> ArraySized.attach Up
            (ArraySized.repeat (ArraySized.repeat Empty n8) n4)
        |> ArraySized.push (pawnRow Black)
        |> ArraySized.push (firstRow Black)

initialChessBoard
    |> ArraySized.element ( Up, n2 )
    |> ArraySized.element ( Up, n7 )
--> Piece Pawn White
--  (indexes start with 1)

a maximum length?

import N exposing (In, Up, To, N16)
import ArraySized exposing (ArraySized)

-- the max tag count should be 16
tag :
    ArraySized String (In min_ (Up maxTo16_ To N16))
    -> (Metadata -> MetadataTagged)
tag tags =
    ...

tag (ArraySized.l3 "fun" "easy" "simple") -- valid
tag (ArraySized.repeat "into-the-trends" n100) -- type error

ready? go!

Orasund's static-array – comparison

typesafe-array development started before static-array was published but the ideas are similar

create

append

length in a range

anything static-array is better at?