Skip to content

Instantly share code, notes, and snippets.

@mpilquist
Created September 13, 2016 16:58
Show Gist options
  • Save mpilquist/0db0d050941c922299fabc2f5524961f to your computer and use it in GitHub Desktop.
Save mpilquist/0db0d050941c922299fabc2f5524961f to your computer and use it in GitHub Desktop.
package scratch
sealed trait Sub1[-F[_],+G[_]] {
def apply[A](f: F[A]): G[A]
}
object Sub1 {
implicit def sub1[F[_]]: Sub1[F,F] = new Sub1[F,F] { def apply[A](f: F[A]) = f }
}
object TypeMember {
sealed trait Lub1[-F[_],-G[_]] {
type Lub[_]
implicit def subF: Sub1[F,Lub]
implicit def subG: Sub1[G,Lub]
}
trait Lub1Instances0 {
implicit def lub1[F[_],G[_],Lub0[_]](implicit S1: Sub1[F,Lub0], S2: Sub1[G,Lub0]): Lub1[F,G] { type Lub[x] = Lub0[x] }= new Lub1[F,G] {
type Lub[x] = Lub0[x]
def subF = S1
def subG = S2
}
}
object Lub1 extends Lub1Instances0 {
implicit def id[F[_]]: Lub1[F,F] { type Lub[x] = F[x] } = new Lub1[F,F] {
type Lub[x] = F[x]
def subF = implicitly
def subG = implicitly
}
}
def foo[F[_], G[_], A, B](x: F[A], y: G[B])(implicit L: Lub1[F,G]): L.Lub[(A, B)] = ???
def bar = foo(List(1), List(2))
def baz = foo(List(1), List(2))(implicitly)
}
object TypeParameter {
sealed trait Lub1[-F[_],-G[_],+Lub[_]] {
implicit def subF: Sub1[F,Lub]
implicit def subG: Sub1[G,Lub]
}
trait Lub1Instances0 {
implicit def lub1[F[_],G[_],Lub0[_]](implicit S1: Sub1[F,Lub0], S2: Sub1[G,Lub0]): Lub1[F,G,Lub0] = new Lub1[F,G,Lub0] {
def subF = S1
def subG = S2
}
}
object Lub1 extends Lub1Instances0 {
implicit def id[F[_]]: Lub1[F,F,F] = new Lub1[F,F,F] {
def subF = implicitly
def subG = implicitly
}
}
def foo[F[_], G[_], Lub[_], A, B](x: F[A], y: G[B])(implicit L: Lub1[F,G,Lub]): Lub[(A, B)] = ???
def bar = foo(List(1), List(2))
def baz = foo(List(1), List(2))(implicitly)
}
// [error] /Users/mpilquist/Development/scratch/lubs/src/main/scala/scratch/lubs.scala:61: ambiguous implicit values:
// [error] both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String]
// [error] and method $conforms in object Predef of type [A]=> <:<[A,A]
// [error] match expected type T
// [error] def baz = foo(List(1), List(2))(implicitly)
// [error] ^
// [error] one error found
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment