Given:
case class C[A](a: A) {
def map[B](f: A => B): C[B] = C(f(a))
def flatMap[B](f: A => C[B]): C[B] = C(f(a).a)
}
def op(i: Int) = i * 2
val x0: Int = 1
One can write:
def res1: C[Int] =
C(op(x0)) flatMap { x1 =>
C(op(x1)) map { x2 =>
println(x2); op(x2) }
}
Using a for-comprehension, this could be rewritten as:
def res2: C[Int] = for {
x1 <- C(op(x0))
x2 <- C(op(x1))
} yield { println(x2); op(x2) }
So far so good.
Now, with implicit function types in Dotty, we could make the type of the parameters to map/flatMap implicit function types instead of normal function types:
case class C[A](a: A) {
def map[B](f: implicit A => B): C[B] = C(f(a))
def flatMap[B](f: implicit A => C[B]): C[B] = C(f(a).a)
}
And if we also implicitify our helpers:
def op(implicit i: Int) = i * 2
implicit val x0: Int = 1
We could write:
def res1: C[Int] =
C(op) flatMap {
C(op) map {
println(implicitly[Int]); op }
}
This works well.
However, intuitively it would seem that we also here should be able to rewrite ´res1´ in the form of a for-comprehension, something like:
def res2: C[Int] = for {
? <- C(op)
? <- C(op)
} yield { println(implicitly[Int]); op }
Would it be possible to enhance the syntax and desugaring rules of for-comprehensions to allow for this?