mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
commit
43a8d1e610
23 changed files with 164 additions and 207 deletions
|
@ -47,7 +47,7 @@ interface Dict
|
|||
## its population as the associated value.
|
||||
##
|
||||
## populationByCity =
|
||||
## Dict.empty
|
||||
## Dict.empty {}
|
||||
## |> Dict.insert "London" 8_961_989
|
||||
## |> Dict.insert "Philadelphia" 1_603_797
|
||||
## |> Dict.insert "Shanghai" 24_870_895
|
||||
|
@ -100,8 +100,8 @@ Dict k v := {
|
|||
} | k has Hash & Eq
|
||||
|
||||
## Return an empty dictionary.
|
||||
empty : Dict k v | k has Hash & Eq
|
||||
empty =
|
||||
empty : {} -> Dict k v | k has Hash & Eq
|
||||
empty = \{} ->
|
||||
@Dict {
|
||||
metadata: List.repeat emptySlot 8,
|
||||
dataIndices: List.repeat 0 8,
|
||||
|
@ -122,16 +122,16 @@ capacity = \@Dict { dataIndices } ->
|
|||
withCapacity : Nat -> Dict k v | k has Hash & Eq
|
||||
withCapacity = \_ ->
|
||||
# TODO: power of 2 * 8 and actual implementation
|
||||
empty
|
||||
empty {}
|
||||
|
||||
## Returns a dictionary containing the key and value provided as input.
|
||||
##
|
||||
## expect
|
||||
## Dict.single "A" "B"
|
||||
## |> Bool.isEq (Dict.insert Dict.empty "A" "B")
|
||||
## |> Bool.isEq (Dict.insert (Dict.empty {}) "A" "B")
|
||||
single : k, v -> Dict k v | k has Hash & Eq
|
||||
single = \k, v ->
|
||||
insert empty k v
|
||||
insert (empty {}) k v
|
||||
|
||||
## Returns dictionary with the keys and values specified by the input [List].
|
||||
##
|
||||
|
@ -144,12 +144,12 @@ single = \k, v ->
|
|||
fromList : List (T k v) -> Dict k v | k has 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)
|
||||
List.walk data (empty {}) (\dict, T k v -> insert dict k v)
|
||||
|
||||
## Returns the number of values in the dictionary.
|
||||
##
|
||||
## expect
|
||||
## Dict.empty
|
||||
## Dict.empty {}
|
||||
## |> Dict.insert "One" "A Song"
|
||||
## |> Dict.insert "Two" "Candy Canes"
|
||||
## |> Dict.insert "Three" "Boughs of Holly"
|
||||
|
@ -166,7 +166,7 @@ clear = \@Dict { metadata, dataIndices, data } ->
|
|||
|
||||
# Only clear large allocations.
|
||||
if cap > 128 * 8 then
|
||||
empty
|
||||
empty {}
|
||||
else
|
||||
@Dict {
|
||||
metadata: List.map metadata (\_ -> emptySlot),
|
||||
|
@ -182,7 +182,7 @@ clear = \@Dict { metadata, dataIndices, data } ->
|
|||
## initial `state` value provided for the first call.
|
||||
##
|
||||
## expect
|
||||
## Dict.empty
|
||||
## Dict.empty {}
|
||||
## |> Dict.insert "Apples" 12
|
||||
## |> Dict.insert "Orange" 24
|
||||
## |> Dict.walk 0 (\count, _, qty -> count + qty)
|
||||
|
@ -210,7 +210,7 @@ walkUntil = \@Dict { data }, initialState, transform ->
|
|||
## will return [Ok value], otherwise return [Err KeyNotFound].
|
||||
##
|
||||
## dictionary =
|
||||
## Dict.empty
|
||||
## Dict.empty {}
|
||||
## |> Dict.insert 1 "Apple"
|
||||
## |> Dict.insert 2 "Orange"
|
||||
##
|
||||
|
@ -239,7 +239,7 @@ get = \@Dict { metadata, dataIndices, data }, key ->
|
|||
## Check if the dictionary has a value for a specified key.
|
||||
##
|
||||
## expect
|
||||
## Dict.empty
|
||||
## Dict.empty {}
|
||||
## |> Dict.insert 1234 "5678"
|
||||
## |> Dict.contains 1234
|
||||
## |> Bool.isEq Bool.true
|
||||
|
@ -263,7 +263,7 @@ contains = \@Dict { metadata, dataIndices, data }, key ->
|
|||
## Insert a value into the dictionary at a specified key.
|
||||
##
|
||||
## expect
|
||||
## Dict.empty
|
||||
## Dict.empty {}
|
||||
## |> Dict.insert "Apples" 12
|
||||
## |> Dict.get "Apples"
|
||||
## |> Bool.isEq (Ok 12)
|
||||
|
@ -307,7 +307,7 @@ insert = \@Dict { metadata, dataIndices, data, size }, key, value ->
|
|||
## Remove a value from the dictionary for a specified key.
|
||||
##
|
||||
## expect
|
||||
## Dict.empty
|
||||
## Dict.empty {}
|
||||
## |> Dict.insert "Some" "Value"
|
||||
## |> Dict.remove "Some"
|
||||
## |> Dict.len
|
||||
|
@ -352,9 +352,9 @@ remove = \@Dict { metadata, dataIndices, data, size }, key ->
|
|||
## Missing -> Present Bool.false
|
||||
## Present value -> if value then Missing else Present Bool.true
|
||||
##
|
||||
## expect Dict.update Dict.empty "a" alterValue == Dict.single "a" Bool.false
|
||||
## expect Dict.update (Dict.empty {}) "a" alterValue == Dict.single "a" Bool.false
|
||||
## 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
|
||||
## 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, key, alter ->
|
||||
# TODO: look into optimizing by merging substeps and reducing lookups.
|
||||
|
@ -457,7 +457,7 @@ keepShared : Dict k v, Dict k v -> Dict k v | k has Hash & Eq
|
|||
keepShared = \xs, ys ->
|
||||
walk
|
||||
xs
|
||||
empty
|
||||
(empty {})
|
||||
(\state, k, v ->
|
||||
if contains ys k then
|
||||
insert state k v
|
||||
|
@ -688,7 +688,7 @@ h2 = \hashKey ->
|
|||
|
||||
expect
|
||||
val =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo" "bar"
|
||||
|> get "foo"
|
||||
|
||||
|
@ -696,7 +696,7 @@ expect
|
|||
|
||||
expect
|
||||
val =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo" "bar"
|
||||
|> insert "foo" "baz"
|
||||
|> get "foo"
|
||||
|
@ -705,20 +705,20 @@ expect
|
|||
|
||||
expect
|
||||
val =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo" "bar"
|
||||
|> get "bar"
|
||||
|
||||
val == Err KeyNotFound
|
||||
|
||||
expect
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo" {}
|
||||
|> contains "foo"
|
||||
|
||||
expect
|
||||
dict =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo" {}
|
||||
|> insert "bar" {}
|
||||
|> insert "baz" {}
|
||||
|
@ -746,7 +746,7 @@ expect
|
|||
# Reach capacity, no rehash.
|
||||
expect
|
||||
val =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "a" 0
|
||||
|> insert "b" 1
|
||||
|> insert "c" 2
|
||||
|
@ -760,7 +760,7 @@ expect
|
|||
|
||||
expect
|
||||
dict =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "a" 0
|
||||
|> insert "b" 1
|
||||
|> insert "c" 2
|
||||
|
@ -780,7 +780,7 @@ expect
|
|||
# Force rehash.
|
||||
expect
|
||||
val =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "a" 0
|
||||
|> insert "b" 1
|
||||
|> insert "c" 2
|
||||
|
@ -795,7 +795,7 @@ expect
|
|||
|
||||
expect
|
||||
dict =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "a" 0
|
||||
|> insert "b" 1
|
||||
|> insert "c" 2
|
||||
|
@ -815,7 +815,7 @@ expect
|
|||
&& (get dict "h" == Ok 7)
|
||||
|
||||
expect
|
||||
empty
|
||||
empty {}
|
||||
|> insert "Some" "Value"
|
||||
|> remove "Some"
|
||||
|> len
|
||||
|
@ -823,7 +823,7 @@ expect
|
|||
|
||||
# Makes sure a Dict with Nat keys works
|
||||
expect
|
||||
empty
|
||||
empty {}
|
||||
|> insert 7nat "Testing"
|
||||
|> get 7
|
||||
|> Bool.isEq (Ok "Testing")
|
||||
|
|
|
@ -43,9 +43,9 @@ isEq = \xs, ys ->
|
|||
else
|
||||
Break Bool.false
|
||||
|
||||
## An empty set.
|
||||
empty : Set k | k has Hash & Eq
|
||||
empty = @Set Dict.empty
|
||||
## Creates a new empty set.
|
||||
empty : {} -> Set k | k has Hash & Eq
|
||||
empty = \{} -> @Set (Dict.empty {})
|
||||
|
||||
single : k -> Set k | k has Hash & Eq
|
||||
single = \key ->
|
||||
|
@ -58,14 +58,14 @@ insert = \@Set dict, key ->
|
|||
# Inserting a duplicate key has no effect.
|
||||
expect
|
||||
actual =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo"
|
||||
|> insert "bar"
|
||||
|> insert "foo"
|
||||
|> insert "baz"
|
||||
|
||||
expected =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo"
|
||||
|> insert "bar"
|
||||
|> insert "baz"
|
||||
|
@ -79,7 +79,7 @@ len = \@Set dict ->
|
|||
# Inserting a duplicate key has no effect on length.
|
||||
expect
|
||||
actual =
|
||||
empty
|
||||
empty {}
|
||||
|> insert "foo"
|
||||
|> insert "bar"
|
||||
|> insert "foo"
|
||||
|
|
|
@ -969,7 +969,7 @@ mod test_can {
|
|||
fn dict() {
|
||||
let src = indoc!(
|
||||
r#"
|
||||
x = Dict.empty
|
||||
x = Dict.empty {}
|
||||
|
||||
Dict.len x
|
||||
"#
|
||||
|
|
|
@ -12,6 +12,7 @@ roc_error_macros = { path = "../../error_macros" }
|
|||
roc_region = { path = "../region" }
|
||||
roc_module = { path = "../module" }
|
||||
roc_parse = { path = "../parse" }
|
||||
roc_problem = { path = "../problem" }
|
||||
roc_types = { path = "../types" }
|
||||
roc_can = { path = "../can" }
|
||||
arrayvec = "0.7.2"
|
||||
|
|
|
@ -3825,32 +3825,44 @@ fn is_generalizable_expr(mut expr: &Expr) -> bool {
|
|||
match expr {
|
||||
Num(..) | Int(..) | Float(..) => return true,
|
||||
Closure(_) => return true,
|
||||
OpaqueRef { argument, .. } => expr = &argument.1.value,
|
||||
Str(_) | List { .. } | SingleQuote(_, _, _, _) | When { .. } | If { .. } => {
|
||||
return false
|
||||
Accessor(_) => {
|
||||
// Accessor functions `.field` are equivalent to closures `\r -> r.field`, no need to weaken them.
|
||||
return true;
|
||||
}
|
||||
// TODO(weakening)
|
||||
Var(_, _)
|
||||
| AbilityMember(_, _, _)
|
||||
OpaqueWrapFunction(_) => {
|
||||
// Opaque wrapper functions `@Q` are equivalent to closures `\x -> @Q x`, no need to weaken them.
|
||||
return true;
|
||||
}
|
||||
RuntimeError(roc_problem::can::RuntimeError::NoImplementation)
|
||||
| RuntimeError(roc_problem::can::RuntimeError::NoImplementationNamed { .. }) => {
|
||||
// Allow generalization of signatures with no implementation
|
||||
return true;
|
||||
}
|
||||
OpaqueRef { argument, .. } => expr = &argument.1.value,
|
||||
Str(_)
|
||||
| List { .. }
|
||||
| SingleQuote(_, _, _, _)
|
||||
| When { .. }
|
||||
| If { .. }
|
||||
| LetRec(_, _, _)
|
||||
| LetNonRec(_, _)
|
||||
| Call(_, _, _)
|
||||
| RunLowLevel { .. }
|
||||
| ForeignCall { .. }
|
||||
| Expr::Record { .. }
|
||||
| EmptyRecord
|
||||
| Expr::Record { .. }
|
||||
| Crash { .. }
|
||||
| Access { .. }
|
||||
| Accessor(_)
|
||||
| Update { .. }
|
||||
| Tag { .. }
|
||||
| ZeroArgumentTag { .. }
|
||||
| OpaqueWrapFunction(_)
|
||||
| Expect { .. }
|
||||
| ExpectFx { .. }
|
||||
| Dbg { .. }
|
||||
| TypedHole(_)
|
||||
| RuntimeError(_) => return true,
|
||||
| RuntimeError(..) => return false,
|
||||
// TODO(weakening)
|
||||
Var(_, _) | AbilityMember(_, _, _) | Tag { .. } | ZeroArgumentTag { .. } => {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ Model position :
|
|||
|
||||
initialModel : position -> Model position
|
||||
initialModel = \start ->
|
||||
{ evaluated : Set.empty
|
||||
{ evaluated : Set.empty {}
|
||||
, openSet : Set.single start
|
||||
, costs : Dict.single start 0.0
|
||||
, cameFrom : Map.empty
|
||||
|
|
|
@ -15,10 +15,10 @@ Model position :
|
|||
|
||||
initialModel : position -> Model position | position has Hash & Eq
|
||||
initialModel = \start ->
|
||||
{ evaluated : Set.empty
|
||||
{ evaluated : Set.empty {}
|
||||
, openSet : Set.single start
|
||||
, costs : Dict.single start 0.0
|
||||
, cameFrom : Dict.empty
|
||||
, cameFrom : Dict.empty {}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7140,7 +7140,7 @@ mod solve_expr {
|
|||
#^^^{-1}
|
||||
"#
|
||||
),
|
||||
@r#"fun : {} -[[thunk(5) [A Str]*, thunk(5) { a : Str }]]-> Str"#
|
||||
@r#"fun : {} -[[thunk(5) [A Str]w_a, thunk(5) { a : Str }]]-> Str"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -7264,7 +7264,7 @@ mod solve_expr {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn polymorphic_lambda_set_specialization_with_let_generalization() {
|
||||
fn polymorphic_lambda_set_specialization_with_let_weakened() {
|
||||
infer_queries!(
|
||||
indoc!(
|
||||
r#"
|
||||
|
@ -7282,6 +7282,7 @@ mod solve_expr {
|
|||
#^{-1}
|
||||
|
||||
main =
|
||||
# h should get weakened
|
||||
h = f (@Fo {})
|
||||
# ^ ^
|
||||
h (@Go {})
|
||||
|
@ -7291,15 +7292,15 @@ mod solve_expr {
|
|||
@r###"
|
||||
Fo#f(7) : Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b has G
|
||||
Go#g(8) : Go -[[g(8)]]-> {}
|
||||
h : b -[[] + b:g(4):1]-> {} | b has G
|
||||
Fo#f(7) : Fo -[[f(7)]]-> (b -[[] + b:g(4):1]-> {}) | b has G
|
||||
h : Go -[[g(8)]]-> {}
|
||||
Fo#f(7) : Fo -[[f(7)]]-> (Go -[[g(8)]]-> {})
|
||||
h : Go -[[g(8)]]-> {}
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn polymorphic_lambda_set_specialization_with_let_generalization_unapplied() {
|
||||
fn polymorphic_lambda_set_specialization_with_let_weakened_unapplied() {
|
||||
infer_queries!(
|
||||
indoc!(
|
||||
r#"
|
||||
|
@ -7461,9 +7462,9 @@ mod solve_expr {
|
|||
|
||||
main =
|
||||
#^^^^{-1}
|
||||
it =
|
||||
it = \x ->
|
||||
# ^^
|
||||
(f A (@C {}) (@D {}))
|
||||
(f A (@C {}) (@D {})) x
|
||||
# ^
|
||||
if Bool.true
|
||||
then it (@E {})
|
||||
|
@ -7484,10 +7485,10 @@ mod solve_expr {
|
|||
J#j(2) : j -[[] + j:j(2):1]-> (k -[[] + j1:j(2):2 + j:j(2):2]-> {}) | j has J, j1 has J, k has K
|
||||
it : k -[[] + j:j(2):2 + j1:j(2):2]-> {} | j has J, j1 has J, k has K
|
||||
main : {}
|
||||
it : k -[[] + k:k(4):1]-> {} | k has K
|
||||
it : k -[[it(21)]]-> {} | k has K
|
||||
f : [A, B], C, D -[[f(13)]]-> (k -[[] + k:k(4):1]-> {}) | k has K
|
||||
it : E -[[kE(11)]]-> {}
|
||||
it : F -[[kF(12)]]-> {}
|
||||
it : E -[[it(21)]]-> {}
|
||||
it : F -[[it(21)]]-> {}
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
@ -8475,10 +8476,10 @@ mod solve_expr {
|
|||
|
||||
main =
|
||||
s1 : Set U8
|
||||
s1 = Set.empty
|
||||
s1 = Set.empty {}
|
||||
|
||||
s2 : Set Str
|
||||
s2 = Set.empty
|
||||
s2 = Set.empty {}
|
||||
|
||||
Bool.isEq s1 s1 && Bool.isEq s2 s2
|
||||
# ^^^^^^^^^ ^^^^^^^^^
|
||||
|
|
|
@ -21,7 +21,7 @@ fn dict_empty_len() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Dict.len Dict.empty
|
||||
Dict.len (Dict.empty {})
|
||||
"#
|
||||
),
|
||||
0,
|
||||
|
@ -35,7 +35,7 @@ fn dict_insert_empty() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 42 32
|
||||
|> Dict.len
|
||||
"#
|
||||
|
@ -52,7 +52,7 @@ fn dict_empty_contains() {
|
|||
indoc!(
|
||||
r#"
|
||||
empty : Dict.Dict I64 F64
|
||||
empty = Dict.empty
|
||||
empty = Dict.empty {}
|
||||
|
||||
Dict.contains empty 42
|
||||
"#
|
||||
|
@ -69,7 +69,7 @@ fn dict_nonempty_contains() {
|
|||
indoc!(
|
||||
r#"
|
||||
empty : Dict.Dict I64 F64
|
||||
empty = Dict.insert Dict.empty 42 1.23
|
||||
empty = Dict.insert (Dict.empty {}) 42 1.23
|
||||
|
||||
Dict.contains empty 42
|
||||
"#
|
||||
|
@ -87,7 +87,7 @@ fn dict_empty_remove() {
|
|||
indoc!(
|
||||
r#"
|
||||
empty : Dict.Dict I64 F64
|
||||
empty = Dict.empty
|
||||
empty = Dict.empty {}
|
||||
|
||||
empty
|
||||
|> Dict.remove 42
|
||||
|
@ -106,7 +106,7 @@ fn dict_nonempty_remove() {
|
|||
indoc!(
|
||||
r#"
|
||||
empty : Dict.Dict I64 F64
|
||||
empty = Dict.insert Dict.empty 42 1.23
|
||||
empty = Dict.insert (Dict.empty {}) 42 1.23
|
||||
|
||||
empty
|
||||
|> Dict.remove 42
|
||||
|
@ -126,7 +126,7 @@ fn dict_nonempty_get() {
|
|||
indoc!(
|
||||
r#"
|
||||
empty : Dict.Dict I64 F64
|
||||
empty = Dict.insert Dict.empty 42 1.23
|
||||
empty = Dict.insert (Dict.empty {}) 42 1.23
|
||||
|
||||
withDefault = \x, def ->
|
||||
when x is
|
||||
|
@ -151,7 +151,7 @@ fn dict_nonempty_get() {
|
|||
Ok v -> v
|
||||
Err _ -> def
|
||||
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 42 1.23
|
||||
|> Dict.get 43
|
||||
|> withDefault 0
|
||||
|
@ -170,7 +170,7 @@ fn keys() {
|
|||
r#"
|
||||
myDict : Dict.Dict I64 I64
|
||||
myDict =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 0 100
|
||||
|> Dict.insert 1 100
|
||||
|> Dict.insert 2 100
|
||||
|
@ -192,7 +192,7 @@ fn values() {
|
|||
r#"
|
||||
myDict : Dict.Dict I64 I64
|
||||
myDict =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 0 100
|
||||
|> Dict.insert 1 200
|
||||
|> Dict.insert 2 300
|
||||
|
@ -215,7 +215,7 @@ fn from_list_with_fold_simple() {
|
|||
myDict : Dict.Dict I64 I64
|
||||
myDict =
|
||||
[1,2,3]
|
||||
|> List.walk Dict.empty (\accum, value -> Dict.insert accum value value)
|
||||
|> List.walk (Dict.empty {}) (\accum, value -> Dict.insert accum value value)
|
||||
|
||||
Dict.values myDict
|
||||
"#
|
||||
|
@ -242,7 +242,7 @@ fn from_list_with_fold_reallocates() {
|
|||
myDict =
|
||||
# 25 elements (8 + 16 + 1) is guaranteed to overflow/reallocate at least twice
|
||||
range 0 25 []
|
||||
|> List.walk Dict.empty (\accum, value -> Dict.insert accum value value)
|
||||
|> List.walk (Dict.empty {}) (\accum, value -> Dict.insert accum value value)
|
||||
|
||||
Dict.values myDict
|
||||
"#
|
||||
|
@ -267,7 +267,7 @@ fn small_str_keys() {
|
|||
r#"
|
||||
myDict : Dict.Dict Str I64
|
||||
myDict =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert "a" 100
|
||||
|> Dict.insert "b" 100
|
||||
|> Dict.insert "c" 100
|
||||
|
@ -289,7 +289,7 @@ fn big_str_keys() {
|
|||
r#"
|
||||
myDict : Dict.Dict Str I64
|
||||
myDict =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert "Leverage agile frameworks to provide a robust" 100
|
||||
|> Dict.insert "synopsis for high level overviews. Iterative approaches" 200
|
||||
|> Dict.insert "to corporate strategy foster collaborative thinking to" 300
|
||||
|
@ -314,7 +314,7 @@ fn big_str_values() {
|
|||
r#"
|
||||
myDict : Dict.Dict I64 Str
|
||||
myDict =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 100 "Leverage agile frameworks to provide a robust"
|
||||
|> Dict.insert 200 "synopsis for high level overviews. Iterative approaches"
|
||||
|> Dict.insert 300 "to corporate strategy foster collaborative thinking to"
|
||||
|
@ -339,7 +339,7 @@ fn unit_values() {
|
|||
r#"
|
||||
myDict : Dict.Dict I64 {}
|
||||
myDict =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 0 {}
|
||||
|> Dict.insert 1 {}
|
||||
|> Dict.insert 2 {}
|
||||
|
@ -417,7 +417,7 @@ fn keep_shared() {
|
|||
r#"
|
||||
dict1 : Dict.Dict I64 {}
|
||||
dict1 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 1 {}
|
||||
|> Dict.insert 2 {}
|
||||
|> Dict.insert 3 {}
|
||||
|
@ -426,7 +426,7 @@ fn keep_shared() {
|
|||
|
||||
dict2 : Dict.Dict I64 {}
|
||||
dict2 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 0 {}
|
||||
|> Dict.insert 2 {}
|
||||
|> Dict.insert 4 {}
|
||||
|
@ -449,7 +449,7 @@ fn keep_shared_prefer_first() {
|
|||
r#"
|
||||
dict1 : Dict.Dict I64 I64
|
||||
dict1 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 1 1
|
||||
|> Dict.insert 2 2
|
||||
|> Dict.insert 3 3
|
||||
|
@ -458,7 +458,7 @@ fn keep_shared_prefer_first() {
|
|||
|
||||
dict2 : Dict.Dict I64 I64
|
||||
dict2 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 0 100
|
||||
|> Dict.insert 2 200
|
||||
|> Dict.insert 4 300
|
||||
|
@ -480,7 +480,7 @@ fn remove_all() {
|
|||
r#"
|
||||
dict1 : Dict.Dict I64 {}
|
||||
dict1 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 1 {}
|
||||
|> Dict.insert 2 {}
|
||||
|> Dict.insert 3 {}
|
||||
|
@ -489,7 +489,7 @@ fn remove_all() {
|
|||
|
||||
dict2 : Dict.Dict I64 {}
|
||||
dict2 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 0 {}
|
||||
|> Dict.insert 2 {}
|
||||
|> Dict.insert 4 {}
|
||||
|
@ -512,7 +512,7 @@ fn remove_all_prefer_first() {
|
|||
r#"
|
||||
dict1 : Dict.Dict I64 I64
|
||||
dict1 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 1 1
|
||||
|> Dict.insert 2 2
|
||||
|> Dict.insert 3 3
|
||||
|
@ -521,7 +521,7 @@ fn remove_all_prefer_first() {
|
|||
|
||||
dict2 : Dict.Dict I64 I64
|
||||
dict2 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 0 100
|
||||
|> Dict.insert 2 200
|
||||
|> Dict.insert 4 300
|
||||
|
@ -543,7 +543,7 @@ fn walk_sum_keys() {
|
|||
r#"
|
||||
dict1 : Dict.Dict I64 I64
|
||||
dict1 =
|
||||
Dict.empty
|
||||
Dict.empty {}
|
||||
|> Dict.insert 1 1
|
||||
|> Dict.insert 2 2
|
||||
|> Dict.insert 3 3
|
||||
|
|
|
@ -21,7 +21,7 @@ fn empty_len() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Set.len Set.empty
|
||||
Set.len (Set.empty {})
|
||||
"#
|
||||
),
|
||||
0,
|
||||
|
@ -73,7 +73,7 @@ fn insert() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Set.empty
|
||||
Set.empty {}
|
||||
|> Set.insert 0
|
||||
|> Set.insert 1
|
||||
|> Set.insert 2
|
||||
|
@ -91,7 +91,7 @@ fn remove() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Set.empty
|
||||
Set.empty {}
|
||||
|> Set.insert 0
|
||||
|> Set.insert 1
|
||||
|> Set.remove 1
|
||||
|
@ -259,7 +259,7 @@ fn to_list_empty() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Set.toList Set.empty
|
||||
Set.toList (Set.empty {})
|
||||
"#
|
||||
),
|
||||
RocList::<std::convert::Infallible>::default(),
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.23 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.23;
|
||||
|
||||
procedure Bool.11 (#Attr.2, #Attr.3):
|
||||
let Bool.24 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
|
||||
ret Bool.24;
|
||||
|
@ -18,18 +14,6 @@ procedure List.26 (List.152, List.153, List.154):
|
|||
let List.156 : U64 = UnionAtIndex (Id 0) (Index 0) List.493;
|
||||
ret List.156;
|
||||
|
||||
procedure List.26 (List.152, List.153, List.154):
|
||||
let List.515 : [C I64, C I64] = CallByName List.90 List.152 List.153 List.154;
|
||||
let List.518 : U8 = 1i64;
|
||||
let List.519 : U8 = GetTagId List.515;
|
||||
let List.520 : Int1 = lowlevel Eq List.518 List.519;
|
||||
if List.520 then
|
||||
let List.155 : I64 = UnionAtIndex (Id 1) (Index 0) List.515;
|
||||
ret List.155;
|
||||
else
|
||||
let List.156 : I64 = UnionAtIndex (Id 0) (Index 0) List.515;
|
||||
ret List.156;
|
||||
|
||||
procedure List.29 (List.294, List.295):
|
||||
let List.492 : U64 = CallByName List.6 List.294;
|
||||
let List.296 : U64 = CallByName Num.77 List.492 List.295;
|
||||
|
@ -75,13 +59,7 @@ procedure List.90 (List.426, List.427, List.428):
|
|||
let List.499 : [C U64, C U64] = CallByName List.91 List.426 List.427 List.428 List.500 List.501;
|
||||
ret List.499;
|
||||
|
||||
procedure List.90 (List.426, List.427, List.428):
|
||||
let List.522 : U64 = 0i64;
|
||||
let List.523 : U64 = CallByName List.6 List.426;
|
||||
let List.521 : [C I64, C I64] = CallByName List.91 List.426 List.427 List.428 List.522 List.523;
|
||||
ret List.521;
|
||||
|
||||
procedure List.91 (List.549, List.550, List.551, List.552, List.553):
|
||||
procedure List.91 (List.528, List.529, List.530, List.531, List.532):
|
||||
joinpoint List.502 List.429 List.430 List.431 List.432 List.433:
|
||||
let List.504 : Int1 = CallByName Num.22 List.432 List.433;
|
||||
if List.504 then
|
||||
|
@ -103,66 +81,35 @@ procedure List.91 (List.549, List.550, List.551, List.552, List.553):
|
|||
let List.503 : [C U64, C U64] = TagId(1) List.430;
|
||||
ret List.503;
|
||||
in
|
||||
jump List.502 List.549 List.550 List.551 List.552 List.553;
|
||||
|
||||
procedure List.91 (List.562, List.563, List.564, List.565, List.566):
|
||||
joinpoint List.524 List.429 List.430 List.431 List.432 List.433:
|
||||
let List.526 : Int1 = CallByName Num.22 List.432 List.433;
|
||||
if List.526 then
|
||||
let List.535 : U8 = CallByName List.66 List.429 List.432;
|
||||
let List.527 : [C I64, C I64] = CallByName Test.4 List.430 List.535;
|
||||
let List.532 : U8 = 1i64;
|
||||
let List.533 : U8 = GetTagId List.527;
|
||||
let List.534 : Int1 = lowlevel Eq List.532 List.533;
|
||||
if List.534 then
|
||||
let List.434 : I64 = UnionAtIndex (Id 1) (Index 0) List.527;
|
||||
let List.530 : U64 = 1i64;
|
||||
let List.529 : U64 = CallByName Num.19 List.432 List.530;
|
||||
jump List.524 List.429 List.434 List.431 List.529 List.433;
|
||||
else
|
||||
let List.435 : I64 = UnionAtIndex (Id 0) (Index 0) List.527;
|
||||
let List.531 : [C I64, C I64] = TagId(0) List.435;
|
||||
ret List.531;
|
||||
else
|
||||
let List.525 : [C I64, C I64] = TagId(1) List.430;
|
||||
ret List.525;
|
||||
in
|
||||
jump List.524 List.562 List.563 List.564 List.565 List.566;
|
||||
jump List.502 List.528 List.529 List.530 List.531 List.532;
|
||||
|
||||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.259 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
ret Num.259;
|
||||
let Num.258 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
ret Num.258;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.261 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.261;
|
||||
let Num.259 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.259;
|
||||
|
||||
procedure Num.77 (#Attr.2, #Attr.3):
|
||||
let Num.257 : U64 = lowlevel NumSubSaturated #Attr.2 #Attr.3;
|
||||
ret Num.257;
|
||||
|
||||
procedure Test.1 (Test.2):
|
||||
let Test.18 : I64 = 0i64;
|
||||
let Test.19 : {} = Struct {};
|
||||
let Test.12 : I64 = CallByName List.26 Test.2 Test.18 Test.19;
|
||||
let Test.14 : U64 = 0i64;
|
||||
let Test.15 : {} = Struct {};
|
||||
let Test.3 : U64 = CallByName List.26 Test.2 Test.14 Test.15;
|
||||
let Test.13 : I64 = 0i64;
|
||||
let Test.10 : Int1 = CallByName Bool.11 Test.12 Test.13;
|
||||
let Test.13 : U64 = 0i64;
|
||||
let Test.14 : {} = Struct {};
|
||||
let Test.3 : U64 = CallByName List.26 Test.2 Test.13 Test.14;
|
||||
let Test.12 : U64 = 0i64;
|
||||
let Test.10 : Int1 = CallByName Bool.11 Test.3 Test.12;
|
||||
if Test.10 then
|
||||
ret Test.2;
|
||||
else
|
||||
let Test.9 : List U8 = CallByName List.29 Test.2 Test.3;
|
||||
ret Test.9;
|
||||
|
||||
procedure Test.4 (Test.5, Test.16):
|
||||
let Test.17 : [C U64, C U64] = TagId(0) Test.5;
|
||||
ret Test.17;
|
||||
|
||||
procedure Test.4 (Test.5, Test.16):
|
||||
let Test.21 : [C U64, C U64] = TagId(0) Test.5;
|
||||
ret Test.21;
|
||||
procedure Test.4 (Test.5, Test.15):
|
||||
let Test.16 : [C U64, C U64] = TagId(0) Test.5;
|
||||
ret Test.16;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.8 : List U8 = Array [1i64, 2i64, 3i64];
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
procedure Dict.1 ():
|
||||
let Dict.520 : List {[], []} = Array [];
|
||||
let Dict.527 : U64 = 0i64;
|
||||
let Dict.528 : U64 = 8i64;
|
||||
let Dict.521 : List U64 = CallByName List.11 Dict.527 Dict.528;
|
||||
let Dict.524 : I8 = CallByName Dict.34;
|
||||
let Dict.525 : U64 = 8i64;
|
||||
let Dict.522 : List I8 = CallByName List.11 Dict.524 Dict.525;
|
||||
let Dict.523 : U64 = 0i64;
|
||||
let Dict.519 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.520, Dict.521, Dict.522, Dict.523};
|
||||
ret Dict.519;
|
||||
procedure Dict.1 (Dict.518):
|
||||
let Dict.521 : List {[], []} = Array [];
|
||||
let Dict.528 : U64 = 0i64;
|
||||
let Dict.529 : U64 = 8i64;
|
||||
let Dict.522 : List U64 = CallByName List.11 Dict.528 Dict.529;
|
||||
let Dict.525 : I8 = CallByName Dict.34;
|
||||
let Dict.526 : U64 = 8i64;
|
||||
let Dict.523 : List I8 = CallByName List.11 Dict.525 Dict.526;
|
||||
let Dict.524 : U64 = 0i64;
|
||||
let Dict.520 : {List {[], []}, List U64, List I8, U64} = Struct {Dict.521, Dict.522, Dict.523, Dict.524};
|
||||
ret Dict.520;
|
||||
|
||||
procedure Dict.34 ():
|
||||
let Dict.526 : I8 = -128i64;
|
||||
ret Dict.526;
|
||||
let Dict.527 : I8 = -128i64;
|
||||
ret Dict.527;
|
||||
|
||||
procedure Dict.4 (Dict.507):
|
||||
let Dict.85 : U64 = StructAtIndex 3 Dict.507;
|
||||
|
@ -82,6 +82,7 @@ procedure Num.24 (#Attr.2, #Attr.3):
|
|||
ret Num.259;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.2 : {List {[], []}, List U64, List I8, U64} = CallByName Dict.1;
|
||||
let Test.3 : {} = Struct {};
|
||||
let Test.2 : {List {[], []}, List U64, List I8, U64} = CallByName Dict.1 Test.3;
|
||||
let Test.1 : U64 = CallByName Dict.4 Test.2;
|
||||
ret Test.1;
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
procedure Test.1 ():
|
||||
let Test.7 : U8 = 1i64;
|
||||
let Test.8 : U8 = 2i64;
|
||||
let Test.6 : {U8, U8} = Struct {Test.7, Test.8};
|
||||
ret Test.6;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.9 : {U8, U8} = CallByName Test.1;
|
||||
let Test.3 : U8 = StructAtIndex 0 Test.9;
|
||||
let Test.5 : {U8, U8} = CallByName Test.1;
|
||||
let Test.4 : U8 = StructAtIndex 1 Test.5;
|
||||
let Test.2 : List U8 = Array [Test.3, Test.4];
|
||||
ret Test.2;
|
|
@ -1,19 +0,0 @@
|
|||
procedure Test.1 ():
|
||||
let Test.11 : I64 = 2i64;
|
||||
let Test.12 : U8 = 1i64;
|
||||
let Test.10 : {I64, U8} = Struct {Test.11, Test.12};
|
||||
ret Test.10;
|
||||
|
||||
procedure Test.1 ():
|
||||
let Test.7 : I64 = 1i64;
|
||||
let Test.8 : U8 = 2i64;
|
||||
let Test.6 : {I64, U8} = Struct {Test.7, Test.8};
|
||||
ret Test.6;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.9 : {I64, U8} = CallByName Test.1;
|
||||
let Test.3 : U8 = StructAtIndex 1 Test.9;
|
||||
let Test.5 : {I64, U8} = CallByName Test.1;
|
||||
let Test.4 : U8 = StructAtIndex 1 Test.5;
|
||||
let Test.2 : List U8 = Array [Test.3, Test.4];
|
||||
ret Test.2;
|
|
@ -385,7 +385,7 @@ fn when_on_two_values() {
|
|||
#[mono_test]
|
||||
fn dict() {
|
||||
r#"
|
||||
Dict.len Dict.empty
|
||||
Dict.len (Dict.empty {})
|
||||
"#
|
||||
}
|
||||
|
||||
|
@ -1273,7 +1273,7 @@ fn aliased_polymorphic_closure() {
|
|||
}
|
||||
|
||||
#[mono_test]
|
||||
fn issue_2535_polymorphic_fields_referenced_in_list() {
|
||||
fn issue_2535_let_weakened_fields_referenced_in_list() {
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [nums] to "./platform"
|
||||
|
|
|
@ -4049,11 +4049,11 @@ fn flat_type_to_err_type(
|
|||
ErrorType::RecursiveTagUnion(rec_error_type, sub_tags.union(err_tags), sub_ext, pol)
|
||||
}
|
||||
|
||||
ErrorType::FlexVar(var) => {
|
||||
ErrorType::FlexVar(var) | ErrorType::FlexAbleVar(var, _) => {
|
||||
ErrorType::RecursiveTagUnion(rec_error_type, err_tags, TypeExt::FlexOpen(var), pol)
|
||||
}
|
||||
|
||||
ErrorType::RigidVar(var) => {
|
||||
ErrorType::RigidVar(var) | ErrorType::RigidAbleVar(var, _) => {
|
||||
ErrorType::RecursiveTagUnion(rec_error_type, err_tags, TypeExt::RigidOpen(var), pol)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue