lue-bird/elm-typesafe-array/18.0.1

NOTE: the latest version is 34.0.1

MinArr

If the length is Min or the maximum length is a type variable:

first :
    Arr (In (Nat1Plus minMinus1_) max_) element
    -> element

use these operations instead of the ones in Arr or InArr.

modify

element
-> Arr (In minLength maxLength_) element
-> Arr (Min (Nat1Plus minLength)) element

Put a new element after the others.

atLeast5Elements
    |> MinArr.push "becomes the last"
--> : Arr (Min Nat6) String
Nat (ArgIn indexMin_ minLengthMinus1 indexIfN_)
-> LinearDirection
-> Arr (In (Nat1Plus minLengthMinus1) maxLength) element
-> Arr (In minLengthMinus1 maxLength) element

Kick out the element at an index in a direction.

removeLast atLeast1Element =
    atLeast1Element
        |> MinArr.removeAt nat0 LastToFirst
Nat (ArgIn indexMin_ minLength indexIfN_)
-> LinearDirection
-> element
-> Arr (In minLength maxLength_) element
-> Arr (Min (Nat1Plus minLength)) element

Put a new element at an index in a direction.

atLeast5Elements
    |> MinArr.insertAt nat0 LastToFirst
        "becomes the last"
--> : Arr (Min Nat6) String


cons :
    element
    -> Arr (In minLength maxLength_) element
    -> Arr (Min (Nat1Plus minLength)) element
cons =
    MinArr.insertAt nat0 FirstToLast
element
-> Nat
(N
minLength
atLeastMinLength_
(Is minLength To (Nat1Plus minDoubleLengthMinus1))
minIs_
)
-> Arr (In minLength maxLength_) element
-> Arr (Min minDoubleLengthMinus1) element

Place a value between all members.

To get the correct final length type, we need to give the current minimum length as an arguments.

atLeast3Turtles
    |> MinArr.intersperse "on" nat3
--> "turtles" "on" "turtles" "on" "turtles" ...
--> : Arr (Min Nat5) String

glue

Nat
(N
minAdded
atLeastMinAdded_
(Is minLength To minLengthSum)
is_
)
-> Arr (In minAdded maxAdded_) element
-> Arr (In minLength maxLength_) element
-> Arr (Min minLengthSum) element

Attach elements of an Arr to the right.

Arr.from3 1 2 3
    |> MinArr.append nat3
        atLeast3Elements
--> : Arr (Min Nat6) ...
Nat
(N
minAdded
atLeastMinAdded_
(Is minLength To minLengthSum)
is_
)
-> Arr (In minAdded maxAdded_) element
-> Arr (In minLength maxLength_) element
-> Arr (Min minLengthSum) element

Add elements of an Arr to the left.

Arr.from3 1 2 3
    |> MinArr.prepend nat3
        atLeast3Elements
--> : Arr (Min Nat6) ...

part

Nat (N dropped_ atLeastDropped_ (Is minTaken To minLength) is_)
-> LinearDirection
-> Arr (In minLength maxLength) element
-> Arr (In minTaken maxLength) element

Elements after a certain number of elements in a direction.

atLeast6Elements
    |> MinArr.drop nat2 LastToFirst
--> : Arr (Min Nat4) ...

scan length

Nat
(N
(Nat1Plus nMinus1)
atLeastN
(Is a_ To (Nat1Plus nPlusAMinus1))
is_
)
-> { lowest :
Nat
(N
lowest
atLeastLowest_
(Is lowestToMin_ To minLength)
(Is minToValueMinus1_ To nMinus1)
)
}
-> Arr (In minLength maxLength_) element
-> LessOrEqualOrGreater
(Arr (In lowest nPlusAMinus1) element)
(Arr (In (Nat1Plus nMinus1) atLeastN) element)
(Arr (Min (Nat2Plus nMinus1)) element)

Compare its length to a given exact length. Is it LessOrEqualOrGreater?

lowest can be a number <= the minimum length.

convertUserArguments :
    String
    -> Result String (Arr (Only Nat3))
convertUserArguments =
    let
        wordArr =
            String.words arguments
                |> Arr.fromList
    in
    case
        wordArr
            |> MinArr.isLength nat3 { lowest = nat0 }
    of
        Nat.Equal only3 ->
            Ok only3


        Nat.Less atMost2 ->
            Err
                ("I need 3 arguments, but there are only "
                    ++ String.fromInt (val (Arr.length atMost2))
                    ++ "."
                )


        Nat.Greater atLeast4 ->
            Err
                ("I need exact 3 arguments, so "
                    ++ String.fromInt (val (Arr.length atLeast4))
                    ++ " is too much."
                )
