An Arr describes an array where you know more about the amount of elements.
Array.empty |> Array.get 0
--> Nothing
Arr.empty |> Arr.at nat0 FirstToLast
--> compile time errorIs this any useful? Let's look at an example:
0 to 100 joined by a space
joinBy between =
\before after -> before ++ between ++ after
let
intStringsAfter =
Array.fromList (List.range 1 100)
String.fromInt
in
Array.foldl (joinBy " ") "0" intStringsAfter
--> "0 1 2 3 4 5 ..."
Arr.nats nat100
|> Arr.map (val >> String.fromInt)
|> Arr.foldWith FirstToLast (joinBy " ")
--> "0 1 2 3 4 5 ..."The Array version just seems hacky and is less readable. Arr simply knows more about the length at compile time, so you can e.g. call foldWith without a worry.
Create an Arr from an Array. As every Array has >= 0 elements:
Arr.fromArray arrayFromSomewhere
--> : Arr (ValueMin Nat0)
Arr.fromArray
(Array.fromList [ 0, 1, 2, 3, 4, 5, 6 ])
--> big no
Arr.from7 0 1 2 3 4 5 6
--> ok
Arr.nats nat7
--> big yesTell the compiler if you know the amount of elements. Make sure the it knows as much as you!
An Arr with a given amount of same elements.
Arr.repeat nat4 'L'
--> Arr.from4 'L' 'L' 'L' 'L'
--> : Arr (ValueN Nat4 ...) Char
Arr.repeat atLeast3 'L'
--> : Arr (ValueMin Nat3) CharIncreasing natural numbers. In the end, there are length numbers.
Arr.nats nat10
--> : Arr
--> (ValueN Nat10 ...)
--> (Nat (ValueIn Nat0 (Nat9Plus a)))
from first length_ =
Arr.nats length_
|> Arr.map (InNat.add first)Generate a given amount of elements and put them in an Arr.
No elements.
Arr.empty
--> : Arr (ValueN Nat0 ...) element
|> NArr.push ":)"
--> : Arr (ValueN Nat1 ...) StringCreate an Arr (ValueN Nat1 ...) from exactly 1 element in this order.
Create an Arr (ValueN Nat2 ...) from exactly 2 element in this order.
Create an Arr (ValueN Nat3 ...) from exactly 3 element in this order.
Create an Arr (ValueN Nat4 ...) from exactly 4 element in this order.
Create an Arr (ValueN Nat10 ...) from exactly 10 element in this order.
Create an Arr (ValueN Nat11 ...) from exactly 11 element in this order.
Create an Arr (ValueN Nat12 ...) from exactly 12 element in this order.
Create an Arr (ValueN Nat13 ...) from exactly 13 element in this order.
Create an Arr (ValueN Nat14 ...) from exactly 14 element in this order.
Create an Arr (ValueN Nat15 ...) from exactly 15 element in this order.
Create an Arr (ValueN Nat16 ...) from exactly 16 element in this order.
Create an Arr (ValueN Nat5 ...) from exactly 5 element in this order.
Create an Arr (ValueN Nat6 ...) from exactly 6 element in this order.
Create an Arr (ValueN Nat7 ...) from exactly 7 element in this order.
Create an Arr (ValueN Nat8 ...) from exactly 8 element in this order.
Create an Arr (ValueN Nat9 ...) from exactly 9 element in this order.
The amount of elements.
Element at a valid position.
Arr.from3 1 2 3
|> Arr.at nat1
--> 2This works for both
Arr.from8 0 1 2 3 4 5 6 7
|> Arr.take nat3 nat3 LastToFirst
--> Arr.from3 5 6 7
Arr.from8 0 1 2 3 4 5 6 7
|> Arr.take between3To7 nat7 FirstToLast
--> : Arr (ValueIn Nat3 Nat7) ...After a certain number of elements from one side.
with6To10Elements
|> Arr.drop nat2 LastToFirst
--> : Arr (In Nat4 (Nat10Plus a)) ...Use take LastToFirst if you know the exact amount of elements.
Change every element.
aToZ =
Arr.nats nat26
|> Arr.map
((+) ('a' |> Char.toCode)
>> Char.fromCode
)Reduce an Arr in a direction.
Arr.from5 "l" "i" "v" "e"
|> Arr.fold FirstToLast (++) ""
--> "live"
Arr.from5 "l" "i" "v" "e"
|> Arr.fold LastToFirst (++) ""
--> "evil"Convert the Arr to an Array.
Just do this in the end.
Try to keep extra information as long as you can.
Arr.nats nat5
|> Arr.map val
|> Arr.toArray
--> Array.fromList [ 0, 1, 2, 3, 4 ]Combine the elements of 2 Arrs to a new element.
If one list is longer, the extra elements are dropped.
teamLifes aBoard bBoard =
Arr.map2 (\a b -> a.lifes + b.lifes)
aBoard
bBoardWorks like map2.
Works like map2.
A fold where the initial result is the first value.
Arr.foldWith FirstToLast maximum
(Arr.from3 234 345 543)
--> 543Flip the order of the elements.
Arr.from5 "l" "i" "v" "e"
|> Arr.reverse
--> Arr.from5 "e" "v" "i" "l"Set the element at an index in a direction.
Arr.from3 "I" "am" "ok"
|> Arr.replaceAt nat2 FirstToLast "confusion"
--> Arr.from3 "I" "am" "confusion"
Arr.from3 "I" "am" "ok"
|> Arr.replaceAt nat1 LastToFirst "feel"
--> Arr.from3 "I" "feel" "ok"Use a lower minimum length in the type.
[ atLeast3Elements
, atLeast4Elements
]Elm complains:
But all the previous elements in the list are
Arr (ValueMin Nat3) ...
[ atLeast3Elements
, atLeast4Elements
|> Arr.lowerMinLength nat3
]Make an Arr with a fixed maximum length fit into functions with require a higher maximum length.
While designing argument annotations as general as possible:
atMost18Elements : Arr (In min Nat18 maybeN) ...The argument in atMost18Elements should also fit in atMost19Elements.
atMost19Elements theArgument
--> error :(
atMost19Elements
(theArgument |> Arr.restoreMaxLength nat18)
--> worksTransform a potential ValueOnly Arr to a ValueN.
append10s :
Arr (Only Nat10 aMaybeN) element
-> Arr (Only Nat10 bMaybeN) element
-> Arr (ValueN Nat20 (Nat20Plus a) ...)
append10s a10Elements b10Elements =
a10Elements
|> InArr.extend nat10 nat10 b10Elements
|> Arr.restoreLength nat20A Codec to serialize Arrs with a specific amount of elements.
import Serialize
-- we can't start if we have no worlds to choose from!
serializeGameRow :
Serialize.Codec
String
(Arr (ValueN Nat10 ...) GameField)
serializeGameRow =
Arr.serialize nat10 serializeGameField
encode : Arr (Only Nat10 maybeN) GameField -> Bytes
encode =
Arr.restoreLength nat10
>> Serialize.encodeToBytes serializeGameRow
decode :
Bytes
->
Result
(Serialize.Error String)
(Arr (ValueN Nat10 ...) GameField)
decode =
Serialize.decodeFromBytes serializeGameRow
An
Arrdescribes an array where you know more about the amount of elements.value / return types
function argument types