2
是否有可能將(Option[Int], Option[String])
轉換爲(FirstOption[Int], FirstOption[String])
?比x=> (x._1.first, x._2.first)
短?在元組中使用FirstOption monoid實例
在我看來,應該有辦法做到這一點,但我無法找到它。
是否有可能將(Option[Int], Option[String])
轉換爲(FirstOption[Int], FirstOption[String])
?比x=> (x._1.first, x._2.first)
短?在元組中使用FirstOption monoid實例
在我看來,應該有辦法做到這一點,但我無法找到它。
一種方式是使用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: ([email protected]@[Option[Int],scalaz.Tags.First], [email protected]@[Option[java.lang.String],scalaz.Tags.First]) = (Some(1),Some(str))
更習慣的方法(好吧,一個更通用的方法:將任何元組,特里普爾等工作)可能會被使用到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))
不錯,但我會質疑使用「更地道」在這裏;-) – 2013-03-22 13:55:37
@MilesSabin Yyeah,一個「更多的鐵桿」可能會形容這是怎麼回事更好:) – folone 2013-03-22 13:59:15
好吧,還有一個問題:是否可以在不寫整個'Monoid [Option [T]]'的情況下使Monoid Default的FirstOption實現?例如。 'implicit def firstOptionMonoid [T] = implicitly [Monoid [FirstOption [T]]]' - 這顯然不起作用,但我能想到的方式真的很冗長(隱式def firstOptionMonoid [T] = new Monoid [T] { def append(...)= implicitly [Monoid [FirstOption [T]]] append(...); def zero = ...}) – 2013-03-22 17:55:24