Nat (ArgIn minLowerBound (Nat1Plus maxLowerBoundMinus1) ifN_)
-> { lowest :
Nat
(N
lowest
atLeastLowest_
(Is lowestToMin_ To minLength)
(Is lowestToMinLowerBound_ To minLowerBound)
)
}
-> Arr (In minLength maxLength_) element
-> BelowOrAtLeast
(Arr (In lowest maxLowerBoundMinus1) element)
(Arr (Min minLowerBound) element)

Compare its length to a given exact length. Is it BelowOrAtLeast that value?

lowest can be a number <= the minimum length.

convertUserArguments : String -> Result String (Arr (Min Nat3))
convertUserArguments arguments =
    let
        wordArr =
            String.words arguments
                |> Arr.fromList
    in
    case
        wordArr
            |> MinArr.isLengthAtLeast nat3 { lowest = nat0 }
    of
        Nat.EqualOrGreater atLeast3 ->
            Ok atLeast3


        Nat.Below atMost2 ->
            Err
                ("I need at least 3 arguments, but there are only "
                    ++ String.fromInt (val (Arr.length atMost2))
                    ++ "."
                )
Nat (ArgIn minUpperBound maxUpperBound ifN_)
-> { lowest :
Nat
(N
lowest
atLeastLowest_
(Is lowestToMin_ To minLength)
(Is lowestToMinUpperBound_ To minUpperBound)
)
}
-> Arr (In minLength maxLength_) element
-> AtMostOrAbove
(Arr (In lowest maxUpperBound) element)
(Arr (Min (Nat1Plus minUpperBound)) element)

Is its length AtMostOrAbove a given length?

lowest can be a number <= the minimum length.

-- only up to 50 tags
tag : Arr (In min Nat50) String -> a -> Tagged a


tagIfValidTags : Array String -> a -> Maybe (Tagged a)
tagIfValidTags array value =
    case
        array
            |> Arr.fromArray
            |> MinArr.isLengthAtMost nat50 { lowest = nat0 }
    of
        Nat.EqualOrLess atMost50 ->
            tag value atMost50 |> Just


        Nat.Above _ ->
            Nothing

transform

serialize

Nat (ArgIn minLength max_ ifN_)
-> ( { expected : { length : { atLeast : Nat (Min Nat0) } }
, actual : { length : Nat (Min Nat0) }
}
-> error
)
-> Codec error element
-> Codec error (Arr (Min minLength) element)

A Codec to serialize Arrs with a minimum amount of elements.

import Serialize exposing (Codec)




-- we can't start if we have no worlds to choose from
serializeSaves : Codec String (Arr (Min Nat1) World)
serializeSaves =
    MinArr.serialize nat1
        -- if we just want a simple error string
        MinArr.errorToString
        serializeWorld

The encode/decode functions can be extracted if needed.

encode : Arr (In (Nat1Plus minMinus1_) max_) World -> Bytes
encode =
    Arr.lowerMinLength nat1
        >> Arr.toMin
        >> Serialize.encodeToBytes serializeSaves


decode :
    Bytes
    ->
        Result
            (Serialize.Error String)
            (Arr (Min Nat1) World)
decode =
    Serialize.decodeFromBytes serializeSaves

error

type alias Error =
{ expected : { length : { atLeast : Nat (Min Nat0) } }
, actual : { length : Nat (Min Nat0) }
}

An error for when a decoded array has a length that's less than the expected minimum length. You can transform it into

See serialize.

generalizeError : Error -> Error

Convert its error to a Arr.Error: an error type that covers all cases where Array to Arr conversions can fail.

import Serialize exposing (Codec)


Serialize.mapError MinArr.generalizeError
--> : Codec MinArr.Error a -> Codec Arr.Error a

Use this if you serialize Arr (In ...) together with Arr (Min ...):

Serialize.tuple
    (MinArr.serialize nat10 ...)
    (InArr.serializeIn nat10 nat99 ...)
--> error : `Codec`s have different custom errors


Serialize.tuple
    (MinArr.serialize nat10 ...
        |> Serialize.mapError MinArr.generalizeError
    )
    (InArr.serializeIn nat10 nat99 ...)
--> Codec
-->     Arr.Error
-->     ( Arr (Min Nat0) ...
-->     , Arr (In Nat0 (Nat99Plus a_)) ...
-->     )

Note: There's also errorToString.

errorToString : Error -> String

Convert the serialization error into a readable message.

{ expected = { length = { atLeast = nat11 } }
, actual = { length = 10 }
}
    |> MinArr.errorToString
--> "Expected an array of length >= 11, but the actual length was 10."

(example doesn't compile)

Equivalent to

error
    |> MinArr.generalizeError
    |> Arr.errorToString