Skip to content

Commit d27adc1

Browse files
committed
Make minor fix to record pattern + misc
1 parent 066f301 commit d27adc1

File tree

5 files changed

+118
-2
lines changed

5 files changed

+118
-2
lines changed

hkmc2/shared/src/main/scala/hkmc2/semantics/ucs/Desugarer.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,9 +612,10 @@ class Desugarer(val elaborator: Elaborator)
612612
fallback
613613
case InfixApp(id: Ident, Keyword.`:`, pat) => fallback => ctx =>
614614
val sym = VarSymbol(id)
615-
val ctxWithAlias = ctx + (id.name -> sym)
615+
val ctx2 = ctx
616+
// + (id.name -> sym) // * This binds the field's name in the context; probably surprising
616617
Split.Let(sym, ref.sel(id, N),
617-
expandMatch(sym, pat, sequel)(fallback)(ctxWithAlias))
618+
expandMatch(sym, pat, sequel)(fallback)(ctx2))
618619
case Block(st :: Nil) => fallback => ctx =>
619620
expandMatch(scrutSymbol, st, sequel)(fallback)(ctx)
620621
// case Block(sts) => fallback => ctx => // TODO

hkmc2/shared/src/test/mlscript-compile/Predef.mls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ fun (???) notImplementedError = throw Error("Not implemented")
5656

5757
fun tuple(...xs) = xs
5858

59+
5960
val foldl = fold
6061

6162
// fun foldr(f)(...rest, init) = // TODO allow this syntax
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
import "./Predef.mls"
3+
open Predef
4+
5+
import "./Iter.mls"
6+
7+
8+
module Record with...
9+
10+
fun steal(from, ...fields) =
11+
let rcd = new Object
12+
fields Iter.each of f => set rcd.(f) = from.(f)
13+
rcd
14+
15+
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
:js
2+
3+
import "../../mlscript-compile/Record.mls"
4+
5+
6+
let src =
7+
k0: 0
8+
k1: 1
9+
k2: 2
10+
k3: 3
11+
k4: 4
12+
//│ src = {k0: 0, k1: 1, k2: 2, k3: 3, k4: 4}
13+
14+
src Record.steal("k1", "k2", "k3")
15+
//│ = {k1: 1, k2: 2, k3: 3}
16+
17+
let dst =
18+
k0: "0"
19+
...src Record.steal("k1", "k2", "k3")
20+
k4: "4"
21+
//│ dst = {k0: "0", k1: 1, k2: 2, k3: 3, k4: "4"}
22+
23+
24+
// * Alternative 'cute' API
25+
26+
import "../../mlscript-compile/Iter.mls"
27+
28+
fun steal(...fields_from) =
29+
let from = fields_from.at(-1).from
30+
let fields = fields_from.slice(0, -1)
31+
let rcd = new Object
32+
fields Iter.each of f => set rcd.(f) = from.(f)
33+
rcd
34+
35+
let src =
36+
k0: 0
37+
k1: 1
38+
k2: 2
39+
k3: 3
40+
k4: 4
41+
//│ src = {k0: 0, k1: 1, k2: 2, k3: 3, k4: 4}
42+
43+
steal("k1", "k2", "k3", from: src)
44+
//│ = {k1: 1, k2: 2, k3: 3}
45+
46+
let dst =
47+
k0: "0"
48+
...steal("k1", "k2", "k3", from: src)
49+
k4: "4"
50+
//│ dst = {k0: "0", k1: 1, k2: 2, k3: 3, k4: "4"}
51+
52+

hkmc2/shared/src/test/mlscript/ucs/patterns/RecordPattern.mls

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,50 @@ fun take_1(p) =
2020
//│ ╙── ^^^^^
2121

2222

23+
let f = case
24+
{ a: 1 as a } then a
25+
//│ f = [function]
26+
27+
f(a: 1)
28+
//│ = 1
29+
30+
31+
// * It would probably be surprising to bind `a` in the RHS here
32+
:e
33+
let f = case
34+
{ a: 1 } then a
35+
//│ ╔══[ERROR] Name not found: a
36+
//│ ║ l.34: { a: 1 } then a
37+
//│ ╙── ^
38+
//│ f = [function]
39+
40+
// * OTOH, note that `a` is bound here
41+
let rcd =
42+
a: 1
43+
b: a + 1
44+
//│ rcd = {a: 1, b: 2}
45+
46+
// * As that will make sense when we have dependent types,
47+
// * as in: `{ n: Int, v: Vec[Int, n] }`
48+
49+
50+
:todo
51+
let f = case
52+
{ a: 1 & a } then a
53+
//│ ╔══[ERROR] Name not found: &
54+
//│ ║ l.52: { a: 1 & a } then a
55+
//│ ╙── ^
56+
//│ ╔══[ERROR] Cannot use this identifier as an extractor
57+
//│ ║ l.52: { a: 1 & a } then a
58+
//│ ╙── ^
59+
//│ f = [function]
60+
61+
62+
let f = case
63+
{ :a } then a
64+
//│ f = [function]
65+
66+
f(a: 1)
67+
//│ = 1
68+
69+

0 commit comments

Comments
 (0)