9

tupleサイズを指定せずにa を部分的に一致させる方法はありますか? たとえば、タプルがあった場合

val v = ( "Dr", "John","H", "Watson") 

次のようなことができるようになりたいです:

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

これはコンパイルされません。:_*通常、パラメーターの数が不定であることを意味しますが、この場合は明らかに使用できません。アイデアは、このマッチャーを 2 より大きい任意のタプルに使用できるようにすることです。最初に (たとえば) に変換できることはvわかっListていtupleます。

編集:私がウェブで見つけたほとんどの情報はこの議論であり、これはscala 2.8にさかのぼるので、「いいえ、できません」という答えを出します。

4

3 に答える 3

11

タプルは、異種の型の構造です。そのため、彼らは特性を実装しているproductIteratorので、次のことができます:

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

Seq[String]しかし、あなたの例は本当にすぐに欲しいように見えます。タプルを使用したい理由はありますか?

于 2013-03-29T23:17:44.197 に答える
10

これは、タプルから へのshapelessHListsの変換を使用して行うことができます。

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?

上記の例では見えませんが、可能であれば、case 句でバインドされた名前の完全な静的型情報が維持されることに注意してください。たとえば、

scala> (23, "foo", true).hlisted match {
     |   case i :: s :: b :: HNil => if(b) i+s.length else 0
     |   case _ => -1
     | }
res1: Int = 26
于 2013-03-30T10:51:48.227 に答える