Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Forked from julien-truffaut/implicits.scala
Created October 17, 2016 15:46
Show Gist options
  • Save xuwei-k/57dad8eed6863021dbaa995b26e509f8 to your computer and use it in GitHub Desktop.
Save xuwei-k/57dad8eed6863021dbaa995b26e509f8 to your computer and use it in GitHub Desktop.
import scalaz.std.string._
import scalaz.std.list._
import scalaz.{Semigroup, Monoid, Functor, Applicative}
trait Foo[A] {
override def toString: String = "Foo"
}
trait Foo2[A] extends Foo[A] {
override def toString: String = "Foo2"
}
trait Foo3[A] extends Foo2[A] {
override def toString: String = "Foo3"
}
case class Yo[A](a: A)
object Yo {
implicit def foo[A]: Foo[Yo[A]] = new Foo[Yo[A]] {}
implicit def foo2[A: Semigroup]: Foo2[Yo[A]] = new Foo2[Yo[A]] {}
implicit def foo3[A: Monoid]: Foo3[Yo[A]] = new Foo3[Yo[A]] {}
}
case class YoT[F[_]](fa: F[Int])
object YoT {
implicit def foo[F[_]]: Foo[YoT[F]] = new Foo[YoT[F]]{}
implicit def foo2[F[_]](implicit ev: Functor[F]): Foo2[YoT[F]] = new Foo2[YoT[F]]{}
implicit def foo3[F[_]](implicit ev: Applicative[F]): Foo3[YoT[F]] = new Foo3[YoT[F]]{}
}
object Test extends App {
val yoFoo = implicitly[Foo[Yo[String]]]
val yoFoo2 = implicitly[Foo2[Yo[String]]]
val yoFoo3 = implicitly[Foo3[Yo[String]]]
println(s"foo: $yoFoo, foo2: $yoFoo2, foo3: $yoFoo3") // prints Foo3 for all
val yotFoo = implicitly[Foo[YoT[List]]]
val yotFoo2 = implicitly[Foo2[YoT[List]]]
// Error:(49, 27) ambiguous implicit values:
// both method foo in object YoT of type [F[_]]=> typeclass.other.Foo[typeclass.other.YoT[F]]
// and method foo2 in object YoT of type [F[_]](implicit ev: scalaz.Functor[F])typeclass.other.Foo2[typeclass.other.YoT[F]]
// match expected type typeclass.other.Foo[typeclass.other.YoT[List]]
// val yotFoo = implicitly[Foo[YoT[List]]]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment