19

持つ

(Some(1), Some(2))

私は得ることを期待しています

Some((1, 2))

そして持つ

(Some(1), None)

私は得ることを期待しています

None
4

5 に答える 5

33

あなたが Scalaz について質問しているのは承知していますが、標準的な方法は耐え難いほど冗長ではないことを指摘しておく価値があります。

val x = (Some(1), Some(2))

for (a <- x._1; b <-x._2) yield (a,b)

一般的なケース (任意のアリティのタプルなど) では、Shapelessはこの種の処理に最適です。

于 2012-09-13T14:15:23.360 に答える
16

Scalaz 7 がタプルのインスタンスを提供していることを利用して、Bitraverse通常どおり (ただし のbisequence代わりに を使用してsequence)シーケンスを実行できます。

scala> import scalaz._, std.option._, std.tuple._, syntax.bitraverse._
import scalaz._
import std.option._
import std.tuple._
import syntax.bitraverse._

scala> val p: (Option[Int], Option[String]) = (Some(1), Some("a"))
p: (Option[Int], Option[String]) = (Some(1),Some(a))

scala> p.bisequence[Option, Int, String]
res0: Option[(Int, String)] = Some((1,a))

残念ながら、Scalaz 7 では現在、ここに型アノテーションが必要です。


コメントで、Yo Eight は、ここでは型注釈が引き続き必須であると述べています。彼または彼女の推論が何であるかはわかりませんが、実際には、適切に型指定されたタプルにbisequenceメソッドを提供し、型注釈を必要としない独自のラッパーを作成するのは非常に簡単です。

import scalaz._, std.option._, std.tuple._    

class BisequenceWrapper[F[_, _]: Bitraverse, G[_]: Applicative, A, B](
  v: F[G[A], G[B]]
) {
  def bisequence = implicitly[Bitraverse[F]].bisequence(v)
}

implicit def bisequenceWrap[F[_, _]: Bitraverse, G[_]: Applicative, A, B](
  v: F[G[A], G[B]]
) = new BisequenceWrapper(v)

(some(1), some("a")).bisequenceこれで問題なくコンパイルできます。

Scalaz がこのようなものを含めない正当な理由が思いつきません。それまでに追加するかどうかは好みの問題ですが、ここでコンパイラーに型付けを行わせることに理論的な障害はまったくありません。

于 2012-09-13T15:02:57.930 に答える
4
scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> (Tuple2.apply[Int, Int] _).lift[Option].tupled
res5: (Option[Int], Option[Int]) => Option[(Int, Int)] = <function1>

scala> res5((some(3), some(11)))
res6: Option[(Int, Int)] = Some((3,11))

scala> res5((some(3), none))
res7: Option[(Int, Int)] = None
于 2012-09-13T14:56:25.647 に答える