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
}
starblue
57k14 gold badges101 silver badges153 bronze badges
asked Feb 23, 2009 at 0:00
3 Answers 3
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
answered Feb 23, 2009 at 0:42
Sign up to request clarification or add additional context in comments.
2 Comments
jpalecek
That's what I thought I needed to do, but wanted to avoid, because that would change the implementation of classes extending this trait.
jpalecek
Also, does this mean the Element pair would be the same Pair even in subclasses? Shouldn't it be rather Element <: (First, Second) [or maybe lower bounded, too]?
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
}
answered May 15, 2010 at 21:44
Comments
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
}
answered May 15, 2010 at 20:53
Comments
lang-scala