Skip to content

Instantly share code, notes, and snippets.

@mandubian
Created December 15, 2012 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mandubian/4295367 to your computer and use it in GitHub Desktop.
Save mandubian/4295367 to your computer and use it in GitHub Desktop.
Scala potential issue when importing similar implicits from different packages
case class ~[A, B](a: A, b: B)
package alpha {
trait AlphaReader[A] {
def read(s: String): A
}
object AlphaReader{
def apply[A](f: String => A): AlphaReader[A] = new AlphaReader[A] {
def read(s: String) = f(s)
}
}
trait AlphaCombinator[M[_]]{
def apply[A, B](ma: M[A], mb: M[B]): M[A~B]
}
class AlphaOps[M[_], A](ma: M[A])(implicit c: AlphaCombinator[M]) {
def and[B](mb: M[B]): M[A~B] = c(ma, mb)
}
object Implicits {
implicit def toAlphaOps[M[_], A](ma: M[A])(implicit c: AlphaCombinator[M]) = new AlphaOps(ma)(c)
implicit def toCombinator = new AlphaCombinator[AlphaReader] {
def apply[A, B](ma: AlphaReader[A], mb: AlphaReader[B]): AlphaReader[A~B] =
new AlphaReader[A~B] { def read(s: String) = new ~(ma.read(s), mb.read(s)) }
}
}
}
package beta {
trait BetaReader[A] {
def read(s: String): A
}
object BetaReader{
def apply[A](f: String => A): BetaReader[A] = new BetaReader[A] {
def read(s: String) = f(s)
}
}
trait BetaCombinator[M[_]]{
def apply[A, B](ma: M[A], mb: M[B]): M[A~B]
}
class BetaOps[M[_], A](ma: M[A])(implicit c: BetaCombinator[M]) {
def and[B](mb: M[B]): M[A~B] = c(ma, mb)
}
object Implicits {
implicit def toBetaOps[M[_], A](ma: M[A])(implicit c: BetaCombinator[M]) = new BetaOps(ma)(c)
implicit def toCombinator = new BetaCombinator[BetaReader] {
def apply[A, B](ma: BetaReader[A], mb: BetaReader[B]): BetaReader[A~B] =
new BetaReader[A~B] { def read(s: String) = new ~(ma.read(s), mb.read(s)) }
}
}
}
// CODE WITH COMPILING ERROR
object main {
import alpha.Implicits._
import beta.Implicits._
val a1 = alpha.AlphaReader[Int](s => s.toInt)
val b1 = alpha.AlphaReader[Long](s => s.toLong)
val c1 = a1 and b1
val a2 = beta.BetaReader[Int](s => s.toInt)
val b2 = beta.BetaReader[Long](s => s.toLong)
val c2 = a2 and b2
}
//COMPILING GIVES THIS ERROR (and function is not found)
implicit_test.scala:70: error: value and is not a member of alpha.AlphaReader[Int]
val c1 = a1 and b1
^
one error found
// COMPILING WITHOUT ERROR
object main {
import alpha.Implicits._
val a1 = alpha.AlphaReader[Int](s => s.toInt)
val b1 = alpha.AlphaReader[Long](s => s.toLong)
val c1 = a1 and b1
import beta.Implicits._
val a2 = beta.BetaReader[Int](s => s.toInt)
val b2 = beta.BetaReader[Long](s => s.toLong)
val c2 = a2 and b2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment