1

orElse を使用して Option をチェーンした後、要素の型が変更され、期待どおりに使用できなくなったことがわかりました。

例: タイプが .xml のNodeSeq.

scala> xml1.headOption map { head => None } orElse xml2.lastOption map {last => Some(last)}
res11: Option[Some[ScalaObject with Equals]] = Some(Some(None))

の前にorElseheadは typeNodeであり、これは正しいですが、 type であるlast必要がありますNodeが、コンパイラはそれが typeであると見なし、パラメーターとして aを取る関数にScalaObject with Equals渡すことができません。lastNode

を使用してキャストできますlast.asInstanceOf[Node]が、このキャストを回避してlastタイプを作成する方法はありNodeますか?

4

3 に答える 3

3

代わりにこれを試してください(括弧が追加されていることに注意してください):

(xml.headOption map { head => None }) orElse (xml.lastOption map {last => Some(last)})

問題は、がbefore ではなくmapafter に適用されていることです。つまり、式は次のように解析されます。orElseorElse

((xml.headOption map { head => None }) orElse xml.lastOption) map {last => Some(last)}

の左側の式orElseは typeを持っていますOption[Option[Node]]が、右側の式は type を持っているOption[Node]ため、最も一般的なスーパータイプはOption[ScalaObject with Equals]です。

Scala の柔軟な構文により、コーディングが非常にうまくいく場合もありますが、別の場合には、このようなおかしな結果になります。このような複雑な式の場合は、括弧を追加して意味をより明確にすることをお勧めします。

于 2012-08-28T10:11:36.180 に答える
1

一般的に、あまり意味がないので、自分が何をしているのかを正確に再検討する必要があると思います。xml.headOption map { head => None }(あなたの場合)常に解決しようとしてSome(None)いますが、これはめったにあなたが望むものではありません。私の最もよい推測はあなたが次のようなものが欲しいということです:

xml.headOption.orElse(xml.lastOption)

headOptionがNoneの場合、lastOptionもNoneになることに注意してください。

編集:Dao Wenが指摘しているように、この例ではの正しい上限を推測することはかなり可能でOption[Node]あり、それを曖昧にする問題は間違ったorElse呼び出しの問題でした。ただし、ここでの本当の問題は、あなたがしていることがあまり意味をなさないことであり、おそらく再考する必要があると思います。

于 2012-08-28T10:04:00.443 に答える
0

map {head => None}おそらくあなたが意図したものではありません。それはタイプミスですか?

その後、Option[None.type]2つの可能な値しかない、あまり面白くないタイプである、、NoneおよびがありSome(None)ます。xmlは空ではないため、たまたまSome(None)になっています。

xml.LastOptionタイプがありますOption[Node]

したがって、orElseそれらの間で実行すると、との最も正確な一般的なスーパータイプ(最小の上限)が検索されNone.typeますNode。そして、興味のあるものはありません、それはたまたまそうですScalaObject with Equals、それは同じようにそうかもしれませんAnyRef

あなたの決勝戦map {last => Some(last)}もかなり奇妙です。そこで何をするつもりですか?

于 2012-08-28T10:03:17.973 に答える