与JodaTime工作,尝试转换列表[LOCALDATE的]到Tuple2 [JodaTime,JodaTime]所以我可以做多分配新建分配FY像这样:
val(expire, now) =
List(row.expireDate, new JodaDate) zip (_.toDateTimeAtStartOfDay.getMillis)
这当然不能编译。 有没有类似的简洁的方式做以上? 我知道我可以做手工:
val(expire, now) =
(row.expireDate.toDateTimeAtStartOfDay.getMillis,
new JodaDate().toDateTimeAtStartOfDay.getMillis)
但是这是一个有点难看
val Seq(expire, now) =
Seq(row.expireDate, new JodaDate).map(_.toDateTimeAtStartOfDay.getMillis)
你想(假设你不想去转换-TO-什么Seq
路线)是Scalaz的Bifunctor
实例元组(这是不是在标准库)。 有了它,你可以写:
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> val cap = (_: String).toUpperCase
cap: String => java.lang.String = <function1>
scala> val removeLs = (_: String).replaceAll("l", "")
removeLs: String => java.lang.String = <function1>
scala> cap <-: ("hello", "world") :-> removeLs
res0: (java.lang.String, java.lang.String) = (HELLO,word)
或者,你的情况:
val f = (_: JodaDate).toDateTimeAtStartOfDay.getMillis
val (expire, now) = f <-: (row.expireDate, new JodaDate) :-> f
val Seq(a, b) =
Seq("a", "b").map(_.toUpperCase)
println("a, b = %s, %s".format(a, b)) // a, b = A, B
如果你想继续使用一个元组(记住,unapplying一个时的类型安全Seq
,编译器将不检查长度),你可以写一个包装中添加标准库不具备的功能,可以让你映射在一个元组。
在通过使用单功能两种元素映射的情况下,因为一个Tuple2[A, B]
具有两个类型参数,所述关键是使这个工作是需要的证据表明, A
和B
的类型相同。 要做到这一点,需要类型的隐式参数B =:= A
; 如果类型确实相等,则编译器将提供类型的函数B => A
。
class Tuple2Wrapper[A, B](t: (A, B)) {
def bimap[C, D](f: A => C, g: B => D): (C, D) = (f(t._1), g(t._2))
def <-:->[C](f: A => C)(implicit ev: B =:= A): (C, C) = bimap(f, f compose ev)
}
implicit def tuple2Tuple2Wrapper[A, B](t: (A, B)) = new Tuple2Wrapper(t)
scala> (1, 1) <-:-> (_ + 1)
res1: (Int, Int) = (2,2)
这可能在(适用于多种类型的不仅仅是一个更加普遍和有效的方式来完成Tuple2
),如果Scalaz的方面实现Bifunctor
特质。