2014-01-16 11 views
5

のマッチタプルは、私が持っている:スカラ - オプション

val foo = Some(List(1, 2, 3)) -> Some("y") 

私はそれに合わせキャストしたいと思います:

foo match { 
    case (Some(x), Some(y)) => println(x + " " + y) 
    case _ => println("error") 

これはSome(List(1, 2, 3) -> Some("score"))のため正常に動作しますが、とSome(List(1, 2, 3) -> NoneNone -> Some("y")またはNone -> Noneのために失敗します。

error: constructor cannot be instantiated to expected type; 
    found : Some[A] 
    required: None.type 
error: not found: value ... 

なぜですか?

もちろん、私はgetOrElse()を使用できますが、それほどエレガントではありません。

Thxをたくさん、 カルステン

アップデート:私はcase _はそれの世話をするだろうと思うだろう

error: pattern type is incompatible with expected type; 
found : Some[Int] 
required: None.type 

foo match { 
case (x: Some[List[Int]], y: Some[Int]) => println(x.get) 
case _ => println("error") 
} 

はとにも失敗。以下のコードで

答えて

6

それはあなたに何かを伝えるコンパイラです。あなたは

val foo = Some(List(1, 2, 3)) -> None 

のような表現を持っている場合それはあなたが簡単にScalaのコンソールで表現して

scala> val foo = Some(List(1, 2, 3)) -> None 
foo: (Some[List[Int]], None.type) = (Some(List(1, 2, 3)),None) 
を入力してから見ることができるタイプ(一部[一覧[INT]]、None.type)を、持っています

コンパイル時にタプルの2番目の要素がNoneにしかならないことが分かっているので、Someとの一致は決して成功できません。したがって、エラーメッセージ。

fooにあまり制限の少ないタイプを指定するとうまくいきます。

val foo : (Option[List[Int]], Option[String]) = Some(List(1, 2, 3) -> None 

これはまさにそのとおりであることに注意してください。決して起こりえないことにマッチングすることは、間違いなく間違いです。コンパイル時のエラーを回避するには、いずれかにアップキャストする必要があります(ただし、ランタイムエラーが発生します)。

+0

Hm、それは意味がありますが、foo._1とfoo._2が定義されている可能性があります。 – Karsten

+0

さて、私はfooが型(Option [List [Int]]、Option [Any])であると思っていましたが、 – Karsten

+0

そのようにすることはできますが、scalaの言語設計者はSomeとNoneを与えることにしました これは実際のコードではほとんど問題になりません。fooを処理する最も一般的な型に定義するからです。たとえば、Option [List [Int ]]、Option [String]) –

2

、Scalaはfoo matchにコンパイル・エラーが発生しますが、コンパイルしfoo2/foo3で正常に動作します:

val foo = None -> None 
val foo2: (Option[Any], Option[Any]) = None -> None 
val foo3: (Option[Any], Option[Any]) = foo 

foo match { 
    case (Some(x), Some(y)) => println(x + " " + y) 
    case _ => println("error") 
}