2013-03-29 19 views
9

Boyutu belirtmek zorunda kalmadan bir tuple eşleştirmenin bir yolu var mı? Bir tupleScala'da bilinmeyen boyutta bir tuple eşleştirin

val v = ("Dr", "John","H", "Watson") 
olsaydı Örneğin, böyle bir şey yapabilmek istiyorum

: Bu derleme değil

v match { 
    case ("Dr", : _*) => "What's up, Doc?" 
    case ("Mr", name, :_*) => s"Welcome, Mr. ${name}" 
    case _ => "Have we met?" 
} 

, :_* normalde parametrelerin belirsiz sayıda anlamına gelir ama Bu durumda görünüşte kullanılamaz. Bu izleyici, 2'den büyük herhangi bir tuple için kullanabilmekti. v'u List (örneğin) dönüştürmek için yapabileceğimi biliyorum, sadece bir tuple ile yapmanın mümkün olup olmadığını bilmek istiyorum.

DÜZENLEME: Web'de bulunan en bilgilerin geri scala 2.8 kadar uzanır ki, this discussion, bu yüzden 'Hayır, olamaz' cevap vereceğim.

+0

Bildiğim kadarıyla, hiçbir yol yoktur, çünkü farklı büyüklükteki tupllar farklı tiplerdir. Ancak makrolarla yapılabilir - amaç tüm olası boyutlara uyacak kod üretmektir. Ya da önerdiğiniz gibi, örtülü dönüşümleri "Seq [Any]" olarak tanımlayın. Bu da kirli bir çözümdür ve kendinize sormanız daha iyi olur, sorunlarınızda kullanmak için doğru tipler mi? Belki de değiller. –

+1

@SargeBorsch ama hepsi Ürün'ü uzatır ;-) –

+0

@ om-nom-nom Evet, bu doğrudur, ancak Ürün türünüz varsa, öğelerinin türlerini bilmiyorsunuz ve bu nedenle verilerinize güvenli bir şekilde erişimini kaybediyorsunuz (gereksiniminiz var) öğelerinin türlerini el ile kontrol etmek/dökmek için) –

cevap

11

Tupllar, heterojen tipler için yapılardır. Bunun gibi, onlar productIterator özellik uygulamak, böylece yapabileceği:

v.productIterator.toList match { 
    case "Dr" :: _ => "What's up, Doc?" 
    case "Mr" :: name :: _ => s"Welcome, Mr. ${name}" 
    case _ => "Have we met?" 
} 

Ama hemen bir Seq[String] gibi istediğiniz örnek gerçekten görünüyor. Tuples kullanmak istemek için herhangi bir sebep var mı?

+1

Soruda belirtildiği gibi, sadece mümkün olup olmadığını bilmek istiyorum, tuplleri kullanmak için özel bir neden yoktur. Aslında bunu yapmaya gerek yok, sadece merak ediyorum: D – Chirlo

+1

Yani kısa cevap “hayır”, farklı nesnelerin tupleri aralarında hiçbir şey paylaşmıyorlar. –

10

Bu HLists için küpe gelen shapeless 'ın dönüşümleri kullanılarak yapılabilir,

scala> import shapeless._ 
import shapeless._ 

scala> import Tuples._ 
import Tuples._ 

scala> val v = ("Dr", "John","H", "Watson") 
v: (String, String, String, String) = (Dr,John,H,Watson) 

scala> v.hlisted match { 
    | case "Dr" :: _ => "What's up Doc?" 
    | case "Mr" :: name :: _ => s"Welcome, Mr. ${name}" 
    | case _ => "Have we met?" 
    | } 
res0: String = What's up Doc? 

o yukarıdaki örnekte görünür olmasa da, olası tam statik türü bilgisi bağlanmış adları için tutulur nerede olduğuna dikkat vaka hükümler, örneğin,

scala> (23, "foo", true).hlisted match { 
    | case i :: s :: b :: HNil => if(b) i+s.length else 0 
    | case _ => -1 
    | } 
res1: Int = 26 
-1

bu deneyin:

case tuple:Product => { 
    tuple.productIterator.toList match { 
     case (head::rest) => ... 

    } 
} 
İlgili konular