Opaques take @ : %s/\$\([A-Z]\)/@\1/g

This commit is contained in:
Ayaz Hafiz 2022-04-25 12:26:38 -04:00
parent e43994530f
commit f1dc9c8298
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
20 changed files with 201 additions and 206 deletions

View file

@ -110,7 +110,7 @@ fn build_effect_always(
effect_symbol: Symbol, effect_symbol: Symbol,
var_store: &mut VarStore, var_store: &mut VarStore,
) -> (Symbol, Def) { ) -> (Symbol, Def) {
// Effect.always = \value -> $Effect \{} -> value // Effect.always = \value -> @Effect \{} -> value
let value_symbol = { let value_symbol = {
scope scope
@ -167,9 +167,9 @@ fn build_effect_always(
}) })
}; };
// \value -> $Effect \{} -> value // \value -> @Effect \{} -> value
let (function_var, always_closure) = { let (function_var, always_closure) = {
// `$Effect \{} -> value` // `@Effect \{} -> value`
let (specialized_def_type, type_arguments, lambda_set_variables) = let (specialized_def_type, type_arguments, lambda_set_variables) =
build_fresh_opaque_variables(var_store); build_fresh_opaque_variables(var_store);
let body = Expr::OpaqueRef { let body = Expr::OpaqueRef {
@ -255,7 +255,7 @@ fn build_effect_map(
effect_symbol: Symbol, effect_symbol: Symbol,
var_store: &mut VarStore, var_store: &mut VarStore,
) -> (Symbol, Def) { ) -> (Symbol, Def) {
// Effect.map = \$Effect thunk, mapper -> $Effect \{} -> mapper (thunk {}) // Effect.map = \@Effect thunk, mapper -> @Effect \{} -> mapper (thunk {})
let thunk_symbol = { let thunk_symbol = {
scope scope
@ -350,7 +350,7 @@ fn build_effect_map(
}) })
}; };
// \$Effect thunk, mapper // \@Effect thunk, mapper
let (specialized_def_type, type_arguments, lambda_set_variables) = let (specialized_def_type, type_arguments, lambda_set_variables) =
build_fresh_opaque_variables(var_store); build_fresh_opaque_variables(var_store);
let arguments = vec![ let arguments = vec![
@ -374,7 +374,7 @@ fn build_effect_map(
), ),
]; ];
// `$Effect \{} -> (mapper (thunk {}))` // `@Effect \{} -> (mapper (thunk {}))`
let (specialized_def_type, type_arguments, lambda_set_variables) = let (specialized_def_type, type_arguments, lambda_set_variables) =
build_fresh_opaque_variables(var_store); build_fresh_opaque_variables(var_store);
let body = Expr::OpaqueRef { let body = Expr::OpaqueRef {
@ -473,7 +473,7 @@ fn build_effect_after(
effect_symbol: Symbol, effect_symbol: Symbol,
var_store: &mut VarStore, var_store: &mut VarStore,
) -> (Symbol, Def) { ) -> (Symbol, Def) {
// Effect.after = \$Effect effect, toEffect -> toEffect (effect {}) // Effect.after = \@Effect effect, toEffect -> toEffect (effect {})
let thunk_symbol = { let thunk_symbol = {
scope scope
@ -636,7 +636,7 @@ fn build_effect_after(
(after_symbol, def) (after_symbol, def)
} }
/// turn `value` into `$Effect \{} -> value` /// turn `value` into `@Effect \{} -> value`
fn wrap_in_effect_thunk( fn wrap_in_effect_thunk(
body: Expr, body: Expr,
effect_symbol: Symbol, effect_symbol: Symbol,
@ -670,7 +670,7 @@ fn wrap_in_effect_thunk(
}) })
}; };
// `$Effect \{} -> value` // `@Effect \{} -> value`
let (specialized_def_type, type_arguments, lambda_set_variables) = let (specialized_def_type, type_arguments, lambda_set_variables) =
build_fresh_opaque_variables(var_store); build_fresh_opaque_variables(var_store);
Expr::OpaqueRef { Expr::OpaqueRef {
@ -749,14 +749,14 @@ fn build_effect_forever(
// //
// Effect.forever : Effect a -> Effect b // Effect.forever : Effect a -> Effect b
// Effect.forever = \effect -> // Effect.forever = \effect ->
// $Effect \{} -> // @Effect \{} ->
// $Effect thunk1 = effect // @Effect thunk1 = effect
// _ = thunk1 {} // _ = thunk1 {}
// $Effect thunk2 = Effect.forever effect // @Effect thunk2 = Effect.forever effect
// thunk2 {} // thunk2 {}
// //
// We then rely on our defunctionalization to turn this into a tail-recursive loop. // We then rely on our defunctionalization to turn this into a tail-recursive loop.
// First the `$Effect` wrapper melts away // First the `@Effect` wrapper melts away
// //
// Effect.forever : ({} -> a) -> ({} -> b) // Effect.forever : ({} -> a) -> ({} -> b)
// Effect.forever = \effect -> // Effect.forever = \effect ->
@ -955,7 +955,7 @@ fn build_effect_forever_inner_body(
.unwrap() .unwrap()
}; };
// $Effect thunk1 = effect // @Effect thunk1 = effect
let thunk_from_effect = { let thunk_from_effect = {
let whole_var = var_store.fresh(); let whole_var = var_store.fresh();
@ -1022,7 +1022,7 @@ fn build_effect_forever_inner_body(
}; };
// ``` // ```
// $Effect thunk2 = forever effect // @Effect thunk2 = forever effect
// thunk2 {} // thunk2 {}
// ``` // ```
let force_thunk2 = Loc::at_zero(force_effect( let force_thunk2 = Loc::at_zero(force_effect(
@ -1330,7 +1330,7 @@ fn build_effect_loop_inner_body(
}; };
// ``` // ```
// $Effect thunk2 = loop effect // @Effect thunk2 = loop effect
// thunk2 {} // thunk2 {}
// ``` // ```
let force_thunk2 = force_effect(loop_new_state_step, effect_symbol, thunk2_symbol, var_store); let force_thunk2 = force_effect(loop_new_state_step, effect_symbol, thunk2_symbol, var_store);

View file

@ -163,8 +163,7 @@ pub enum Expr {
name: TagName, name: TagName,
}, },
/// A wrapping of an opaque type, like `$Age 21` /// A wrapping of an opaque type, like `@Age 21`
// TODO(opaques): $->@ above when opaques land
OpaqueRef { OpaqueRef {
opaque_var: Variable, opaque_var: Variable,
name: Symbol, name: Symbol,

View file

@ -134,15 +134,14 @@ impl Scope {
} }
/// Check if there is an opaque type alias referenced by `opaque_ref` referenced in the /// Check if there is an opaque type alias referenced by `opaque_ref` referenced in the
/// current scope. E.g. `$Age` must reference an opaque `Age` declared in this module, not any /// current scope. E.g. `@Age` must reference an opaque `Age` declared in this module, not any
/// other! /// other!
// TODO(opaques): $->@ in the above comment
pub fn lookup_opaque_ref( pub fn lookup_opaque_ref(
&self, &self,
opaque_ref: &str, opaque_ref: &str,
lookup_region: Region, lookup_region: Region,
) -> Result<(Symbol, &Alias), RuntimeError> { ) -> Result<(Symbol, &Alias), RuntimeError> {
debug_assert!(opaque_ref.starts_with('$')); debug_assert!(opaque_ref.starts_with('@'));
let opaque = opaque_ref[1..].into(); let opaque = opaque_ref[1..].into();
match self.idents.get(&opaque) { match self.idents.get(&opaque) {

View file

@ -757,9 +757,9 @@ mod test_load {
r#" r#"
interface Main exposes [ twenty, readAge ] imports [ Age.{ Age } ] interface Main exposes [ twenty, readAge ] imports [ Age.{ Age } ]
twenty = $Age 20 twenty = @Age 20
readAge = \$Age n -> n readAge = \@Age n -> n
"# "#
), ),
), ),
@ -775,7 +775,7 @@ mod test_load {
The unwrapped opaque type Age referenced here: The unwrapped opaque type Age referenced here:
3 twenty = $Age 20 3 twenty = @Age 20
^^^^ ^^^^
is imported from another module: is imported from another module:
@ -789,7 +789,7 @@ mod test_load {
The unwrapped opaque type Age referenced here: The unwrapped opaque type Age referenced here:
5 readAge = \$Age n -> n 5 readAge = \@Age n -> n
^^^^ ^^^^
is imported from another module: is imported from another module:

View file

@ -190,8 +190,7 @@ pub enum Expr<'a> {
// Tags // Tags
GlobalTag(&'a str), GlobalTag(&'a str),
// Reference to an opaque type, e.g. $Opaq // Reference to an opaque type, e.g. @Opaq
// TODO(opaques): $->@ in the above comment
OpaqueRef(&'a str), OpaqueRef(&'a str),
// Pattern Matching // Pattern Matching

View file

@ -36,8 +36,7 @@ impl<'a> From<&'a UppercaseIdent<'a>> for &'a str {
pub enum Ident<'a> { pub enum Ident<'a> {
/// Foo or Bar /// Foo or Bar
GlobalTag(&'a str), GlobalTag(&'a str),
/// $Foo or $Bar /// @Foo or @Bar
// TODO(opaques): $->@ in the above comment
OpaqueRef(&'a str), OpaqueRef(&'a str),
/// foo or foo.bar or Foo.Bar.baz.qux /// foo or foo.bar or Foo.Bar.baz.qux
Access { Access {
@ -291,10 +290,10 @@ fn chomp_accessor(buffer: &[u8], pos: Position) -> Result<&str, BadIdent> {
} }
} }
/// a `$Token` opaque /// a `@Token` opaque
fn chomp_opaque_ref(buffer: &[u8], pos: Position) -> Result<&str, BadIdent> { fn chomp_opaque_ref(buffer: &[u8], pos: Position) -> Result<&str, BadIdent> {
// assumes the leading `$` has NOT been chomped already // assumes the leading `@` has NOT been chomped already
debug_assert_eq!(buffer.get(0), Some(&b'$')); debug_assert_eq!(buffer.get(0), Some(&b'@'));
use encode_unicode::CharExt; use encode_unicode::CharExt;
let bad_ident = BadIdent::BadOpaqueRef; let bad_ident = BadIdent::BadOpaqueRef;
@ -334,7 +333,7 @@ fn chomp_identifier_chain<'a>(
} }
Err(fail) => return Err((1, fail)), Err(fail) => return Err((1, fail)),
}, },
'$' => match chomp_opaque_ref(buffer, pos) { '@' => match chomp_opaque_ref(buffer, pos) {
Ok(tagname) => { Ok(tagname) => {
let bytes_parsed = tagname.len(); let bytes_parsed = tagname.len();

View file

@ -5462,7 +5462,7 @@ mod solve_expr {
r#" r#"
Age := U32 Age := U32
$Age 21 @Age 21
"# "#
), ),
r#"Age"#, r#"Age"#,
@ -5477,7 +5477,7 @@ mod solve_expr {
Age := U32 Age := U32
a : Age a : Age
a = $Age 21 a = @Age 21
a a
"# "#
@ -5493,7 +5493,7 @@ mod solve_expr {
r#" r#"
Id n := [ Id U32 n ] Id n := [ Id U32 n ]
$Id (Id 21 "sasha") @Id (Id 21 "sasha")
"# "#
), ),
r#"Id Str"#, r#"Id Str"#,
@ -5508,7 +5508,7 @@ mod solve_expr {
Id n := [ Id U32 n ] Id n := [ Id U32 n ]
a : Id Str a : Id Str
a = $Id (Id 21 "sasha") a = @Id (Id 21 "sasha")
a a
"# "#
@ -5526,8 +5526,8 @@ mod solve_expr {
condition : Bool condition : Bool
if condition if condition
then $Id (Id 21 (Y "sasha")) then @Id (Id 21 (Y "sasha"))
else $Id (Id 21 (Z "felix")) else @Id (Id 21 (Z "felix"))
"# "#
), ),
r#"Id [ Y Str, Z Str ]*"#, r#"Id [ Y Str, Z Str ]*"#,
@ -5545,8 +5545,8 @@ mod solve_expr {
v : Id [ Y Str, Z Str ] v : Id [ Y Str, Z Str ]
v = v =
if condition if condition
then $Id (Id 21 (Y "sasha")) then @Id (Id 21 (Y "sasha"))
else $Id (Id 21 (Z "felix")) else @Id (Id 21 (Z "felix"))
v v
"# "#
@ -5562,7 +5562,7 @@ mod solve_expr {
r#" r#"
Age := U32 Age := U32
\$Age n -> n \@Age n -> n
"# "#
), ),
r#"Age -> U32"#, r#"Age -> U32"#,
@ -5577,7 +5577,7 @@ mod solve_expr {
Age := U32 Age := U32
v : Age -> U32 v : Age -> U32
v = \$Age n -> n v = \@Age n -> n
v v
"# "#
), ),
@ -5592,7 +5592,7 @@ mod solve_expr {
r#" r#"
Id n := [ Id U32 n ] Id n := [ Id U32 n ]
\$Id (Id _ n) -> n \@Id (Id _ n) -> n
"# "#
), ),
r#"Id a -> a"#, r#"Id a -> a"#,
@ -5607,7 +5607,7 @@ mod solve_expr {
Id n := [ Id U32 n ] Id n := [ Id U32 n ]
v : Id a -> a v : Id a -> a
v = \$Id (Id _ n) -> n v = \@Id (Id _ n) -> n
v v
"# "#
@ -5625,7 +5625,7 @@ mod solve_expr {
strToBool : Str -> Bool strToBool : Str -> Bool
\$Id (Id _ n) -> strToBool n \@Id (Id _ n) -> strToBool n
"# "#
), ),
r#"Id Str -> Bool"#, r#"Id Str -> Bool"#,
@ -5642,7 +5642,7 @@ mod solve_expr {
strToBool : Str -> Bool strToBool : Str -> Bool
v : Id Str -> Bool v : Id Str -> Bool
v = \$Id (Id _ n) -> strToBool n v = \@Id (Id _ n) -> strToBool n
v v
"# "#
@ -5660,9 +5660,9 @@ mod solve_expr {
\id -> \id ->
when id is when id is
$Id (Id _ A) -> "" @Id (Id _ A) -> ""
$Id (Id _ B) -> "" @Id (Id _ B) -> ""
$Id (Id _ (C { a: "" })) -> "" @Id (Id _ (C { a: "" })) -> ""
"# "#
), ),
r#"Id [ A, B, C { a : Str }* ] -> Str"#, r#"Id [ A, B, C { a : Str }* ] -> Str"#,
@ -5679,9 +5679,9 @@ mod solve_expr {
f : Id [ A, B, C { a : Str }e ] -> Str f : Id [ A, B, C { a : Str }e ] -> Str
f = \id -> f = \id ->
when id is when id is
$Id (Id _ A) -> "" @Id (Id _ A) -> ""
$Id (Id _ B) -> "" @Id (Id _ B) -> ""
$Id (Id _ (C { a: "" })) -> "" @Id (Id _ (C { a: "" })) -> ""
f f
"# "#
@ -5703,7 +5703,7 @@ mod solve_expr {
effectAlways = \x -> effectAlways = \x ->
inner = \{} -> x inner = \{} -> x
$Effect inner @Effect inner
"# "#
), ),
r#"a -> Effect a"#, r#"a -> Effect a"#,
@ -5765,8 +5765,8 @@ mod solve_expr {
insert : Outer k, k -> Outer k insert : Outer k, k -> Outer k
insert = \m, var -> insert = \m, var ->
when m is when m is
$Outer Empty -> $Outer (Wrapped var) @Outer Empty -> @Outer (Wrapped var)
$Outer (Wrapped _) -> $Outer (Wrapped var) @Outer (Wrapped _) -> @Outer (Wrapped var)
insert insert
"# "#
@ -5782,9 +5782,9 @@ mod solve_expr {
r#" r#"
Outer k := [ Empty, Wrapped k ] Outer k := [ Empty, Wrapped k ]
when ($Outer Empty) is when (@Outer Empty) is
$Outer Empty -> $Outer (Wrapped "") @Outer Empty -> @Outer (Wrapped "")
$Outer (Wrapped k) -> $Outer (Wrapped k) @Outer (Wrapped k) -> @Outer (Wrapped k)
"# "#
), ),
r#"Outer Str"#, r#"Outer Str"#,
@ -5798,9 +5798,9 @@ mod solve_expr {
r#" r#"
Outer := [ A, B ] Outer := [ A, B ]
when ($Outer A) is when (@Outer A) is
$Outer A -> $Outer A @Outer A -> @Outer A
$Outer B -> $Outer B @Outer B -> @Outer B
"# "#
), ),
r#"Outer"#, r#"Outer"#,
@ -5857,7 +5857,7 @@ mod solve_expr {
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
"# "#
), ),
[("Hash:hash", "Id")], [("Hash:hash", "Id")],
@ -5877,8 +5877,8 @@ mod solve_expr {
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
hash32 = \$Id n -> Num.toU32 n hash32 = \@Id n -> Num.toU32 n
"# "#
), ),
[("Hash:hash", "Id"), ("Hash:hash32", "Id")], [("Hash:hash", "Id"), ("Hash:hash32", "Id")],
@ -5902,11 +5902,11 @@ mod solve_expr {
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
hash32 = \$Id n -> Num.toU32 n hash32 = \@Id n -> Num.toU32 n
eq = \$Id m, $Id n -> m == n eq = \@Id m, @Id n -> m == n
le = \$Id m, $Id n -> m < n le = \@Id m, @Id n -> m < n
"# "#
), ),
[ [
@ -5931,7 +5931,7 @@ mod solve_expr {
Id := U64 Id := U64
hash : Id -> U64 hash : Id -> U64
hash = \$Id n -> n hash = \@Id n -> n
"# "#
), ),
[("Hash:hash", "Id")], [("Hash:hash", "Id")],
@ -5969,9 +5969,9 @@ mod solve_expr {
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
zero = hash ($Id 0) zero = hash (@Id 0)
"# "#
), ),
"U64", "U64",
@ -6062,9 +6062,9 @@ mod solve_expr {
hashEq = \x, y -> hash x == hash y hashEq = \x, y -> hash x == hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
result = hashEq ($Id 100) ($Id 101) result = hashEq (@Id 100) (@Id 101)
"# "#
), ),
"Bool", "Bool",
@ -6084,12 +6084,12 @@ mod solve_expr {
mulHashes = \x, y -> hash x * hash y mulHashes = \x, y -> hash x * hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
Three := {} Three := {}
hash = \$Three _ -> 3 hash = \@Three _ -> 3
result = mulHashes ($Id 100) ($Three {}) result = mulHashes (@Id 100) (@Three {})
"# "#
), ),
"U64", "U64",
@ -6162,7 +6162,7 @@ mod solve_expr {
Task a err : Effect (Result a err) Task a err : Effect (Result a err)
always : a -> Task a * always : a -> Task a *
always = \x -> $Effect (\{} -> Ok x) always = \x -> @Effect (\{} -> Ok x)
"# "#
), ),
"a -> Task a *", "a -> Task a *",

View file

@ -23,9 +23,9 @@ fn hash_specialization() {
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
main = hash ($Id 1234) main = hash (@Id 1234)
"# "#
), ),
1234, 1234,
@ -46,13 +46,13 @@ fn hash_specialization_multiple_add() {
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
One := {} One := {}
hash = \$One _ -> 1 hash = \@One _ -> 1
main = hash ($Id 1234) + hash ($One {}) main = hash (@Id 1234) + hash (@One {})
"# "#
), ),
1235, 1235,
@ -73,11 +73,11 @@ fn alias_member_specialization() {
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
main = main =
aliasedHash = hash aliasedHash = hash
aliasedHash ($Id 1234) aliasedHash (@Id 1234)
"# "#
), ),
1234, 1234,
@ -100,9 +100,9 @@ fn ability_constrained_in_non_member_usage() {
mulHashes = \x, y -> hash x * hash y mulHashes = \x, y -> hash x * hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
result = mulHashes ($Id 5) ($Id 7) result = mulHashes (@Id 5) (@Id 7)
"# "#
), ),
35, 35,
@ -124,9 +124,9 @@ fn ability_constrained_in_non_member_usage_inferred() {
mulHashes = \x, y -> hash x * hash y mulHashes = \x, y -> hash x * hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
result = mulHashes ($Id 5) ($Id 7) result = mulHashes (@Id 5) (@Id 7)
"# "#
), ),
35, 35,
@ -149,12 +149,12 @@ fn ability_constrained_in_non_member_multiple_specializations() {
mulHashes = \x, y -> hash x * hash y mulHashes = \x, y -> hash x * hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
Three := {} Three := {}
hash = \$Three _ -> 3 hash = \@Three _ -> 3
result = mulHashes ($Id 100) ($Three {}) result = mulHashes (@Id 100) (@Three {})
"# "#
), ),
300, 300,
@ -176,12 +176,12 @@ fn ability_constrained_in_non_member_multiple_specializations_inferred() {
mulHashes = \x, y -> hash x * hash y mulHashes = \x, y -> hash x * hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
Three := {} Three := {}
hash = \$Three _ -> 3 hash = \@Three _ -> 3
result = mulHashes ($Id 100) ($Three {}) result = mulHashes (@Id 100) (@Three {})
"# "#
), ),
300, 300,
@ -204,12 +204,12 @@ fn ability_used_as_type_still_compiles() {
mulHashes = \x, y -> hash x * hash y mulHashes = \x, y -> hash x * hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
Three := {} Three := {}
hash = \$Three _ -> 3 hash = \@Three _ -> 3
result = mulHashes ($Id 100) ($Three {}) result = mulHashes (@Id 100) (@Three {})
"# "#
), ),
300, 300,

View file

@ -1137,10 +1137,10 @@ fn io_poc_effect() {
Effect a := {} -> a Effect a := {} -> a
succeed : a -> Effect a succeed : a -> Effect a
succeed = \x -> $Effect \{} -> x succeed = \x -> @Effect \{} -> x
runEffect : Effect a -> a runEffect : Effect a -> a
runEffect = \$Effect thunk -> thunk {} runEffect = \@Effect thunk -> thunk {}
foo : Effect F64 foo : Effect F64
foo = foo =
@ -1196,7 +1196,7 @@ fn return_wrapped_function_pointer() {
Effect a := {} -> a Effect a := {} -> a
foo : Effect {} foo : Effect {}
foo = $Effect \{} -> {} foo = @Effect \{} -> {}
main : Effect {} main : Effect {}
main = foo main = foo
@ -1244,7 +1244,7 @@ fn return_wrapped_closure() {
foo = foo =
x = 5 x = 5
$Effect (\{} -> if x > 3 then {} else {}) @Effect (\{} -> if x > 3 then {} else {})
main : Effect {} main : Effect {}
main = foo main = foo
@ -1870,10 +1870,10 @@ fn task_always_twice() {
effectAlways = \x -> effectAlways = \x ->
inner = \{} -> x inner = \{} -> x
$Effect inner @Effect inner
effectAfter : Effect a, (a -> Effect b) -> Effect b effectAfter : Effect a, (a -> Effect b) -> Effect b
effectAfter = \($Effect thunk), transform -> transform (thunk {}) effectAfter = \(@Effect thunk), transform -> transform (thunk {})
Task a err : Effect (Result a err) Task a err : Effect (Result a err)
@ -1918,7 +1918,7 @@ fn wildcard_rigid() {
always = \x -> always = \x ->
inner = \{} -> (Ok x) inner = \{} -> (Ok x)
$Effect inner @Effect inner
main : Task {} (Float *) main : Task {} (Float *)
@ -1947,7 +1947,7 @@ fn alias_of_alias_with_type_arguments() {
always = \x -> always = \x ->
inner = (Ok x) inner = (Ok x)
$Effect inner @Effect inner
main : Task {} (Float *) main : Task {} (Float *)
@ -1975,10 +1975,10 @@ fn todo_bad_error_message() {
effectAlways = \x -> effectAlways = \x ->
inner = \{} -> x inner = \{} -> x
$Effect inner @Effect inner
effectAfter : Effect a, (a -> Effect b) -> Effect b effectAfter : Effect a, (a -> Effect b) -> Effect b
effectAfter = \($Effect thunk), transform -> transform (thunk {}) effectAfter = \(@Effect thunk), transform -> transform (thunk {})
Task a err : Effect (Result a err) Task a err : Effect (Result a err)
@ -3111,7 +3111,7 @@ fn nested_rigid_alias() {
p2 p2
main = main =
when foo ($Identity "foo") is when foo (@Identity "foo") is
_ -> "hello world" _ -> "hello world"
"# "#
), ),
@ -3225,13 +3225,13 @@ fn recursively_build_effect() {
XEffect a := {} -> a XEffect a := {} -> a
always : a -> XEffect a always : a -> XEffect a
always = \x -> $XEffect (\{} -> x) always = \x -> @XEffect (\{} -> x)
after : XEffect a, (a -> XEffect b) -> XEffect b after : XEffect a, (a -> XEffect b) -> XEffect b
after = \($XEffect e), toB -> after = \(@XEffect e), toB ->
$XEffect \{} -> @XEffect \{} ->
when toB (e {}) is when toB (e {}) is
$XEffect e2 -> @XEffect e2 ->
e2 {} e2 {}
"# "#
), ),

View file

@ -1058,7 +1058,7 @@ fn phantom_polymorphic() {
World := {} World := {}
zero : Point World zero : Point World
zero = Point ($World {}) 0 0 zero = Point (@World {}) 0 0
add : Point a -> Point a add : Point a -> Point a
add = \(Point c x y) -> (Point c x y) add = \(Point c x y) -> (Point c x y)
@ -1593,11 +1593,11 @@ fn opaque_assign_to_symbol() {
fromUtf8 : U8 -> Result Variable [ InvalidVariableUtf8 ] fromUtf8 : U8 -> Result Variable [ InvalidVariableUtf8 ]
fromUtf8 = \char -> fromUtf8 = \char ->
Ok ($Variable char) Ok (@Variable char)
out = out =
when fromUtf8 98 is when fromUtf8 98 is
Ok ($Variable n) -> n Ok (@Variable n) -> n
_ -> 1 _ -> 1
"# "#
), ),

View file

@ -1323,9 +1323,9 @@ fn specialize_ability_call() {
Id := U64 Id := U64
hash : Id -> U64 hash : Id -> U64
hash = \$Id n -> n hash = \@Id n -> n
main = hash ($Id 1234) main = hash (@Id 1234)
"# "#
) )
} }
@ -1340,7 +1340,7 @@ fn opaque_assign_to_symbol() {
fromUtf8 : U8 -> Result Variable [ InvalidVariableUtf8 ] fromUtf8 : U8 -> Result Variable [ InvalidVariableUtf8 ]
fromUtf8 = \char -> fromUtf8 = \char ->
Ok ($Variable char) Ok (@Variable char)
out = fromUtf8 98 out = fromUtf8 98
"# "#

View file

@ -7,7 +7,7 @@ DecodeProblem : [ OutOfBytes ]
Decoder a := State -> [ Good State a, Bad DecodeProblem ] Decoder a := State -> [ Good State a, Bad DecodeProblem ]
decode : List U8, Decoder a -> Result a DecodeProblem decode : List U8, Decoder a -> Result a DecodeProblem
decode = \bytes, $Decoder decoder -> decode = \bytes, @Decoder decoder ->
when decoder { bytes, cursor: 0 } is when decoder { bytes, cursor: 0 } is
Good _ value -> Good _ value ->
Ok value Ok value
@ -16,11 +16,11 @@ decode = \bytes, $Decoder decoder ->
Err e Err e
succeed : a -> Decoder a succeed : a -> Decoder a
succeed = \value -> $Decoder \state -> Good state value succeed = \value -> @Decoder \state -> Good state value
map : Decoder a, (a -> b) -> Decoder b map : Decoder a, (a -> b) -> Decoder b
map = \$Decoder decoder, transform -> map = \@Decoder decoder, transform ->
$Decoder @Decoder
\state -> \state ->
when decoder state is when decoder state is
Good state1 value -> Good state1 value ->
@ -30,8 +30,8 @@ map = \$Decoder decoder, transform ->
Bad e Bad e
map2 : Decoder a, Decoder b, (a, b -> c) -> Decoder c map2 : Decoder a, Decoder b, (a, b -> c) -> Decoder c
map2 = \$Decoder decoder1, $Decoder decoder2, transform -> map2 = \@Decoder decoder1, @Decoder decoder2, transform ->
$Decoder @Decoder
\state1 -> \state1 ->
when decoder1 state1 is when decoder1 state1 is
Good state2 a -> Good state2 a ->
@ -46,8 +46,8 @@ map2 = \$Decoder decoder1, $Decoder decoder2, transform ->
Bad e Bad e
map3 : Decoder a, Decoder b, Decoder c, (a, b, c -> d) -> Decoder d map3 : Decoder a, Decoder b, Decoder c, (a, b, c -> d) -> Decoder d
map3 = \$Decoder decoder1, $Decoder decoder2, $Decoder decoder3, transform -> map3 = \@Decoder decoder1, @Decoder decoder2, @Decoder decoder3, transform ->
$Decoder @Decoder
\state1 -> \state1 ->
when decoder1 state1 is when decoder1 state1 is
Good state2 a -> Good state2 a ->
@ -67,12 +67,12 @@ map3 = \$Decoder decoder1, $Decoder decoder2, $Decoder decoder3, transform ->
Bad e Bad e
after : Decoder a, (a -> Decoder b) -> Decoder b after : Decoder a, (a -> Decoder b) -> Decoder b
after = \$Decoder decoder, transform -> after = \@Decoder decoder, transform ->
$Decoder @Decoder
\state -> \state ->
when decoder state is when decoder state is
Good state1 value -> Good state1 value ->
($Decoder decoder1) = transform value (@Decoder decoder1) = transform value
decoder1 state1 decoder1 state1
@ -80,7 +80,7 @@ after = \$Decoder decoder, transform ->
Bad e Bad e
u8 : Decoder U8 u8 : Decoder U8
u8 = $Decoder u8 = @Decoder
\state -> \state ->
when List.get state.bytes state.cursor is when List.get state.bytes state.cursor is
Ok b -> Ok b ->
@ -93,12 +93,12 @@ Step state b : [ Loop state, Done b ]
loop : (state -> Decoder (Step state a)), state -> Decoder a loop : (state -> Decoder (Step state a)), state -> Decoder a
loop = \stepper, initial -> loop = \stepper, initial ->
$Decoder @Decoder
\state -> \state ->
loopHelp stepper initial state loopHelp stepper initial state
loopHelp = \stepper, accum, state -> loopHelp = \stepper, accum, state ->
($Decoder stepper1) = stepper accum (@Decoder stepper1) = stepper accum
when stepper1 state is when stepper1 state is
Good newState (Done value) -> Good newState (Done value) ->

View file

@ -15,7 +15,7 @@ totalCount =
+ 1 + 1
toStr : Variable -> Str toStr : Variable -> Str
toStr = \$Variable char -> toStr = \@Variable char ->
when Str.fromUtf8 [ char ] is when Str.fromUtf8 [ char ] is
Ok str -> Ok str ->
str str
@ -33,11 +33,11 @@ fromUtf8 = \char ->
<= 0x7A <= 0x7A
# "z" # "z"
then then
Ok ($Variable char) Ok (@Variable char)
else else
Err InvalidVariableUtf8 Err InvalidVariableUtf8
toIndex : Variable -> Nat toIndex : Variable -> Nat
toIndex = \$Variable char -> toIndex = \@Variable char ->
Num.intCast (char - 0x61)# "a" Num.intCast (char - 0x61)# "a"
# List.first (Str.toUtf8 "a") # List.first (Str.toUtf8 "a")

View file

@ -5,19 +5,19 @@ interface File
Handle := U64 Handle := U64
line : Handle -> Task.Task Str * line : Handle -> Task.Task Str *
line = \$Handle handle -> Effect.after (Effect.getFileLine handle) Task.succeed line = \@Handle handle -> Effect.after (Effect.getFileLine handle) Task.succeed
chunk : Handle -> Task.Task (List U8) * chunk : Handle -> Task.Task (List U8) *
chunk = \$Handle handle -> Effect.after (Effect.getFileBytes handle) Task.succeed chunk = \@Handle handle -> Effect.after (Effect.getFileBytes handle) Task.succeed
open : Str -> Task.Task Handle * open : Str -> Task.Task Handle *
open = \path -> open = \path ->
Effect.openFile path Effect.openFile path
|> Effect.map (\id -> $Handle id) |> Effect.map (\id -> @Handle id)
|> Effect.after Task.succeed |> Effect.after Task.succeed
close : Handle -> Task.Task {} * close : Handle -> Task.Task {} *
close = \$Handle handle -> Effect.after (Effect.closeFile handle) Task.succeed close = \@Handle handle -> Effect.after (Effect.closeFile handle) Task.succeed
withOpen : Str, (Handle -> Task {} a) -> Task {} a withOpen : Str, (Handle -> Task {} a) -> Task {} a
withOpen = \path, callback -> withOpen = \path, callback ->

View file

@ -48,16 +48,16 @@ keep : Parser a, (a -> Parser b) -> Parser b
skip : Parser *, ({} -> Parser b) -> Parser b skip : Parser *, ({} -> Parser b) -> Parser b
symbol : Str -> Parser {} symbol : Str -> Parser {}
symbol = \symbol -> $Parser Str.chompStr symbol symbol = \symbol -> @Parser Str.chompStr symbol
u8 : Parser U8 u8 : Parser U8
u8 = $Parser Str.parseU8 u8 = @Parser Str.parseU8
i8 : Parser I8 i8 : Parser I8
i8 = $Parser Str.parseI8 i8 = @Parser Str.parseI8
end : Parser {} end : Parser {}
end = $Parser \str -> end = @Parser \str ->
if Str.isEmpty str then if Str.isEmpty str then
Ok {} Ok {}
else else
@ -65,7 +65,7 @@ end = $Parser \str ->
lazy : ({} -> Parser a) -> Parser a lazy : ({} -> Parser a) -> Parser a
lazy = \thunk -> lazy = \thunk ->
$Parser \str -> @Parser \str ->
$Parser parse = thunk {} @Parser parse = thunk {}
parse str parse str

View file

@ -13,9 +13,9 @@ interface Unicode.CodePoint.Internal
CodePoint := U32 CodePoint := U32
fromU32Unchecked : U32 -> CodePoint fromU32Unchecked : U32 -> CodePoint
fromU32Unchecked = \u32 -> $CodePoint u32 fromU32Unchecked = \u32 -> @CodePoint u32
toU32 : CodePoint -> U32 toU32 : CodePoint -> U32
toU32 = \$CodePoint u32 -> u32 toU32 = \@CodePoint u32 -> u32
fromU32 : U32 -> Result CodePoint [ BadCodePoint ]* fromU32 : U32 -> Result CodePoint [ BadCodePoint ]*

View file

@ -21,7 +21,7 @@ interface Unicode.Scalar
Scalar := U32 Scalar := U32
toStr : Scalar -> Str toStr : Scalar -> Str
toStr = \$Scalar u32 toStr = \@Scalar u32
when Str.fromScalar u32 is when Str.fromScalar u32 is
Ok str -> str Ok str -> str
Err _ -> Err _ ->
@ -29,10 +29,10 @@ toStr = \$Scalar u32
# this Err branch will never run. That's because it only runs # this Err branch will never run. That's because it only runs
# if Str.fromScalar receives an invalid scalar value, and we've # if Str.fromScalar receives an invalid scalar value, and we've
# already validated this! # already validated this!
toStr ($Scalar (scalar * 256)) toStr (@Scalar (scalar * 256))
toCodePt : Scalar -> CodePt toCodePt : Scalar -> CodePt
toCodePt = \$Scalar u32 -> Internal.fromU32Unchecked u32 toCodePt = \@Scalar u32 -> Internal.fromU32Unchecked u32
fromCodePt : CodePt -> Result Scalar [ PointWasSurrogate ]* fromCodePt : CodePt -> Result Scalar [ PointWasSurrogate ]*

View file

@ -1026,7 +1026,7 @@ fn opaque_apply() {
r#" r#"
Age := U32 Age := U32
$Age 23 @Age 23
"# "#
), ),
"23 : Age", "23 : Age",
@ -1040,7 +1040,7 @@ fn opaque_apply_polymorphic() {
r#" r#"
F t u := [ Package t u ] F t u := [ Package t u ]
$F (Package "" { a: "" }) @F (Package "" { a: "" })
"# "#
), ),
r#"Package "" { a: "" } : F Str { a : Str }"#, r#"Package "" { a: "" } : F Str { a : Str }"#,
@ -1054,9 +1054,9 @@ fn opaque_pattern_and_call() {
r#" r#"
F t u := [ Package t u ] F t u := [ Package t u ]
f = \$F (Package A {}) -> $F (Package {} A) f = \@F (Package A {}) -> @F (Package {} A)
f ($F (Package A {})) f (@F (Package A {}))
"# "#
), ),
r#"Package {} A : F {} [ A ]*"#, r#"Package {} A : F {} [ A ]*"#,

