Help: Is there a support for AsyncShift for extension on opaque types?
I am currently working on https://github.com/getkyo/kyo/issues/1209, and I struggle to have AsyncShift working on Result[?, ?] or Maybe[?].
For this code:
opaque type Maybe[+A] >: (Absent | Present[A]) = Absent | Present[A]
object Maybe:
extension [A](self: Maybe[A])
inline def map[B](inline f: A => B): Maybe[B] =
if isEmpty then Absent else f(get)
val x: Maybe[Int] = Maybe(1)
def f(i: Int): Int < Any = i + 1
"map" in {
val d = defer:
x.map(i => f(i).now)
assert(d.eval == Maybe(1))
}
I get this error (simplified):
Can't shift caller kyo.Maybe$package.Maybe.map[Int](x)[Int] (
tree TypeApply(Apply(
TypeApply(Select(Ident(Maybe),map), List(TypeTree[Int])),
List(Ident(x))
),
List(TypeTree[Int])))
while there is this definition for the AsyncShift
object MaybeAsyncShift extends AsyncShift[Maybe.type]:
def map[F[_], A, B](obj: Maybe.type, monad: CpsMonad[F])(c: Maybe[A])(f: A => F[B]): F[Maybe[B]] =
c.fold(monad.pure(Maybe.empty))(a => monad.map(f(a))(b => Maybe(b)))
transparent inline given shiftedMaybe: MaybeAsyncShift.type = MaybeAsyncShift
Changing the signature to:
def map[F[_], A](obj: Maybe.type, monad: CpsMonad[F])(c: Maybe[A])[B](f: A => F[B]): F[Maybe[B]] =
c.fold(monad.pure(Maybe.empty))(a => monad.map(f(a))(b => Maybe(b)))
Doesn't change anything. Do you think there is a way to implement AsyncShift on Maybe currently?
Hmm, can you define in scope implicit value cps.macros.flags.PrintCode and look on expression, which dotty-cps-async try to reduce.
implicit val printCode = cps.macroFlags.PrintCode
<code-which-not-compiled>
In such a way we will see the actual expression which should be reduced. Also, a small self-contained example would be helpful.
I have reproduced something similar: https://github.com/dotty-cps-async/dotty-cps-async/commit/a1c8baf796d4a002aa17eef53c3d9a8e65f04f48
Don;'t work now, will think, how to include this functionality in the next minor release.
Thank you so much @rssh! Definitely will work with cps.macros.flags.PrintCode.
Hi, I have implemented preliminary support for shifting extension methods. Example is in https://github.com/dotty-cps-async/dotty-cps-async/blob/master/shared/src/test/scala/cpstest/TestOpaqueAsyncShift.scala. (omitt commented-output variants for now).
This is preliminary and has not been published (for release, we need to write the documentation and implement the same functionality for the compiler plugin). However, you may want to experiment with the locally built master branch.
Thanks a lot, it works like the tests: https://github.com/ahoy-jon/kyo/commit/4db4d029f7c805a98c84bc778c64a9d4e288d92a
published 1.1.0
@rssh it's working, thank you (cf. https://github.com/getkyo/kyo/pull/1263)