mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
has clause -> implements clause
This commit is contained in:
parent
0f289ed712
commit
b1d592ec37
8 changed files with 142 additions and 128 deletions
|
@ -30,7 +30,7 @@ Eq has
|
|||
## for more detail.
|
||||
## 5. Functions cannot be compared for structural equality, therefore Roc
|
||||
## cannot derive `isEq` for types that contain functions.
|
||||
isEq : a, a -> Bool | a has Eq
|
||||
isEq : a, a -> Bool | a implements Eq
|
||||
|
||||
## Represents the boolean true and false using an opaque type.
|
||||
## `Bool` implements the `Eq` ability.
|
||||
|
@ -116,7 +116,7 @@ not : Bool -> Bool
|
|||
## expect (Bool.false != Bool.false) == Bool.false
|
||||
## expect "Apples" != "Oranges"
|
||||
## ```
|
||||
isNotEq : a, a -> Bool | a has Eq
|
||||
isNotEq : a, a -> Bool | a implements Eq
|
||||
isNotEq = \a, b -> structuralNotEq a b
|
||||
|
||||
# INTERNAL COMPILER USE ONLY: used to lower calls to `isEq` to structural
|
||||
|
|
|
@ -73,30 +73,30 @@ DecodeResult val : { result : Result val DecodeError, rest : List U8 }
|
|||
## Decodes a `List U8` of utf-8 bytes where `val` is the type of the decoded
|
||||
## value, and `fmt` is a [Decoder] which implements the [DecoderFormatting]
|
||||
## ability
|
||||
Decoder val fmt := List U8, fmt -> DecodeResult val | fmt has DecoderFormatting
|
||||
Decoder val fmt := List U8, fmt -> DecodeResult val | fmt implements DecoderFormatting
|
||||
|
||||
## Definition of the [Decoding] ability
|
||||
Decoding has
|
||||
decoder : Decoder val fmt | val has Decoding, fmt has DecoderFormatting
|
||||
decoder : Decoder val fmt | val implements Decoding, fmt implements DecoderFormatting
|
||||
|
||||
## Definition of the [DecoderFormatting] ability
|
||||
DecoderFormatting has
|
||||
u8 : Decoder U8 fmt | fmt has DecoderFormatting
|
||||
u16 : Decoder U16 fmt | fmt has DecoderFormatting
|
||||
u32 : Decoder U32 fmt | fmt has DecoderFormatting
|
||||
u64 : Decoder U64 fmt | fmt has DecoderFormatting
|
||||
u128 : Decoder U128 fmt | fmt has DecoderFormatting
|
||||
i8 : Decoder I8 fmt | fmt has DecoderFormatting
|
||||
i16 : Decoder I16 fmt | fmt has DecoderFormatting
|
||||
i32 : Decoder I32 fmt | fmt has DecoderFormatting
|
||||
i64 : Decoder I64 fmt | fmt has DecoderFormatting
|
||||
i128 : Decoder I128 fmt | fmt has DecoderFormatting
|
||||
f32 : Decoder F32 fmt | fmt has DecoderFormatting
|
||||
f64 : Decoder F64 fmt | fmt has DecoderFormatting
|
||||
dec : Decoder Dec fmt | fmt has DecoderFormatting
|
||||
bool : Decoder Bool fmt | fmt has DecoderFormatting
|
||||
string : Decoder Str fmt | fmt has DecoderFormatting
|
||||
list : Decoder elem fmt -> Decoder (List elem) fmt | fmt has DecoderFormatting
|
||||
u8 : Decoder U8 fmt | fmt implements DecoderFormatting
|
||||
u16 : Decoder U16 fmt | fmt implements DecoderFormatting
|
||||
u32 : Decoder U32 fmt | fmt implements DecoderFormatting
|
||||
u64 : Decoder U64 fmt | fmt implements DecoderFormatting
|
||||
u128 : Decoder U128 fmt | fmt implements DecoderFormatting
|
||||
i8 : Decoder I8 fmt | fmt implements DecoderFormatting
|
||||
i16 : Decoder I16 fmt | fmt implements DecoderFormatting
|
||||
i32 : Decoder I32 fmt | fmt implements DecoderFormatting
|
||||
i64 : Decoder I64 fmt | fmt implements DecoderFormatting
|
||||
i128 : Decoder I128 fmt | fmt implements DecoderFormatting
|
||||
f32 : Decoder F32 fmt | fmt implements DecoderFormatting
|
||||
f64 : Decoder F64 fmt | fmt implements DecoderFormatting
|
||||
dec : Decoder Dec fmt | fmt implements DecoderFormatting
|
||||
bool : Decoder Bool fmt | fmt implements DecoderFormatting
|
||||
string : Decoder Str fmt | fmt implements DecoderFormatting
|
||||
list : Decoder elem fmt -> Decoder (List elem) fmt | fmt implements DecoderFormatting
|
||||
|
||||
## `record state stepField finalizer` decodes a record field-by-field.
|
||||
##
|
||||
|
@ -104,7 +104,7 @@ DecoderFormatting has
|
|||
## `Skip` if the field is not a part of the decoded record.
|
||||
##
|
||||
## `finalizer` should produce the record value from the decoded `state`.
|
||||
record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting
|
||||
record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt implements DecoderFormatting
|
||||
|
||||
## `tuple state stepElem finalizer` decodes a tuple element-by-element.
|
||||
##
|
||||
|
@ -113,7 +113,7 @@ DecoderFormatting has
|
|||
## index passed to `stepElem` is 0-indexed.
|
||||
##
|
||||
## `finalizer` should produce the tuple value from the decoded `state`.
|
||||
tuple : state, (state, Nat -> [Next (Decoder state fmt), TooLong]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting
|
||||
tuple : state, (state, Nat -> [Next (Decoder state fmt), TooLong]), (state -> Result val DecodeError) -> Decoder val fmt | fmt implements DecoderFormatting
|
||||
|
||||
## Build a custom [Decoder] function. For example the implementation of
|
||||
## `decodeBool` could be defined as follows;
|
||||
|
@ -125,11 +125,11 @@ DecoderFormatting has
|
|||
## ['t', 'r', 'u', 'e', ..] -> { result: Ok Bool.true, rest: List.drop bytes 4 }
|
||||
## _ -> { result: Err TooShort, rest: bytes }
|
||||
## ```
|
||||
custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting
|
||||
custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt implements DecoderFormatting
|
||||
custom = \decode -> @Decoder decode
|
||||
|
||||
## Decode a `List U8` utf-8 bytes using a specific [Decoder] function
|
||||
decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val | fmt has DecoderFormatting
|
||||
decodeWith : List U8, Decoder val fmt, fmt -> DecodeResult val | fmt implements DecoderFormatting
|
||||
decodeWith = \bytes, @Decoder decode, fmt -> decode bytes fmt
|
||||
|
||||
## Decode a `List U8` utf-8 bytes and return a [DecodeResult](#DecodeResult)
|
||||
|
@ -141,7 +141,7 @@ decodeWith = \bytes, @Decoder decode, fmt -> decode bytes fmt
|
|||
##
|
||||
## actual.result == expected
|
||||
## ```
|
||||
fromBytesPartial : List U8, fmt -> DecodeResult val | val has Decoding, fmt has DecoderFormatting
|
||||
fromBytesPartial : List U8, fmt -> DecodeResult val | val implements Decoding, fmt implements DecoderFormatting
|
||||
fromBytesPartial = \bytes, fmt -> decodeWith bytes decoder fmt
|
||||
|
||||
## Decode a `List U8` utf-8 bytes and return a [Result] with no leftover bytes
|
||||
|
@ -155,7 +155,7 @@ fromBytesPartial = \bytes, fmt -> decodeWith bytes decoder fmt
|
|||
##
|
||||
## actual == expected
|
||||
## ```
|
||||
fromBytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError | val has Decoding, fmt has DecoderFormatting
|
||||
fromBytes : List U8, fmt -> Result val [Leftover (List U8)]DecodeError | val implements Decoding, fmt implements DecoderFormatting
|
||||
fromBytes = \bytes, fmt ->
|
||||
when fromBytesPartial bytes fmt is
|
||||
{ result, rest } ->
|
||||
|
|
|
@ -97,13 +97,13 @@ Dict k v := {
|
|||
dataIndices : List Nat,
|
||||
data : List (T k v),
|
||||
size : Nat,
|
||||
} | k has Hash & Eq
|
||||
} | k implements Hash & Eq
|
||||
|
||||
## Return an empty dictionary.
|
||||
## ```
|
||||
## emptyDict = Dict.empty {}
|
||||
## ```
|
||||
empty : {} -> Dict k v | k has Hash & Eq
|
||||
empty : {} -> Dict k v | k implements Hash & Eq
|
||||
empty = \{} ->
|
||||
@Dict {
|
||||
metadata: List.repeat emptySlot 8,
|
||||
|
@ -120,7 +120,7 @@ empty = \{} ->
|
|||
##
|
||||
## capacityOfDict = Dict.capacity foodDict
|
||||
## ```
|
||||
capacity : Dict k v -> Nat | k has Hash & Eq
|
||||
capacity : Dict k v -> Nat | k implements Hash & Eq
|
||||
capacity = \@Dict { dataIndices } ->
|
||||
cap = List.len dataIndices
|
||||
|
||||
|
@ -129,7 +129,7 @@ capacity = \@Dict { dataIndices } ->
|
|||
## Return a dictionary with space allocated for a number of entries. This
|
||||
## may provide a performance optimisation if you know how many entries will be
|
||||
## inserted.
|
||||
withCapacity : Nat -> Dict k v | k has Hash & Eq
|
||||
withCapacity : Nat -> Dict k v | k implements Hash & Eq
|
||||
withCapacity = \_ ->
|
||||
# TODO: power of 2 * 8 and actual implementation
|
||||
empty {}
|
||||
|
@ -140,7 +140,7 @@ withCapacity = \_ ->
|
|||
## Dict.single "A" "B"
|
||||
## |> Bool.isEq (Dict.insert (Dict.empty {}) "A" "B")
|
||||
## ```
|
||||
single : k, v -> Dict k v | k has Hash & Eq
|
||||
single : k, v -> Dict k v | k implements Hash & Eq
|
||||
single = \k, v ->
|
||||
insert (empty {}) k v
|
||||
|
||||
|
@ -153,7 +153,7 @@ single = \k, v ->
|
|||
## |> Dict.insert 4 "Four"
|
||||
## |> Bool.isEq (Dict.fromList [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"])
|
||||
## ```
|
||||
fromList : List (T k v) -> Dict k v | k has Hash & Eq
|
||||
fromList : List (T k v) -> Dict k v | k implements Hash & Eq
|
||||
fromList = \data ->
|
||||
# TODO: make this efficient. Should just set data and then set all indicies in the hashmap.
|
||||
List.walk data (empty {}) (\dict, T k v -> insert dict k v)
|
||||
|
@ -168,7 +168,7 @@ fromList = \data ->
|
|||
## |> Dict.len
|
||||
## |> Bool.isEq 3
|
||||
## ```
|
||||
len : Dict k v -> Nat | k has Hash & Eq
|
||||
len : Dict k v -> Nat | k implements Hash & Eq
|
||||
len = \@Dict { size } ->
|
||||
size
|
||||
|
||||
|
@ -184,7 +184,7 @@ len = \@Dict { size } ->
|
|||
##
|
||||
## expect Dict.len clearSongs == 0
|
||||
## ```
|
||||
clear : Dict k v -> Dict k v | k has Hash & Eq
|
||||
clear : Dict k v -> Dict k v | k implements Hash & Eq
|
||||
clear = \@Dict { metadata, dataIndices, data } ->
|
||||
cap = List.len dataIndices
|
||||
|
||||
|
@ -212,7 +212,7 @@ clear = \@Dict { metadata, dataIndices, data } ->
|
|||
## |> Dict.walk 0 (\count, _, qty -> count + qty)
|
||||
## |> Bool.isEq 36
|
||||
## ```
|
||||
walk : Dict k v, state, (state, k, v -> state) -> state | k has Hash & Eq
|
||||
walk : Dict k v, state, (state, k, v -> state) -> state | k implements Hash & Eq
|
||||
walk = \@Dict { data }, initialState, transform ->
|
||||
List.walk data initialState (\state, T k v -> transform state k v)
|
||||
|
||||
|
@ -244,7 +244,7 @@ walk = \@Dict { data }, initialState, transform ->
|
|||
##
|
||||
## expect someoneIsAnAdult == Bool.true
|
||||
## ```
|
||||
walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state | k has Hash & Eq
|
||||
walkUntil : Dict k v, state, (state, k, v -> [Continue state, Break state]) -> state | k implements Hash & Eq
|
||||
walkUntil = \@Dict { data }, initialState, transform ->
|
||||
List.walkUntil data initialState (\state, T k v -> transform state k v)
|
||||
|
||||
|
@ -259,7 +259,7 @@ walkUntil = \@Dict { data }, initialState, transform ->
|
|||
## expect Dict.get dictionary 1 == Ok "Apple"
|
||||
## expect Dict.get dictionary 2000 == Err KeyNotFound
|
||||
## ```
|
||||
get : Dict k v, k -> Result v [KeyNotFound] | k has Hash & Eq
|
||||
get : Dict k v, k -> Result v [KeyNotFound] | k implements Hash & Eq
|
||||
get = \@Dict { metadata, dataIndices, data }, key ->
|
||||
hashKey =
|
||||
createLowLevelHasher {}
|
||||
|
@ -287,7 +287,7 @@ get = \@Dict { metadata, dataIndices, data }, key ->
|
|||
## |> Dict.contains 1234
|
||||
## |> Bool.isEq Bool.true
|
||||
## ```
|
||||
contains : Dict k v, k -> Bool | k has Hash & Eq
|
||||
contains : Dict k v, k -> Bool | k implements Hash & Eq
|
||||
contains = \@Dict { metadata, dataIndices, data }, key ->
|
||||
hashKey =
|
||||
createLowLevelHasher {}
|
||||
|
@ -312,7 +312,7 @@ contains = \@Dict { metadata, dataIndices, data }, key ->
|
|||
## |> Dict.get "Apples"
|
||||
## |> Bool.isEq (Ok 12)
|
||||
## ```
|
||||
insert : Dict k v, k, v -> Dict k v | k has Hash & Eq
|
||||
insert : Dict k v, k, v -> Dict k v | k implements Hash & Eq
|
||||
insert = \@Dict { metadata, dataIndices, data, size }, key, value ->
|
||||
hashKey =
|
||||
createLowLevelHasher {}
|
||||
|
@ -358,7 +358,7 @@ insert = \@Dict { metadata, dataIndices, data, size }, key, value ->
|
|||
## |> Dict.len
|
||||
## |> Bool.isEq 0
|
||||
## ```
|
||||
remove : Dict k v, k -> Dict k v | k has Hash & Eq
|
||||
remove : Dict k v, k -> Dict k v | k implements Hash & Eq
|
||||
remove = \@Dict { metadata, dataIndices, data, size }, key ->
|
||||
# TODO: change this from swap remove to tombstone and test is performance is still good.
|
||||
hashKey =
|
||||
|
@ -402,7 +402,7 @@ remove = \@Dict { metadata, dataIndices, data, size }, key ->
|
|||
## expect Dict.update (Dict.single "a" Bool.false) "a" alterValue == Dict.single "a" Bool.true
|
||||
## expect Dict.update (Dict.single "a" Bool.true) "a" alterValue == Dict.empty {}
|
||||
## ```
|
||||
update : Dict k v, k, ([Present v, Missing] -> [Present v, Missing]) -> Dict k v | k has Hash & Eq
|
||||
update : Dict k v, k, ([Present v, Missing] -> [Present v, Missing]) -> Dict k v | k implements Hash & Eq
|
||||
update = \dict, key, alter ->
|
||||
# TODO: look into optimizing by merging substeps and reducing lookups.
|
||||
possibleValue =
|
||||
|
@ -425,7 +425,7 @@ update = \dict, key, alter ->
|
|||
## |> Dict.toList
|
||||
## |> Bool.isEq [T 1 "One", T 2 "Two", T 3 "Three", T 4 "Four"]
|
||||
## ```
|
||||
toList : Dict k v -> List (T k v) | k has Hash & Eq
|
||||
toList : Dict k v -> List (T k v) | k implements Hash & Eq
|
||||
toList = \@Dict { data } ->
|
||||
data
|
||||
|
||||
|
@ -440,7 +440,7 @@ toList = \@Dict { data } ->
|
|||
## |> Dict.keys
|
||||
## |> Bool.isEq [1,2,3,4]
|
||||
## ```
|
||||
keys : Dict k v -> List k | k has Hash & Eq
|
||||
keys : Dict k v -> List k | k implements Hash & Eq
|
||||
keys = \@Dict { data } ->
|
||||
List.map data (\T k _ -> k)
|
||||
|
||||
|
@ -455,7 +455,7 @@ keys = \@Dict { data } ->
|
|||
## |> Dict.values
|
||||
## |> Bool.isEq ["One","Two","Three","Four"]
|
||||
## ```
|
||||
values : Dict k v -> List v | k has Hash & Eq
|
||||
values : Dict k v -> List v | k implements Hash & Eq
|
||||
values = \@Dict { data } ->
|
||||
List.map data (\T _ v -> v)
|
||||
|
||||
|
@ -483,7 +483,7 @@ values = \@Dict { data } ->
|
|||
## expect
|
||||
## Dict.insertAll first second == expected
|
||||
## ```
|
||||
insertAll : Dict k v, Dict k v -> Dict k v | k has Hash & Eq
|
||||
insertAll : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq
|
||||
insertAll = \xs, ys ->
|
||||
walk ys xs insert
|
||||
|
||||
|
@ -505,7 +505,7 @@ insertAll = \xs, ys ->
|
|||
##
|
||||
## expect Dict.keepShared first second == first
|
||||
## ```
|
||||
keepShared : Dict k v, Dict k v -> Dict k v | k has Hash & Eq
|
||||
keepShared : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq
|
||||
keepShared = \xs, ys ->
|
||||
walk
|
||||
xs
|
||||
|
@ -537,11 +537,11 @@ keepShared = \xs, ys ->
|
|||
##
|
||||
## expect Dict.removeAll first second == expected
|
||||
## ```
|
||||
removeAll : Dict k v, Dict k v -> Dict k v | k has Hash & Eq
|
||||
removeAll : Dict k v, Dict k v -> Dict k v | k implements Hash & Eq
|
||||
removeAll = \xs, ys ->
|
||||
walk ys xs (\state, k, _ -> remove state k)
|
||||
|
||||
swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v | k has Hash & Eq
|
||||
swapAndUpdateDataIndex : Dict k v, Nat, Nat -> Dict k v | k implements Hash & Eq
|
||||
swapAndUpdateDataIndex = \@Dict { metadata, dataIndices, data, size }, removedIndex, lastIndex ->
|
||||
(T key _) = listGetUnsafe data lastIndex
|
||||
hashKey =
|
||||
|
@ -605,7 +605,7 @@ nextEmptyOrDeletedHelper = \metadata, probe, offset ->
|
|||
|
||||
# TODO: investigate if this needs to be split into more specific helper functions.
|
||||
# There is a chance that returning specific sub-info like the value would be faster.
|
||||
findIndexHelper : List I8, List Nat, List (T k v), I8, k, Probe, Nat -> Result Nat [NotFound] | k has Hash & Eq
|
||||
findIndexHelper : List I8, List Nat, List (T k v), I8, k, Probe, Nat -> Result Nat [NotFound] | k implements Hash & Eq
|
||||
findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset ->
|
||||
# For finding a value, we must search past all deleted element tombstones.
|
||||
index = Num.addWrap (mul8 probe.slotIndex) offset
|
||||
|
@ -637,7 +637,7 @@ findIndexHelper = \metadata, dataIndices, data, h2Key, key, probe, offset ->
|
|||
# This is how we grow the container.
|
||||
# If we aren't to the load factor yet, just ignore this.
|
||||
# The container must have an updated size including any elements about to be inserted.
|
||||
maybeRehash : Dict k v -> Dict k v | k has Hash & Eq
|
||||
maybeRehash : Dict k v -> Dict k v | k implements Hash & Eq
|
||||
maybeRehash = \@Dict { metadata, dataIndices, data, size } ->
|
||||
cap = List.len dataIndices
|
||||
maxLoadCap =
|
||||
|
@ -650,7 +650,7 @@ maybeRehash = \@Dict { metadata, dataIndices, data, size } ->
|
|||
@Dict { metadata, dataIndices, data, size }
|
||||
|
||||
# TODO: switch rehash to iterate data and eventually clear out tombstones as well.
|
||||
rehash : Dict k v -> Dict k v | k has Hash & Eq
|
||||
rehash : Dict k v -> Dict k v | k implements Hash & Eq
|
||||
rehash = \@Dict { metadata, dataIndices, data, size } ->
|
||||
newLen = 2 * List.len dataIndices
|
||||
newDict =
|
||||
|
@ -663,7 +663,7 @@ rehash = \@Dict { metadata, dataIndices, data, size } ->
|
|||
|
||||
rehashHelper newDict metadata dataIndices data 0
|
||||
|
||||
rehashHelper : Dict k v, List I8, List Nat, List (T k v), Nat -> Dict k v | k has Hash & Eq
|
||||
rehashHelper : Dict k v, List I8, List Nat, List (T k v), Nat -> Dict k v | k implements Hash & Eq
|
||||
rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index ->
|
||||
when List.get oldMetadata index is
|
||||
Ok md ->
|
||||
|
@ -684,7 +684,7 @@ rehashHelper = \dict, oldMetadata, oldDataIndices, oldData, index ->
|
|||
# Walked entire list, complete now.
|
||||
dict
|
||||
|
||||
insertForRehash : Dict k v, k, Nat -> Dict k v | k has Hash & Eq
|
||||
insertForRehash : Dict k v, k, Nat -> Dict k v | k implements Hash & Eq
|
||||
insertForRehash = \@Dict { metadata, dataIndices, data, size }, key, dataIndex ->
|
||||
hashKey =
|
||||
createLowLevelHasher {}
|
||||
|
|
|
@ -47,40 +47,40 @@ interface Encode
|
|||
Bool.{ Bool },
|
||||
]
|
||||
|
||||
Encoder fmt := List U8, fmt -> List U8 | fmt has EncoderFormatting
|
||||
Encoder fmt := List U8, fmt -> List U8 | fmt implements EncoderFormatting
|
||||
|
||||
Encoding has
|
||||
toEncoder : val -> Encoder fmt | val has Encoding, fmt has EncoderFormatting
|
||||
toEncoder : val -> Encoder fmt | val implements Encoding, fmt implements EncoderFormatting
|
||||
|
||||
EncoderFormatting has
|
||||
u8 : U8 -> Encoder fmt | fmt has EncoderFormatting
|
||||
u16 : U16 -> Encoder fmt | fmt has EncoderFormatting
|
||||
u32 : U32 -> Encoder fmt | fmt has EncoderFormatting
|
||||
u64 : U64 -> Encoder fmt | fmt has EncoderFormatting
|
||||
u128 : U128 -> Encoder fmt | fmt has EncoderFormatting
|
||||
i8 : I8 -> Encoder fmt | fmt has EncoderFormatting
|
||||
i16 : I16 -> Encoder fmt | fmt has EncoderFormatting
|
||||
i32 : I32 -> Encoder fmt | fmt has EncoderFormatting
|
||||
i64 : I64 -> Encoder fmt | fmt has EncoderFormatting
|
||||
i128 : I128 -> Encoder fmt | fmt has EncoderFormatting
|
||||
f32 : F32 -> Encoder fmt | fmt has EncoderFormatting
|
||||
f64 : F64 -> Encoder fmt | fmt has EncoderFormatting
|
||||
dec : Dec -> Encoder fmt | fmt has EncoderFormatting
|
||||
bool : Bool -> Encoder fmt | fmt has EncoderFormatting
|
||||
string : Str -> Encoder fmt | fmt has EncoderFormatting
|
||||
list : List elem, (elem -> Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
||||
record : List { key : Str, value : Encoder fmt } -> Encoder fmt | fmt has EncoderFormatting
|
||||
tuple : List (Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
||||
tag : Str, List (Encoder fmt) -> Encoder fmt | fmt has EncoderFormatting
|
||||
u8 : U8 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
u16 : U16 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
u32 : U32 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
u64 : U64 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
u128 : U128 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
i8 : I8 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
i16 : I16 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
i32 : I32 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
i64 : I64 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
i128 : I128 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
f32 : F32 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
f64 : F64 -> Encoder fmt | fmt implements EncoderFormatting
|
||||
dec : Dec -> Encoder fmt | fmt implements EncoderFormatting
|
||||
bool : Bool -> Encoder fmt | fmt implements EncoderFormatting
|
||||
string : Str -> Encoder fmt | fmt implements EncoderFormatting
|
||||
list : List elem, (elem -> Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting
|
||||
record : List { key : Str, value : Encoder fmt } -> Encoder fmt | fmt implements EncoderFormatting
|
||||
tuple : List (Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting
|
||||
tag : Str, List (Encoder fmt) -> Encoder fmt | fmt implements EncoderFormatting
|
||||
|
||||
custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt has EncoderFormatting
|
||||
custom : (List U8, fmt -> List U8) -> Encoder fmt | fmt implements EncoderFormatting
|
||||
custom = \encoder -> @Encoder encoder
|
||||
|
||||
appendWith : List U8, Encoder fmt, fmt -> List U8 | fmt has EncoderFormatting
|
||||
appendWith : List U8, Encoder fmt, fmt -> List U8 | fmt implements EncoderFormatting
|
||||
appendWith = \lst, @Encoder doEncoding, fmt -> doEncoding lst fmt
|
||||
|
||||
append : List U8, val, fmt -> List U8 | val has Encoding, fmt has EncoderFormatting
|
||||
append : List U8, val, fmt -> List U8 | val implements Encoding, fmt implements EncoderFormatting
|
||||
append = \lst, val, fmt -> appendWith lst (toEncoder val) fmt
|
||||
|
||||
toBytes : val, fmt -> List U8 | val has Encoding, fmt has EncoderFormatting
|
||||
toBytes : val, fmt -> List U8 | val implements Encoding, fmt implements EncoderFormatting
|
||||
toBytes = \val, fmt -> appendWith [] (toEncoder val) fmt
|
||||
|
|
|
@ -32,7 +32,7 @@ Hash has
|
|||
## Hashes a value into a [Hasher].
|
||||
## Note that [hash] does not produce a hash value itself; the hasher must be
|
||||
## [complete]d in order to extract the hash value.
|
||||
hash : hasher, a -> hasher | a has Hash, hasher has Hasher
|
||||
hash : hasher, a -> hasher | a implements Hash, hasher implements Hasher
|
||||
|
||||
## Describes a hashing algorithm that is fed bytes and produces an integer hash.
|
||||
##
|
||||
|
@ -41,26 +41,26 @@ Hash has
|
|||
## cryptographically-secure hashing.
|
||||
Hasher has
|
||||
## Adds a list of bytes to the hasher.
|
||||
addBytes : a, List U8 -> a | a has Hasher
|
||||
addBytes : a, List U8 -> a | a implements Hasher
|
||||
|
||||
## Adds a single U8 to the hasher.
|
||||
addU8 : a, U8 -> a | a has Hasher
|
||||
addU8 : a, U8 -> a | a implements Hasher
|
||||
|
||||
## Adds a single U16 to the hasher.
|
||||
addU16 : a, U16 -> a | a has Hasher
|
||||
addU16 : a, U16 -> a | a implements Hasher
|
||||
|
||||
## Adds a single U32 to the hasher.
|
||||
addU32 : a, U32 -> a | a has Hasher
|
||||
addU32 : a, U32 -> a | a implements Hasher
|
||||
|
||||
## Adds a single U64 to the hasher.
|
||||
addU64 : a, U64 -> a | a has Hasher
|
||||
addU64 : a, U64 -> a | a implements Hasher
|
||||
|
||||
## Adds a single U128 to the hasher.
|
||||
addU128 : a, U128 -> a | a has Hasher
|
||||
addU128 : a, U128 -> a | a implements Hasher
|
||||
|
||||
## Completes the hasher, extracting a hash value from its
|
||||
## accumulated hash state.
|
||||
complete : a -> U64 | a has Hasher
|
||||
complete : a -> U64 | a implements Hasher
|
||||
|
||||
## Adds a string into a [Hasher] by hashing its UTF-8 bytes.
|
||||
hashStrBytes = \hasher, s ->
|
||||
|
@ -72,33 +72,33 @@ hashList = \hasher, lst ->
|
|||
hash accumHasher elem
|
||||
|
||||
## Adds a single [Bool] to a hasher.
|
||||
hashBool : a, Bool -> a | a has Hasher
|
||||
hashBool : a, Bool -> a | a implements Hasher
|
||||
hashBool = \hasher, b ->
|
||||
asU8 = if b then 1 else 0
|
||||
addU8 hasher asU8
|
||||
|
||||
## Adds a single I8 to a hasher.
|
||||
hashI8 : a, I8 -> a | a has Hasher
|
||||
hashI8 : a, I8 -> a | a implements Hasher
|
||||
hashI8 = \hasher, n -> addU8 hasher (Num.toU8 n)
|
||||
|
||||
## Adds a single I16 to a hasher.
|
||||
hashI16 : a, I16 -> a | a has Hasher
|
||||
hashI16 : a, I16 -> a | a implements Hasher
|
||||
hashI16 = \hasher, n -> addU16 hasher (Num.toU16 n)
|
||||
|
||||
## Adds a single I32 to a hasher.
|
||||
hashI32 : a, I32 -> a | a has Hasher
|
||||
hashI32 : a, I32 -> a | a implements Hasher
|
||||
hashI32 = \hasher, n -> addU32 hasher (Num.toU32 n)
|
||||
|
||||
## Adds a single I64 to a hasher.
|
||||
hashI64 : a, I64 -> a | a has Hasher
|
||||
hashI64 : a, I64 -> a | a implements Hasher
|
||||
hashI64 = \hasher, n -> addU64 hasher (Num.toU64 n)
|
||||
|
||||
## Adds a single I128 to a hasher.
|
||||
hashI128 : a, I128 -> a | a has Hasher
|
||||
hashI128 : a, I128 -> a | a implements Hasher
|
||||
hashI128 = \hasher, n -> addU128 hasher (Num.toU128 n)
|
||||
|
||||
## Adds a single Nat to a hasher.
|
||||
hashNat : a, Nat -> a | a has Hasher
|
||||
hashNat : a, Nat -> a | a implements Hasher
|
||||
hashNat = \hasher, n ->
|
||||
isPlatform32bit =
|
||||
x : Nat
|
||||
|
|
|
@ -362,7 +362,7 @@ join = \lists ->
|
|||
|
||||
List.walk lists (List.withCapacity totalLength) (\state, list -> List.concat state list)
|
||||
|
||||
contains : List a, a -> Bool | a has Eq
|
||||
contains : List a, a -> Bool | a implements Eq
|
||||
contains = \list, needle ->
|
||||
List.any list (\x -> x == needle)
|
||||
|
||||
|
@ -1036,7 +1036,7 @@ intersperse = \list, sep ->
|
|||
## is considered to "start with" an empty list.
|
||||
##
|
||||
## If the first list is empty, this only returns `Bool.true` if the second list is empty.
|
||||
startsWith : List elem, List elem -> Bool | elem has Eq
|
||||
startsWith : List elem, List elem -> Bool | elem implements Eq
|
||||
startsWith = \list, prefix ->
|
||||
# TODO once we have seamless slices, verify that this wouldn't
|
||||
# have better performance with a function like List.compareSublists
|
||||
|
@ -1048,7 +1048,7 @@ startsWith = \list, prefix ->
|
|||
## is considered to "end with" an empty list.
|
||||
##
|
||||
## If the first list is empty, this only returns `Bool.true` if the second list is empty.
|
||||
endsWith : List elem, List elem -> Bool | elem has Eq
|
||||
endsWith : List elem, List elem -> Bool | elem implements Eq
|
||||
endsWith = \list, suffix ->
|
||||
# TODO once we have seamless slices, verify that this wouldn't
|
||||
# have better performance with a function like List.compareSublists
|
||||
|
@ -1078,7 +1078,7 @@ split = \elements, userSplitIndex ->
|
|||
## ```
|
||||
## List.splitFirst [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo], after: [Bar, Z, Baz] }
|
||||
## ```
|
||||
splitFirst : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem has Eq
|
||||
splitFirst : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem implements Eq
|
||||
splitFirst = \list, delimiter ->
|
||||
when List.findFirstIndex list (\elem -> elem == delimiter) is
|
||||
Ok index ->
|
||||
|
@ -1094,7 +1094,7 @@ splitFirst = \list, delimiter ->
|
|||
## ```
|
||||
## List.splitLast [Foo, Z, Bar, Z, Baz] Z == Ok { before: [Foo, Z, Bar], after: [Baz] }
|
||||
## ```
|
||||
splitLast : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem has Eq
|
||||
splitLast : List elem, elem -> Result { before : List elem, after : List elem } [NotFound] | elem implements Eq
|
||||
splitLast = \list, delimiter ->
|
||||
when List.findLastIndex list (\elem -> elem == delimiter) is
|
||||
Ok index ->
|
||||
|
|
|
@ -25,7 +25,7 @@ interface Set
|
|||
|
||||
# We should have this line above the next has.
|
||||
# It causes the formatter to fail currently.
|
||||
# | k has Hash & Eq
|
||||
# | k implements Hash & Eq
|
||||
## Provides a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type))
|
||||
## type which stores a collection of unique values, without any ordering
|
||||
Set k := Dict.Dict k {}
|
||||
|
@ -35,7 +35,7 @@ Set k := Dict.Dict k {}
|
|||
},
|
||||
]
|
||||
|
||||
isEq : Set k, Set k -> Bool | k has Hash & Eq
|
||||
isEq : Set k, Set k -> Bool | k implements Hash & Eq
|
||||
isEq = \xs, ys ->
|
||||
if len xs != len ys then
|
||||
Bool.false
|
||||
|
@ -53,7 +53,7 @@ isEq = \xs, ys ->
|
|||
##
|
||||
## expect countValues == 0
|
||||
## ```
|
||||
empty : {} -> Set k | k has Hash & Eq
|
||||
empty : {} -> Set k | k implements Hash & Eq
|
||||
empty = \{} -> @Set (Dict.empty {})
|
||||
|
||||
## Creates a new `Set` with a single value.
|
||||
|
@ -63,7 +63,7 @@ empty = \{} -> @Set (Dict.empty {})
|
|||
##
|
||||
## expect countValues == 1
|
||||
## ```
|
||||
single : k -> Set k | k has Hash & Eq
|
||||
single : k -> Set k | k implements Hash & Eq
|
||||
single = \key ->
|
||||
Dict.single key {} |> @Set
|
||||
|
||||
|
@ -79,7 +79,7 @@ single = \key ->
|
|||
##
|
||||
## expect countValues == 3
|
||||
## ```
|
||||
insert : Set k, k -> Set k | k has Hash & Eq
|
||||
insert : Set k, k -> Set k | k implements Hash & Eq
|
||||
insert = \@Set dict, key ->
|
||||
Dict.insert dict key {} |> @Set
|
||||
|
||||
|
@ -112,7 +112,7 @@ expect
|
|||
##
|
||||
## expect countValues == 3
|
||||
## ```
|
||||
len : Set k -> Nat | k has Hash & Eq
|
||||
len : Set k -> Nat | k implements Hash & Eq
|
||||
len = \@Set dict ->
|
||||
Dict.len dict
|
||||
|
||||
|
@ -142,7 +142,7 @@ expect
|
|||
## expect has10 == Bool.false
|
||||
## expect has20 == Bool.true
|
||||
## ```
|
||||
remove : Set k, k -> Set k | k has Hash & Eq
|
||||
remove : Set k, k -> Set k | k implements Hash & Eq
|
||||
remove = \@Set dict, key ->
|
||||
Dict.remove dict key |> @Set
|
||||
|
||||
|
@ -161,7 +161,7 @@ remove = \@Set dict, key ->
|
|||
## expect hasApple == Bool.true
|
||||
## expect hasBanana == Bool.false
|
||||
## ```
|
||||
contains : Set k, k -> Bool | k has Hash & Eq
|
||||
contains : Set k, k -> Bool | k implements Hash & Eq
|
||||
contains = \@Set dict, key ->
|
||||
Dict.contains dict key
|
||||
|
||||
|
@ -174,7 +174,7 @@ contains = \@Set dict, key ->
|
|||
##
|
||||
## expect Set.toList numbers == values
|
||||
## ```
|
||||
toList : Set k -> List k | k has Hash & Eq
|
||||
toList : Set k -> List k | k implements Hash & Eq
|
||||
toList = \@Set dict ->
|
||||
Dict.keys dict
|
||||
|
||||
|
@ -188,7 +188,7 @@ toList = \@Set dict ->
|
|||
##
|
||||
## expect Set.fromList [Pear, Apple, Banana] == values
|
||||
## ```
|
||||
fromList : List k -> Set k | k has Hash & Eq
|
||||
fromList : List k -> Set k | k implements Hash & Eq
|
||||
fromList = \list ->
|
||||
initial = @Set (Dict.withCapacity (List.len list))
|
||||
|
||||
|
@ -204,7 +204,7 @@ fromList = \list ->
|
|||
##
|
||||
## expect Set.union set1 set2 == Set.fromList [Left, Right]
|
||||
## ```
|
||||
union : Set k, Set k -> Set k | k has Hash & Eq
|
||||
union : Set k, Set k -> Set k | k implements Hash & Eq
|
||||
union = \@Set dict1, @Set dict2 ->
|
||||
Dict.insertAll dict1 dict2 |> @Set
|
||||
|
||||
|
@ -217,7 +217,7 @@ union = \@Set dict1, @Set dict2 ->
|
|||
##
|
||||
## expect Set.intersection set1 set2 == Set.single Left
|
||||
## ```
|
||||
intersection : Set k, Set k -> Set k | k has Hash & Eq
|
||||
intersection : Set k, Set k -> Set k | k implements Hash & Eq
|
||||
intersection = \@Set dict1, @Set dict2 ->
|
||||
Dict.keepShared dict1 dict2 |> @Set
|
||||
|
||||
|
@ -231,7 +231,7 @@ intersection = \@Set dict1, @Set dict2 ->
|
|||
##
|
||||
## expect Set.difference first second == Set.fromList [Up, Down]
|
||||
## ```
|
||||
difference : Set k, Set k -> Set k | k has Hash & Eq
|
||||
difference : Set k, Set k -> Set k | k implements Hash & Eq
|
||||
difference = \@Set dict1, @Set dict2 ->
|
||||
Dict.removeAll dict1 dict2 |> @Set
|
||||
|
||||
|
@ -254,7 +254,7 @@ difference = \@Set dict1, @Set dict2 ->
|
|||
##
|
||||
## expect result == 2
|
||||
## ```
|
||||
walk : Set k, state, (state, k -> state) -> state | k has Hash & Eq
|
||||
walk : Set k, state, (state, k -> state) -> state | k implements Hash & Eq
|
||||
walk = \@Set dict, state, step ->
|
||||
Dict.walk dict state (\s, k, _ -> step s k)
|
||||
|
||||
|
@ -273,7 +273,7 @@ walk = \@Set dict, state, step ->
|
|||
##
|
||||
## expect result == FoundTheAnswer
|
||||
## ```
|
||||
walkUntil : Set k, state, (state, k -> [Continue state, Break state]) -> state | k has Hash & Eq
|
||||
walkUntil : Set k, state, (state, k -> [Continue state, Break state]) -> state | k implements Hash & Eq
|
||||
walkUntil = \@Set dict, state, step ->
|
||||
Dict.walkUntil dict state (\s, k, _ -> step s k)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue