2016-07-13 23 views
0

Option(Option(Some))をフラット化しようとしていますが、コードをコンパイルしようとするとエラーが発生します。Option(Option(Some))を実行しようとするとエラーが発生する

val foo = request.options.get(myKey).flatten 
if(foo.get == bar) {...} 

request.option.get(Key)戻りOption[Any]次のよう

コードです。この場合、myKeyに関連付けられた値はOptionなので、このコードをデバッグするときに見たOption(Option(Some))を返すように、request.options.get(myKey) を返す必要があります。

はしかし、私は次のエラーを受け取る:

Error: Cannot prove that Any <:< Option[B]. 

Error: not enough arguments for method flatten: (implicit ev: <: <[Any,Option[B]])Option[B] 
Unspecified value parameter ev. 

私の知る限り、このケースで動作するはず平ら。

答えて

0

を:私はあなたがgetに渡す前にSomeのうちkeyを得ている何をしたいかと思いますコンパイル時にメソッドの署名は、それがOption[Any]を返すことを保証するだけです。これは、コンパイラが不平を言っていることです。 Option[Any]があることを証明できますが、Option[Option[_]]コンパイル時ににあることを証明することはできません。

道のりは<:<[A, B]の構文糖だけです。この型は、コンパイラがA <: Bを知っている証拠を表します。それは、その存在を目の当たりにすることです。コンパイラが何らかの形でその関係を証明できない場合、A <:< Bの値はありません。したがって、flattenは、<:<[A,B]の暗黙のパラメータを持つ通常の方法です。コンパイラはコンパイル時にこのパラメータを解決する必要があります。そうしないと、パラメータがないためにメソッド呼び出しが無効になります。したがって、コンパイル時には、AAnyget(key))、BOption[C]flattenの署名)になります。関係Any <: Option[C]を証明する方法がないため、エラーが発生します。

このコードが有効な場合は、が有効であったとします。あなたのマップがSome(Some(blah))の代わりにSome(5)を返すようになった場合でも、Some(5).flattenに電話をかけようとすると、5をOptionにキャストしようとすると、... oops。あなたのプログラムのロジックがあなたのマップがネストされたOptionを与えていることを絶対に確信したとしても、コンパイラは明らかに魔法ではなく、確かではありません。

部分的な関数matchを使用すると、実行時にコンパイル時にチェックされ、ケースに合致しないものはコンパイラによってキャッチされる代わりにMatchErrorがスローされます。

TL; DR一般型制約は戻り値の型がOption[Any]であるため、ここでは不可能な、コンパイル時に解決されています。

1

request.options.get(key)Option[T]に戻るということは、request.options.get(Some(key))Option[Option[T]]を返すという意味ではありません。あなたはget(key)があるという事実は変わりませんネストされたOption実行時で返すことがわかりという理由だけで

val theValueIWant = for { 
    k <- myKey     // get k out of the Some 
    op <- request.options.get(k) // get the option (Some(value) or None) 
    value <- op     // get the value out of the option 
} yield value 
+0

問題は、マップされた値がオプションであることでした。私が結果にマッチを使うかどうかは、私が必要とする行動を得ることができるかどうかを見る。例:val bar = foo match { caseなし=> //キーが存在しない case(None)=> //マップに存在するが、Noneにマップされたキー case Some(value)=> //マップの値 } – knueser

+0

何が起きているのかを理解するために、私は 'request.options'と' myKey'の型を知る必要があります。 –

関連する問題