Skip to content

Commit

Permalink
#83: extension methods for await/unlift/reflect
Browse files Browse the repository at this point in the history
  • Loading branch information
rssh committed Sep 7, 2024
1 parent 4ac71f3 commit a565b9b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 15 deletions.
24 changes: 14 additions & 10 deletions shared/src/main/scala/cps/Async.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ import scala.compiletime._
import cps.plugin.annotation.CpsNotChange


/**
* Pseudofunction, which can be used inside async block, to 'await' (i.e. receive value of `t:T` from `ft:F[T]`).
**/
@compileTimeOnly("await should be inside async block")
def await[F[_],T,G[_]](f: F[T])(using ctx: CpsMonadContext[G], conversion: CpsMonadConversion[F,G]): T = ???

extension [F[_], T, G[_]](f: F[T])(using ctx: CpsMonadContext[G], conversion: CpsMonadConversion[F,G])
/**
* Pseudofunction, which can be used inside async block, to 'await' (i.e. receive value of `t:T` from `ft:F[T]`).
**/
@compileTimeOnly("await should be inside async block")
def await: T = ???


/**
* Pseudofunction, which can be used inside async block or in function with CpsDirect[F] context parameter, to 'asynchronize computation' (i.e. receive value of `F[T]` from `t:FT`).
Expand Down Expand Up @@ -54,11 +57,12 @@ transparent inline def async[F[_]](using am: CpsMonad[F]) =
transparent inline def reify[F[_]](using am: CpsMonad[F]) =
macros.Async.InferAsyncArg(using am)

/**
* Synonym for `await`
**/
transparent inline def reflect[F[_],T,G[_]](f: F[T])(using inline ctx: CpsMonadContext[G], inline conv: CpsMonadConversion[F,G]): T =
await[F,T,G](f)

extension [F[_], T, G[_]](f: F[T])(using ctx: CpsMonadContext[G], conversion: CpsMonadConversion[F, G])
/**
* Synonym for `await`
* */
transparent inline def reflect: T = await(f)


@experimental
Expand Down
10 changes: 5 additions & 5 deletions shared/src/main/scala/cps/syntax/monadless/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ transparent inline def lift[F[_]](using am: CpsMonad[F]) =
macros.Async.InferAsyncArg(using am)


/**
* Synomym for `await`
**/
transparent inline def unlift[F[_],T,G[_]](f: F[T])(using ctx: CpsMonadContext[G], conversion: CpsMonadConversion[F,G]): T =
cps.await[F,T,G](f)(using ctx, conversion)

extension [F[_], T, G[_]](f: F[T])(using ctx: CpsMonadContext[G], conversion: CpsMonadConversion[F, G])
/**
* Synonym for `await`
* */
transparent inline def unlift: T = await(f)
37 changes: 37 additions & 0 deletions shared/src/test/scala/cpstest/TestExtensionSyntax.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cpstest



import cps.*
import org.junit.Test

import scala.util.Success

class TestExtensionSyntax {

@Test
def testCBExtensionSyntax() = {

val c = async[ComputationBound] {
val a = T1.cbi(1)
val b = T1.cbi(2)
a.await + b.await
}
assert(c.run() == Success(3))

}

@Test
def testCBReflectExtensionSyntax() = {

val c = reify[ComputationBound] {
val a = T1.cbi(1)
val b = T1.cbi(2)
a.reflect + b.reflect
}
assert(c.run() == Success(3))

}


}
14 changes: 14 additions & 0 deletions shared/src/test/scala/cpstest/TestMonadlessSyntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ class TestMonadlessSyntax {
case Failure(ex) => throw ex
}

@Test
def testUnliftExtension() = {
val c = lift[ComputationBound] {
val x = T1.cbi(1).unlift + T1.cbi(2).unlift
x
}
val r = c.run()
assert(r.isSuccess)
r match
case Success(v) => assert(v == 3)
case Failure(ex) => throw ex
}


@Test
def testInferenceForFutureMonad() = {

Expand Down

0 comments on commit a565b9b

Please sign in to comment.