我看到一个名为“at”的对象(可能是一个函数)洒在整个无形源和使用无形的代码中.特别是在
this other question的答案中使用了这个代码片段:
object iterateOverHList extends poly1 { implicit def iterable[T,L[T] <: Iterable[T]] = at[L[T]](_.iterator) }
解决方法
polyN#的定义
是与poly合作的一般方式.
〜>适用于poly1的special case.这里应用的是用于定义隐式方法使用:
implicit def caseUniv[T] = at[F[T]](apply(_))
polyN中的方法是defined(例如poly1),如下所示:
trait polyN extends poly { outer => type Case[T1,T2,...,TN] = poly.Case[this.type,T1 :: T2 :: ... :: TN :: HNil] object Case { type Aux[T1,TN,Result0] = poly.Case[outer.type,T1 :: T2 :: ... :: TN :: HNil] { type Result = Result0 } } class CaseBuilder[T1,TN] { def apply[Res](fn: (T1,TN) => Res) = new Case[T1,TN] { type Result = Res val value = (l: T1 :: T2 :: ... :: TN :: HNil) => l match { case a1 :: a2 :: ... :: aN :: HNil => fn(a1,a2,aN) } } } def at[T1,TN] = new CaseBuilder[T1,TN] }
在poly1的情况下:
trait poly1 extends poly { outer => type Case[T1] = poly.Case[this.type,T1 :: HNil] object Case { type Aux[T1,T1 :: HNil] { type Result = Result0 } } class CaseBuilder[T1] { def apply[Res](fn: (T1) => Res) = new Case[T1] { type Result = Res val value = (l: T1) => l match { case a1 :: HNil => fn(a1) } } } def at[T1] = new CaseBuilder[T1] }
所以在[Int]创建一个CaseBuilder [Int]和[Int] .apply [String](_.toString)的实例,或者在[Int](_.toString)(应用程序调用的synax sugar)创建一个实例的poly.Case [this.type,Int :: HNil] {type Result = String}.
因此,使用隐式def迭代[T,L [T]
def map(f : poly)(implicit mapper : Mapper[f.type,L]) : mapper.Out = mapper(l)
(L是HList的类型)
为Case1 [Fn,T]创建Mapper编译器looks.
对于Map(f)在A :: B :: … :: HNil编译器必须找到Case1 [f.type,A],Case1 [f.type,B]等等的含义.
在List [Int] :: HNil的情况下,唯一需要的隐藏Case1是Case1 [f.type,List [Int]].
请注意,Case1为defined,如下所示:
type Case1[Fn,T] = Case[Fn,T :: HNil]
所以我们必须为Case [f.type,List [Int] :: HNil]找到一个隐含的值.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。