Skip to content

Instantly share code, notes, and snippets.

@loicknuchel
Last active October 16, 2017 12:51
Show Gist options
  • Save loicknuchel/a08a7efedc0e9877f1b53f4ba0112b20 to your computer and use it in GitHub Desktop.
Save loicknuchel/a08a7efedc0e9877f1b53f4ba0112b20 to your computer and use it in GitHub Desktop.
How implicit class resolution works ?
import org.scalatest.{FunSpec, Matchers}
object Implicits {
implicit class SeqEitherExtension[E, A](val elt: Seq[Either[E, A]]) extends AnyVal {
def partition: (Seq[E], Seq[A]) = {
val (left, right) = elt.partition(_.isLeft)
(left.collect { case Left(e) => e }, right.collect { case Right(a) => a })
}
}
}
class ImplicitsSpec extends FunSpec with Matchers {
describe("SeqEitherExtension") {
import Implicits._
it("partition") {
// works
SeqEitherExtension(Seq(Left("err"), Right(1))).partition shouldBe(Seq("err"), Seq(1))
// do not work, implicit not found :(
// Any idea on why implicit class is not found ???
Seq(Left("err"), Right(1)).partition shouldBe(Seq("err"), Seq(1))
/**
* Error:(24, 34) missing argument list for method partition in trait TraversableLike
* Unapplied methods are only converted to functions when a function type is expected.
* You can make this conversion explicit by writing `partition _` or `partition(_)` instead of `partition`.
* Seq(Left("err"), Right(1)).partition shouldBe(Seq("err"), Seq(1))
*/
}
}
}
@jeantil
Copy link

jeantil commented Oct 16, 2017

from your comment it sounds like the parameterless case is processed under

  1. In a selection e.m with e of type T, if the selector mm does not denote an accessible member of T. In this case, a view v is searched which is applicable to e and whose result contains a member named m. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of TT. If such a view is found, the selection e.m is converted to v(e).m.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment