Dotty: implicit function types and for-comprehensions

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?

1 Like