假设我们有这个:
def join[A,B](a: A,b: B) def join[A,B,C](a: A,b: B,c: C) // etc
基本上很多重载方法最多可以包含20个类型的参数.
然后通过在HList上强制执行一元类型约束来创建K列表,以便所有内部元素都是Task [_]类型.
class Test(L <: HList : *->*[Task]#λ](val deps : L = HNil)
是否可以将deps转换为任务[A1,A2,A3]等,其中A1,A3是HList的内部类型?
因此对于:
val hls = Task(1) :: Task("string") :: Task9(true) :: HNil
检索一个:
Task[(Int,String,Boolean)]
为任意数量的论点做这个吗?我可以将任务[A],任务[B]转换为任务[A,B]任意数量的参数,只需要从HList转换为varargs或类似的.
解决方法
从Scala的角度来看,这些连接方法没有任何共同之处,只有它们的名称,所以如果没有很多样板(或自定义宏),在这种情况下使用它们是不可能的.相反,可以反复使用Twitter的Future本身的连接.您可以通过创建新类型来完成此操作:
import shapeless._ trait FutureSequence[L <: HList] extends DepFn1[L]
这个类型类将见证hlist L完全由期货组成,它将为我们提供一种方法将这些期货排序为Future [T],其中T是由每个期货内部类型组成的元组在L(* – > *给我们第一部分,但不支持第二部分,甚至任何方式完全没有第二部分).
伴侣对象完成所有有趣的工作:
import com.twitter.util.Future import shapeless.ops.tuple.Prepend object FutureSequence { type Aux[L <: HList,Out0] = FutureSequence[L] { type Out = Out0 } implicit def hnilFutureSequence: Aux[HNil,Future[Unit]] = new FutureSequence[HNil] { type Out = Future[Unit] def apply(l: HNil): Future[Unit] = Future.Unit } implicit def hconsFutureSequence[H,T <: HList,OutT](implicit fst: Aux[T,Future[OutT]],pre: Prepend[Tuple1[H],OutT] ): Aux[Future[H] :: T,Future[pre.Out]] = new FutureSequence[Future[H] :: T] { type Out = Future[pre.Out] def apply(l: Future[H] :: T): Future[pre.Out] = l.head.join(fst(l.tail)).map { case (h,t) => pre(Tuple1(h),t) } } }
我们在这里使用归纳 – 首先我们描述如何对HNil进行排序(我们的基本情况),然后我们描述如何对Future [H] :: T进行排序,因为我们知道如何对T进行排序.
def sequence[L <: HList](l: L)(implicit fs: FutureSequence[L]): fs.Out = fs(l)
如果我们有一些例子:
val good = Future(1) :: Future("string") :: Future(true) :: HNil val bad = Future(1 / 0) :: Future("string") :: Future(true) :: HNil
我们可以对它们进
scala> import com.twitter.util.Await import com.twitter.util.Await scala> Await.result(sequence(good)) res0: (Int,Boolean) = (1,string,true) scala> sequence(bad).onFailure(println) java.lang.ArithmeticException: / by zero res1: com.twitter.util.Future[(Int,Boolean)] = ...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。