Skip to content

Commit 687f39d

Browse files
committed
Add more interesting tests and some partial fixes
1 parent 15c6ea1 commit 687f39d

File tree

6 files changed

+154
-1
lines changed

6 files changed

+154
-1
lines changed

shared/src/main/scala/mlscript/NewParser.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ abstract class NewParser(origin: Origin, tokens: Ls[Stroken -> Loc], raiseFun: D
335335
case _ => die
336336
}
337337
val (tn, success) = yeetSpaces match {
338-
case (IDENT(idStr, false), l1) :: _ =>
338+
case (IDENT(idStr, _), l1) :: _ =>
339339
consume
340340
(TypeName(idStr).withLoc(S(l1)), true)
341341
case c =>

shared/src/main/scala/mlscript/Typer.scala

+2
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ class Typer(var dbg: Boolean, var verbose: Bool, var explainErrors: Bool, var ne
491491
clsNameToNomTag(ctx.tyDefs2(name).decl.asInstanceOf[NuTypeDef])(tyTp(tyLoc, "class tag"), ctx)
492492
case NuTypeDef(Trt, _, _, _, _, _, _, _, _, _) =>
493493
trtNameToNomTag(ctx.tyDefs2(name).decl.asInstanceOf[NuTypeDef])(tyTp(tyLoc, "class tag"), ctx)
494+
case NuTypeDef(Als, _, _, _, _, _, _, _, _, _) =>
495+
TypeRef(tn, List.fill(tpnum)(freshVar(noProv, N, N)))(tpr)
494496
case _ => die // TODO
495497
}
496498
case _ => err(msg"Type $name takes parameters", tyLoc)(raise)

shared/src/main/scala/mlscript/helpers.scala

+2
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,8 @@ trait TermImpl extends StatementImpl { self: Term =>
571571
case App(App(Var("&"), Tup(N -> Fld(false, false, lhs) :: Nil)), Tup(N -> Fld(false, false, rhs) :: Nil)) => Inter(lhs.toType_!, rhs.toType_!)
572572
case App(App(Var("->"), lhs), Tup(N -> Fld(false, false, rhs) :: Nil)) => Function(lhs.toType_!, rhs.toType_!)
573573
case App(App(Var("->"), lhs), tup: Tup) => Function(lhs.toType_!, tup.toType_!)
574+
case ty @ App(App(v @ Var("\\"), Tup(N -> Fld(false, false, lhs) :: Nil)), Tup(N -> Fld(false, false, rhs) :: Nil)) =>
575+
Inter(lhs.toType_!, Neg(rhs.toType_!).withLoc(Loc(v :: rhs :: Nil))).withLoc(ty.toCoveringLoc)
574576
case App(App(Var("|"), lhs), rhs) => Union(lhs.toType_!, rhs.toType_!)
575577
case App(App(Var("&"), lhs), rhs) => Inter(lhs.toType_!, rhs.toType_!)
576578
case App(Var("~"), rhs) => Neg(rhs.toType_!)

shared/src/test/diff/nu/Jonathan.mls

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
:NewDefs
2+
:NoJS
3+
4+
5+
// * A monadic effect type, covariant in base type and effect type
6+
class Effectful[out A, out E](value: A) {
7+
fun flatMap[B](f: A => Effectful[B, E]): Effectful[B, E] =
8+
f(value)
9+
}
10+
fun pure[A](a: A): Effectful['a, 'e] = Effectful(a)
11+
//│ class Effectful[A, E](value: A) {
12+
//│ fun flatMap: forall 'B. (f: A -> Effectful['B, E],) -> Effectful['B, E]
13+
//│ }
14+
//│ fun pure: forall 'a. (a: 'a,) -> Effectful['a, nothing]
15+
16+
// * Some effect tags
17+
module IO
18+
module Block
19+
//│ module IO
20+
//│ module Block
21+
22+
// * Some example functions
23+
fun println(x: anything): Effectful[(), IO]
24+
fun readLine: Effectful[Str, IO | Block]
25+
//│ fun println: (x: anything,) -> Effectful[(), IO]
26+
//│ fun readLine: Effectful[Str, Block | IO]
27+
28+
29+
// * Define NonBlocking as an effectful computation that does not block (using type-level difference `\`)
30+
type NonBlocking[out A, out E] = Effectful[A, E \ Block]
31+
//│ type NonBlocking[A, E] = Effectful[A, E & ~Block]
32+
33+
// * Example use of NonBlocking in an annotation; the type arguments are inferred
34+
fun f(x) = x : NonBlocking
35+
//│ fun f: forall 'a 'b. NonBlocking['a, 'b] -> NonBlocking['a, 'b]
36+
37+
38+
// * the `listener` callback should be non-blocking
39+
fun onMousePressed(listener) =
40+
fun l(e) = listener(e) : NonBlocking
41+
l(0).flatMap of a => l(1).flatMap of b => pure of ()
42+
//│ fun onMousePressed: forall 'a. ((0 | 1) -> NonBlocking[anything, 'a]) -> Effectful[(), 'a & ~Block]
43+
44+
45+
// * OK: `println` does not block
46+
onMousePressed(event => println("Clicked!"))
47+
//│ Effectful[(), IO & ~Block]
48+
49+
// * NOT OK: `readLine` blocks
50+
:e
51+
onMousePressed(event => readLine.flatMap(println))
52+
//│ ╔══[ERROR] Type mismatch in application:
53+
//│ ║ l.51: onMousePressed(event => readLine.flatMap(println))
54+
//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
55+
//│ ╟── type `Block` does not match type `~Block`
56+
//│ ║ l.24: fun readLine: Effectful[Str, IO | Block]
57+
//│ ╙── ^^^^^
58+
//│ Effectful[(), IO & ~Block] | error
59+
60+
61+
class Event
62+
class MouseEvent: Event
63+
module Register
64+
//│ class Event
65+
//│ class MouseEvent: Event
66+
//│ module Register
67+
68+
fun onMousePressed(listener) =
69+
fun l(e: MouseEvent) = listener(e) : Effectful[(), 'e \ Block \ Register]
70+
()
71+
//│ fun onMousePressed: (MouseEvent -> Effectful[(), ~Block & ~Register]) -> ()
72+
73+
// def onMouseClick ( f : Event -> Unit \ { ef - Register }): Unit \ { Register }
74+
fun onMouseClick(f: Event -> Effectful[(), 'e \ Register]): Effectful[(), Register]
75+
//│ fun onMouseClick: (f: Event -> Effectful[(), ~Register],) -> Effectful[(), Register]
76+
77+
onMouseClick of ev => pure of ()
78+
//│ Effectful[(), Register]
79+
80+
:e
81+
onMouseClick of ev =>
82+
onMouseClick(ev => pure of ()).flatMap of _ =>
83+
pure of ()
84+
//│ ╔══[ERROR] Type mismatch in application:
85+
//│ ║ l.81: onMouseClick of ev =>
86+
//│ ║ ^^^^^^^^^^^^^^^^^^^^^
87+
//│ ║ l.82: onMouseClick(ev => pure of ()).flatMap of _ =>
88+
//│ ║ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
89+
//│ ║ l.83: pure of ()
90+
//│ ║ ^^^^^^^^^^^^^^
91+
//│ ╟── type `Register` does not match type `~Register`
92+
//│ ║ l.74: fun onMouseClick(f: Event -> Effectful[(), 'e \ Register]): Effectful[(), Register]
93+
//│ ╙── ^^^^^^^^
94+
//│ Effectful[(), Register] | error
95+
96+

shared/src/test/diff/nu/TypeOps.mls

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
:NewDefs
2+
3+
4+
type *[A, B] = [A, B]
5+
//│ type *[A, B] = (A, B,)
6+
7+
8+
:e // FIXME parsing of type operators
9+
fun x : Int * Int
10+
fun x = [0, 1]
11+
//│ ╔══[ERROR] Type mismatch in definition:
12+
//│ ║ l.10: fun x = [0, 1]
13+
//│ ║ ^^^^^^^^^^
14+
//│ ╟── integer literal of type `0` is not a 1-element tuple
15+
//│ ║ l.10: fun x = [0, 1]
16+
//│ ║ ^
17+
//│ ╟── Note: constraint arises from tuple type:
18+
//│ ║ l.9: fun x : Int * Int
19+
//│ ╙── ^^^
20+
//│ fun x: (0, 1,)
21+
//│ fun x: *[(Int,), (Int,)]
22+
23+

shared/src/test/diff/nu/ValSigs.mls

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
:NewDefs
2+
3+
4+
val x: Int
5+
val x = 1
6+
//│ let x: Int
7+
//│ let x: 1
8+
//│ x
9+
//│ = <missing implementation>
10+
//│ x
11+
//│ = 1
12+
13+
// * FIXME type
14+
x
15+
//│ 1
16+
//│ res
17+
//│ = 1
18+
19+
20+
// :e // FIXME should be an error
21+
val x: Int
22+
val x = "oops"
23+
//│ let x: Int
24+
//│ let x: "oops"
25+
//│ x
26+
//│ = <missing implementation>
27+
//│ x
28+
//│ = 'oops'
29+
30+

0 commit comments

Comments
 (0)