Skip to content

Commit cf9b3ec

Browse files
committed
Polish tests
New test case demonstrating high efficiency implicit scope injection.
1 parent 139eec4 commit cf9b3ec

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

tests/pos/assumeIn.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
object Test {
2+
import scala.compiletime.constValue
3+
4+
class Context {
5+
inline def assumeIn[T](op: => Context |=> T) = {
6+
instance def ctx: Context = this
7+
op
8+
}
9+
}
10+
11+
def ctx: Context = new Context
12+
def g with Context = ()
13+
ctx.assumeIn(g)
14+
15+
/* The last three statements shoudl generate the following code:
16+
17+
def ctx: Test.Context = new Test.Context()
18+
def g(implicit x$1: Test.Context): Unit = ()
19+
{
20+
val Context_this: Test.Context = Test.ctx
21+
{
22+
implicit def ctx: Test.Context = Context_this
23+
Test.g(ctx)
24+
}
25+
}
26+
*/
27+
}

tests/run/tagless.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// A rewrite of Olivier Blanvillain's [adaptation](https://gist.github.com/OlivierBlanvillain/48bb5c66dbb0557da50465809564ee80)
2+
// of Oleg Kislyov's [lecture notes](http://okmij.org/ftp/tagless-final/course/lecture.pdf)
3+
// on tagless final interpreters.
4+
// Main win: Replace Either by an "algebraic effect" using an implicit function type.
15
object Test extends App {
26

37
// Explicit ADT
@@ -12,23 +16,26 @@ object Test extends App {
1216
Add(Lit(8), Neg(Add(Lit(1), Lit(2))))
1317
}
1418

15-
// Base algebra
19+
// Base trait for type classes
1620
trait Exp[T] {
1721
def lit(i: Int): T
1822
def neg(t: T): T
1923
def add(l: T, r: T): T
2024
}
2125

26+
// An example tree
2227
def tf0[T] with (e: Exp[T]): T =
2328
e.add(e.lit(8), e.neg(e.add(e.lit(1), e.lit(2))))
2429

30+
// Typeclass-style Exp syntax
2531
object ExpSyntax {
2632
def lit[T](i: Int) with (e: Exp[T]): T = e.lit(i)
2733
def neg[T](t: T) with (e: Exp[T]): T = e.neg(t)
2834
def add[T](l: T, r: T) with (e: Exp[T]): T = e.add(l, r)
2935
}
3036
import ExpSyntax._ // It's safe to always have these in scope
3137

38+
// Another tree
3239
def tf1[T] with Exp[T]: T =
3340
add(lit(8), neg(add(lit(1), lit(2))))
3441

@@ -73,7 +80,7 @@ object Test extends App {
7380
println(tfm2[Int])
7481
println(tfm2[String])
7582

76-
// Added operation: Deserialization
83+
// Added operation: serialization
7784
enum Tree {
7885
case Leaf(s: String)
7986
case Node(s: String, ts: Tree*)
@@ -93,6 +100,8 @@ object Test extends App {
93100
println(s"tf1Tree = $tf1Tree")
94101
println(s"tfm1Tree = $tfm1Tree")
95102

103+
// CanThrow infrastructure
104+
// At some point this will be supported in language and stdlib
96105
class CanThrow private ()
97106

98107
object CanThrow {
@@ -122,6 +131,7 @@ object Test extends App {
122131
msg => assert(false, s"thrown: $msg")
123132
}
124133

134+
// Added operation: deserialization
125135
def readInt(str: String): Maybe[Int] =
126136
_try(str.toInt)(_ => _throw(s"""Not a number: "$str""""))
127137

@@ -183,6 +193,7 @@ object Test extends App {
183193
assertEquals(fromTree3[String](tf1[Tree]), tf1[String])
184194
assertEquals(fromTree3[String](tfm1[Tree]), tfm1[String])
185195

196+
// Added operation: negation pushdown
186197
enum NCtx { case Pos, Neg }
187198

188199
instance [T] with (e: Exp[T]) of Exp[NCtx => T] {
@@ -232,6 +243,7 @@ object Test extends App {
232243
case Add(l, r) => e.add(finalize[T](l), finalize[T](r))
233244
}
234245

246+
// Abstracting over multiple typeclasses
235247
type Ring[T] = Exp[T] |=> Mult[T] |=> T
236248

237249
def tfm1a[T]: Ring[T] = add(lit(7), neg(mul(lit(1), lit(2))))

0 commit comments

Comments
 (0)