View file

@ -440,8 +440,7 @@ impl<'a> RocDocAllocator<'a> {
pub fn wrapped_opaque_name(&'a self, opaque: Symbol) -> DocBuilder<'a, Self, Annotation> { pub fn wrapped_opaque_name(&'a self, opaque: Symbol) -> DocBuilder<'a, Self, Annotation> {
debug_assert_eq!(opaque.module_id(), self.home, "Opaque wrappings can only be defined in the same module they're defined in, but this one is defined elsewhere: {:?}", opaque); debug_assert_eq!(opaque.module_id(), self.home, "Opaque wrappings can only be defined in the same module they're defined in, but this one is defined elsewhere: {:?}", opaque);
// TODO(opaques): $->@ self.text(format!("@{}", opaque.ident_str(self.interns)))
self.text(format!("${}", opaque.ident_str(self.interns)))
.annotate(Annotation::Opaque) .annotate(Annotation::Opaque)
} }

View file

@ -5978,7 +5978,7 @@ I need all branches in an `if` to have the same type!
report_problem_as( report_problem_as(
indoc!( indoc!(
r#" r#"
$UUID.bar @UUID.bar
"# "#
), ),
indoc!( indoc!(
@ -5987,7 +5987,7 @@ I need all branches in an `if` to have the same type!
I am very confused by this field access: I am very confused by this field access:
1 $UUID.bar 1 @UUID.bar
^^^^ ^^^^
It looks like a record field access on an opaque reference. It looks like a record field access on an opaque reference.
@ -8237,7 +8237,7 @@ I need all branches in an `if` to have the same type!
report_problem_as( report_problem_as(
indoc!( indoc!(
r#" r#"
$Age 21 @Age 21
"# "#
), ),
indoc!( indoc!(
@ -8246,7 +8246,7 @@ I need all branches in an `if` to have the same type!
The opaque type Age referenced here is not defined: The opaque type Age referenced here is not defined:
1 $Age 21 1 @Age 21
^^^^ ^^^^
Note: It looks like there are no opaque types declared in this scope yet! Note: It looks like there are no opaque types declared in this scope yet!
@ -8262,7 +8262,7 @@ I need all branches in an `if` to have the same type!
r#" r#"
Age : Num.U8 Age : Num.U8
$Age 21 @Age 21
"# "#
), ),
indoc!( indoc!(
@ -8271,7 +8271,7 @@ I need all branches in an `if` to have the same type!
The opaque type Age referenced here is not defined: The opaque type Age referenced here is not defined:
3 $Age 21 3 @Age 21
^^^^ ^^^^
Note: There is an alias of the same name: Note: There is an alias of the same name:
@ -8300,19 +8300,19 @@ I need all branches in an `if` to have the same type!
report_problem_as( report_problem_as(
indoc!( indoc!(
r#" r#"
OtherModule.$Age 21 OtherModule.@Age 21
"# "#
), ),
// TODO: get rid of the first error. Consider parsing OtherModule.$Age to completion // TODO: get rid of the first error. Consider parsing OtherModule.@Age to completion
// and checking it during can. The reason the error appears is because it is parsed as // and checking it during can. The reason the error appears is because it is parsed as
// Apply(Error(OtherModule), [ $Age, 21 ]) // Apply(Error(OtherModule), [ @Age, 21 ])
indoc!( indoc!(
r#" r#"
OPAQUE TYPE NOT APPLIED /code/proj/Main.roc OPAQUE TYPE NOT APPLIED /code/proj/Main.roc
This opaque type is not applied to an argument: This opaque type is not applied to an argument:
1 OtherModule.$Age 21 1 OtherModule.@Age 21
^^^^ ^^^^
Note: Opaque types always wrap exactly one argument! Note: Opaque types always wrap exactly one argument!
@ -8321,7 +8321,7 @@ I need all branches in an `if` to have the same type!
I am trying to parse a qualified name here: I am trying to parse a qualified name here:
1 OtherModule.$Age 21 1 OtherModule.@Age 21
^ ^
I was expecting to see an identifier next, like height. A complete I was expecting to see an identifier next, like height. A complete
@ -8340,11 +8340,11 @@ I need all branches in an `if` to have the same type!
Age := Num.U8 Age := Num.U8
21u8 21u8
$Age age @Age age
"# "#
), ),
// TODO(opaques): there is a potential for a better error message here, if the usage of // TODO(opaques): there is a potential for a better error message here, if the usage of
// `$Age` can be linked to the declaration of `Age` inside `age`, and a suggestion to // `@Age` can be linked to the declaration of `Age` inside `age`, and a suggestion to
// raise that declaration to the outer scope. // raise that declaration to the outer scope.
indoc!( indoc!(
r#" r#"
@ -8362,7 +8362,7 @@ I need all branches in an `if` to have the same type!
The opaque type Age referenced here is not defined: The opaque type Age referenced here is not defined:
5 $Age age 5 @Age age
^^^^ ^^^^
Note: It looks like there are no opaque types declared in this scope yet! Note: It looks like there are no opaque types declared in this scope yet!
@ -8410,7 +8410,7 @@ I need all branches in an `if` to have the same type!
Age := Num.U8 Age := Num.U8
n : Age n : Age
n = $Age "" n = @Age ""
n n
"# "#
@ -8423,7 +8423,7 @@ I need all branches in an `if` to have the same type!
This expression is used in an unexpected way: This expression is used in an unexpected way:
4 n = $Age "" 4 n = @Age ""
^^ ^^
This argument to an opaque type has type: This argument to an opaque type has type:
@ -8446,8 +8446,8 @@ I need all branches in an `if` to have the same type!
F n := n F n := n
if True if True
then $F "" then @F ""
else $F {} else @F {}
"# "#
), ),
indoc!( indoc!(
@ -8456,7 +8456,7 @@ I need all branches in an `if` to have the same type!
This expression is used in an unexpected way: This expression is used in an unexpected way:
5 else $F {} 5 else @F {}
^^ ^^
This argument to an opaque type has type: This argument to an opaque type has type:
@ -8561,8 +8561,8 @@ I need all branches in an `if` to have the same type!
\x -> \x ->
when x is when x is
$F A -> "" @F A -> ""
$F {} -> "" @F {} -> ""
"# "#
), ),
indoc!( indoc!(
@ -8571,7 +8571,7 @@ I need all branches in an `if` to have the same type!
The 2nd pattern in this `when` does not match the previous ones: The 2nd pattern in this `when` does not match the previous ones:
6 $F {} -> "" 6 @F {} -> ""
^^^^^ ^^^^^
The 2nd pattern is trying to matchF unwrappings of type: The 2nd pattern is trying to matchF unwrappings of type:
@ -8596,8 +8596,8 @@ I need all branches in an `if` to have the same type!
v : F [ A, B, C ] v : F [ A, B, C ]
when v is when v is
$F A -> "" @F A -> ""
$F B -> "" @F B -> ""
"# "#
), ),
indoc!( indoc!(
@ -8607,8 +8607,8 @@ I need all branches in an `if` to have the same type!
The branches of this `when` expression don't match the condition: The branches of this `when` expression don't match the condition:
5> when v is 5> when v is
6 $F A -> "" 6 @F A -> ""
7 $F B -> "" 7 @F B -> ""
This `v` value is a: This `v` value is a:
@ -8638,8 +8638,8 @@ I need all branches in an `if` to have the same type!
v : F Num.U8 v : F Num.U8
when v is when v is
$F 1 -> "" @F 1 -> ""
$F 2 -> "" @F 2 -> ""
"# "#
), ),
indoc!( indoc!(
@ -8649,12 +8649,12 @@ I need all branches in an `if` to have the same type!
This `when` does not cover all the possibilities: This `when` does not cover all the possibilities:
5> when v is 5> when v is
6> $F 1 -> "" 6> @F 1 -> ""
7> $F 2 -> "" 7> @F 2 -> ""
Other possibilities include: Other possibilities include:
$F _ @F _
I would have to crash if I saw one of those! Add branches for them! I would have to crash if I saw one of those! Add branches for them!
"# "#
@ -9490,7 +9490,7 @@ I need all branches in an `if` to have the same type!
Id := U32 Id := U32
hash = \$Id n -> n hash = \@Id n -> n
"# "#
), ),
indoc!( indoc!(
@ -9499,7 +9499,7 @@ I need all branches in an `if` to have the same type!
Something is off with this specialization of `hash`: Something is off with this specialization of `hash`:
7 hash = \$Id n -> n 7 hash = \@Id n -> n
^^^^ ^^^^
This value is a declared specialization of type: This value is a declared specialization of type:
@ -9528,7 +9528,7 @@ I need all branches in an `if` to have the same type!
Id := U64 Id := U64
eq = \$Id m, $Id n -> m == n eq = \@Id m, @Id n -> m == n
"# "#
), ),
indoc!( indoc!(
@ -9547,7 +9547,7 @@ I need all branches in an `if` to have the same type!
`eq`, specialized here: `eq`, specialized here:
9 eq = \$Id m, $Id n -> m == n 9 eq = \@Id m, @Id n -> m == n
^^ ^^
"# "#
), ),
@ -9610,7 +9610,7 @@ I need all branches in an `if` to have the same type!
You := {} You := {}
AndI := {} AndI := {}
eq = \$You {}, $AndI {} -> False eq = \@You {}, @AndI {} -> False
"# "#
), ),
indoc!( indoc!(
@ -9619,7 +9619,7 @@ I need all branches in an `if` to have the same type!
Something is off with this specialization of `eq`: Something is off with this specialization of `eq`:
9 eq = \$You {}, $AndI {} -> False 9 eq = \@You {}, @AndI {} -> False
^^ ^^
This value is a declared specialization of type: This value is a declared specialization of type:
@ -9653,7 +9653,7 @@ I need all branches in an `if` to have the same type!
Id := U64 Id := U64
hash : Id -> U32 hash : Id -> U32
hash = \$Id n -> n hash = \@Id n -> n
"# "#
), ),
indoc!( indoc!(
@ -9663,7 +9663,7 @@ I need all branches in an `if` to have the same type!
Something is off with the body of this definition: Something is off with the body of this definition:
8 hash : Id -> U32 8 hash : Id -> U32
9 hash = \$Id n -> n 9 hash = \@Id n -> n
^ ^
This `n` value is a: This `n` value is a:
@ -9678,7 +9678,7 @@ I need all branches in an `if` to have the same type!
Something is off with this specialization of `hash`: Something is off with this specialization of `hash`:
9 hash = \$Id n -> n 9 hash = \@Id n -> n
^^^^ ^^^^
This value is a declared specialization of type: This value is a declared specialization of type:
@ -9706,13 +9706,13 @@ I need all branches in an `if` to have the same type!
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
User := {} User := {}
noGoodVeryBadTerrible = noGoodVeryBadTerrible =
{ {
nope: hash ($User {}), nope: hash (@User {}),
notYet: hash (A 1), notYet: hash (A 1),
} }
"# "#
@ -9738,7 +9738,7 @@ I need all branches in an `if` to have the same type!
This expression has a type that does not implement the abilities it's expected to: This expression has a type that does not implement the abilities it's expected to:
14 nope: hash ($User {}), 14 nope: hash (@User {}),
^^^^^^^^ ^^^^^^^^
This User opaque wrapping has the type: This User opaque wrapping has the type:
@ -9804,10 +9804,10 @@ I need all branches in an `if` to have the same type!
hash : a -> U64 | a has Hash hash : a -> U64 | a has Hash
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
hashable : a | a has Hash hashable : a | a has Hash
hashable = $Id 15 hashable = @Id 15
"# "#
), ),
indoc!( indoc!(
@ -9817,7 +9817,7 @@ I need all branches in an `if` to have the same type!
Something is off with the body of the `hashable` definition: Something is off with the body of the `hashable` definition:
9 hashable : a | a has Hash 9 hashable : a | a has Hash
10 hashable = $Id 15 10 hashable = @Id 15
^^^^^^ ^^^^^^
This Id opaque wrapping has the type: This Id opaque wrapping has the type:
@ -9853,12 +9853,12 @@ I need all branches in an `if` to have the same type!
mulHashes = \x, y -> hash x * hash y mulHashes = \x, y -> hash x * hash y
Id := U64 Id := U64
hash = \$Id n -> n hash = \@Id n -> n
Three := {} Three := {}
hash = \$Three _ -> 3 hash = \@Three _ -> 3
result = mulHashes ($Id 100) ($Three {}) result = mulHashes (@Id 100) (@Three {})
"# "#
), ),
indoc!( indoc!(