Ответ 1
Вы можете использовать тот факт, что 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
будет компилироваться просто отлично.
Я не могу придумать, почему Scalaз не включил бы что-то вроде этого. Независимо от того, хотите ли вы добавить его в то же время, это вопрос вкуса, но, безусловно, нет теоретического препятствия, позволяющего компилятору печатать здесь.