jpalecek
jpalecek

Reputation: 47762

Unpacking tuple types in Scala

I was just wondering, can I decompose a tuple type into its components' types in Scala?

I mean, something like this

trait Container {
  type Element
}

trait AssociativeContainer extends Container {
  type Element <: (Unit, Unit)
  def get(x : Element#First) : Element#Second
}

Upvotes: 7

Views: 2843

Answers (3)

pdbartlett
pdbartlett

Reputation: 1519

I'm a bit late to this, but what about using pattern matching? Doesn't have quite the correct return type, and my syntax might be a bit off, but here goes:

def get[K](key: K): Iterable[Any] {
  for ((key, x) <- elements) yield x
}

Upvotes: 0

retronym
retronym

Reputation: 55028

This doesn't unpack the types, but it does constrain the types A and B when calling get.

trait Container {
  type Element
}

trait AssociativeContainer extends Container {
  type Element <: Tuple2[_, _]

  def get[A, B](x: A)(implicit ev: (A, B) =:= Element): B
}

This looks promising, but is cheating -- it doesn't work if Element is abstract.

def Unpack[T<:Tuple2[_, _]] = new {
  def apply[A, B](implicit ev: T <:< (A, B)) = new {
    type AA = A
    type BB = B
  }
}

trait AssociativeContainer {
  type Element = (Int, String)
  val unpacked = Unpack[Element].apply
  type A = unpacked.AA
  type B = unpacked.BB

  1: A
  "": B
  def get(x: A): B
}

Upvotes: 3

Jorge Ortiz
Jorge Ortiz

Reputation: 4722

You can't unpack, per se, but maybe this achieves what you want:

  type First
  type Second
  type Element = (First, Second)
  def get(x: First): Second

Upvotes: 3

Related Questions