是否可以将(Option[Int], Option[String])
转换为(FirstOption[Int], FirstOption[String])
?以比x=> (x._1.first, x._2.first)
更短的方式?
在我看来应该有办法做到这一点,但我无法找到它。
答案 0 :(得分:4)
一种方法可能是使用Bifunctor实例:
scala> val t = (Option(1), Option("str"))
t: (Option[Int], Option[java.lang.String]) = (Some(1),Some(str))
scala> import scalaz._, Scalaz._, Tags._
import scalaz._
import Scalaz._
import Tags._
scala> t.bimap(First, First)
res0: (scalaz.package.@@[Option[Int],scalaz.Tags.First], scalaz.package.@@[Option[java.lang.String],scalaz.Tags.First]) = (Some(1),Some(str))
更惯用的方式(好的,更通用的方式:适用于任何元组,tripple等)可能会使用shapeless将您的元组转换为HList
,然后应用自然变换Option[A] ~> Option[A] @@ First
。这是一个粗略的实现:
scala> import scalaz._, Scalaz._, Tags._
import scalaz._
import Scalaz._
import Tags._
scala> import shapeless._, Tuples._, Nat._
import shapeless._
import Tuples._
import Nat._
scala> val t = (Option(1), Option("str"))
t: (Option[Int], Option[String]) = (Some(1),Some(str))
scala> object optionToFirstoption extends (Option ~> FirstOption) {
| def apply[A](fa: Option[A]): Option[A] @@ First = First(fa)
| }
defined module optionToFirstoption
scala> t.hlisted.map(optionToFirstoption).tupled
res1: (Option[Int] with scalaz.Tagged[scalaz.Tags.First], Option[String] with scalaz.Tagged[scalaz.Tags.First]) = (Some(1),Some(str))