Skip to content

Instantly share code, notes, and snippets.

@retronym
Created March 23, 2010 18:05
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save retronym/341475 to your computer and use it in GitHub Desktop.
Save retronym/341475 to your computer and use it in GitHub Desktop.
Calculate the Least Upper Bound of two types.
object test {
case class L[A, B]() {
def ToLub[AA >: A <: L, BB >: B <: L, L] = new { type LUB = L }
}
val intBoolLub = L[Int, Boolean].ToLub
(1: AnyVal) : intBoolLub.LUB
1: intBoolLub.LUB
true: intBoolLub.LUB
0L: intBoolLub.LUB
//
// "": intBoolLub.LUB
}
@Skavookie
Copy link

Why doesn't this work?

object lub {

  case class L[A, B]() {
    def ToLub[AA >: A <: L, BB >: B <: L, L] = new { type LUB = L }
  }

  def apply[A,B] = L[A,B].ToLub

}

class Fruit
class Kiwi extends Fruit
class Apple extends Fruit

val kal = lub[Kiwi,Apple]

It gives

scala> :load lub.scala
Loading lub.scala...
defined module lub
defined class Fruit
defined class Kiwi
defined class Apple
kal: java.lang.Object{type LUB = Any} = lub$L$$anon$1@306f7492

@retronym
Copy link
Author

The return type of apply is based on the inferred type arguments A=Any, B=Any, and L=Any, long before any fruit is passed it's way.

@Skavookie
Copy link

Is it possible to make it work without the slightly clumsy ToLub call (or rather, can you hide it)?

@ortizfabio
Copy link

Same problem as here
akka/akka#19418

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