我已经看到一个名为“at”的对象(可能是一个函数)散布在整个无形源和使用无形的代码中。特别是在对 this other question 的回答中使用了它.这是代码片段:
object iterateOverHList extends Poly1 {
implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator)
}
我知道它与 ~> 类型的 apply 方法有关。 “at”具体做什么,它在哪里定义?
最佳答案
PolyN#at
的定义at
是使用 Poly
的通用方法.~>
与 apply
是 special case的 Poly1
. apply
这里用于使用 at
定义隐式方法:
implicit def caseUniv[T] = at[F[T]](apply(_))
方法
at
是 defined在 PolyN
(例如在 Poly1
中)像这样:trait PolyN extends Poly { outer =>
type Case[T1, T2, ..., TN] = poly.Case[this.type, T1 :: T2 :: ... :: TN :: HNil]
object Case {
type Aux[T1, T2, ..., TN, Result0] = poly.Case[outer.type, T1 :: T2 :: ... :: TN :: HNil] { type Result = Result0 }
}
class CaseBuilder[T1, T2, ..., TN] {
def apply[Res](fn: (T1, T2, ..., TN) => Res) = new Case[T1, T2, ..., 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, T2, ..., TN] = new CaseBuilder[T1, T2, ..., TN]
}
如果是
Poly1
:trait Poly1 extends Poly { outer =>
type Case[T1] = poly.Case[this.type, T1 :: HNil]
object Case {
type Aux[T1, Result0] = poly.Case[outer.type, 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]
}
所以
at[Int]
创建 CaseBuilder[Int]
的实例和 at[Int].apply[String](_.toString)
或只是 at[Int](_.toString)
(用于 apply
方法调用的语法糖)创建了一个 poly.Case[this.type, Int :: HNil]{ type Result = String }
的实例.所以与
implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator)
您创建一个隐式方法来创建 poly.Case[this.type, L[T] :: HNil]{ type Result = Iterator[T] }
.此隐式方法用于
map
(以及其他一些多态函数)。HList#map
的实现map
是 defined像这样:def map(f : Poly)(implicit mapper : Mapper[f.type, L]) : mapper.Out = mapper(l)
(
L
是 HList
的类型)创建一个
Mapper
编译器 looks为 Case1[Fn, T]
.对于
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]
找到一个隐含的值.万一
f
是 object
搜索隐式的地方之一是 f
领域和方法。所以编译器会发现Case
定义于 f
.
关于scala - 无形(scala)中的 "at"是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20912679/