シーケンスを作成する操作がある Scala プログラムを書いています。操作が失敗する可能性があるため、 で囲みTry
ます。for 内包内でシーケンスの作成と列挙を行いたいので、正常に作成されたシーケンスは、最初の要素がシーケンスであり、2 番目の要素がその要素であるタプルのシーケンスを生成します。
問題を単純化するために、Range
整数のシーケンスcreateRange
を作成し、奇数の長さの範囲を作成するように求められた場合に失敗する関数を定義します。これは、私が望むことを理解するための簡単なものです。
import scala.util.Try
def createRange(n: Int): Try[Range] = {
Try {
if (n % 2 == 1) throw new Exception
else Range(0, n)
}
}
def rangeElements(n: Int) {
for {
r <- createRange(n)
x <- r
} println(s"$r\t$x")
}
def main(args: Array[String]) {
println("Range length 3")
rangeElements(3)
println("Range length 4")
rangeElements(4)
}
これを実行すると、正しく印刷されます。
Range length 3
Range length 4
Range(0, 1, 2, 3) 0
Range(0, 1, 2, 3) 1
Range(0, 1, 2, 3) 2
Range(0, 1, 2, 3) 3
ここで、関数を書き直してrangeElements
、副作用として出力するのではなく、整数のシーケンスを返すようにします。範囲が作成されていない場合、シーケンスは空です。書きたいのはこれです。
def rangeElements(n: Int):Seq[(Range,Int)] = {
for {
r <- createRange(n)
x <- r
} yield (r, x)
}
// rangeElements(3) returns an empty sequence
// rangeElements(4) returns the sequence (Range(0,1,2,3), 0), (Range(0,1,2,3), 1) etc.
これにより、2 つの型の不一致コンパイラ エラーが発生します。r <- createRange(n)
行が必要ですSeq[Int]
が見つかりましたscala.util.Try[Nothing]
。x <- r
行が必要ですscala.util.Try[?]
が見つかりましたscala.collection.immutable.IndexedSeq[Int]
。
おそらく、Try
私を台無しにしているタイプの消去がありますが、それが何であるかわかりません。私は理解のために、行でさまざまな修飾子を試しましtoOption
たtoSeq
が、役に立ちませんでした。
範囲要素のみを生成する必要がある場合は、以下の最初の 2 つの回答で示唆されているように、自分自身のSuccess
andFailure
条件を明示的に処理できます。createRange
ただし、範囲とその個々の要素の両方にアクセスする必要があります。
これは奇妙に聞こえる例だと思います。私が解決しようとしている本当の問題は複雑な再帰検索ですが、ここで問題を混乱させるだけなので、その詳細をすべて追加したくありません。
rangeElements
目的のシーケンスを生成するにはどうすればよいですか?