什么是“在"?在无形(scala)? [英] What is "at" in shapeless (scala)?

查看:54
本文介绍了什么是“在"?在无形(scala)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到一个名为at"的对象(可能是一个函数)散布在整个无形源代码和使用无形的代码中.特别是,它用于回答另一个问题.这是代码片段:

I've seen an object (probably a function) called "at" sprinkled throughout the shapeless source and in code that uses shapeless. In particular, it is used in the answer to this other question. Here is the code snippet:

object iterateOverHList extends Poly1 {
  implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator)
}

我知道它与 ~> 类型的 apply 方法有关.at"的具体作用是什么,它在哪里定义?

I've had some clue that it is related to the apply method of the ~> type. What specifically does "at" do, and where is it defined?

推荐答案

PolyN#at

的定义

at 是使用 Poly 的通用方法.

Definition of PolyN#at

at is a general way to work with Poly.

~>apply 是一个 特殊情况 Poly1.apply 这里用来定义隐式方法,使用at:

~> with apply is a special case of Poly1. apply here is used to define implicit method using at:

implicit def caseUniv[T] = at[F[T]](apply(_))

方法 atPolyN 中(例如在 Poly1 中)像这样:

Method at is defined in PolyN (for instance in Poly1) like this:

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) 的实例code> 或只是 at[Int](_.toString)(apply 方法调用的语法糖)创建一个 poly.Case[this.type,Int :: HNil]{ type Result = String }.

So at[Int] creates an instance of CaseBuilder[Int] and at[Int].apply[String](_.toString) or just at[Int](_.toString) (synax sugar for apply method call) creates an instance of poly.Case[this.type, Int :: HNil]{ type Result = String }.

所以使用 implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator) 你创建了一个隐式方法来创建a poly.Case[this.type, L[T] :: HNil]{ type Result = Iterator[T] }.

So with implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator) you create an implicit method to create a poly.Case[this.type, L[T] :: HNil]{ type Result = Iterator[T] }.

这个隐式方法用于map(以及其他一些多态函数).

This implicit method is used in map (and in some other polymorphic functions).

map定义如下:

def map(f : Poly)(implicit mapper : Mapper[f.type, L]) : mapper.Out = mapper(l)

(LHList的类型)

创建Mapper 编译器查找Case1[Fn, T].

对于 A :: B :: ... :: HNil 上的 map(f) 编译器必须为 Case1[f.type,A]Case1[f.type, B] 等.

For map(f) on A :: B :: ... :: HNil compiler have to find implicits for Case1[f.type, A], Case1[f.type, B] and so on.

List[Int] :: HNil 的情况下,唯一需要的隐式 Case1Case1[f.type, List[Int]].

In case of List[Int] :: HNil the only implicit Case1 needed is Case1[f.type, List[Int]].

请注意,Case1像这样定义:

type Case1[Fn, T] = Case[Fn, T :: HNil]

所以我们必须为 Case[f.type, List[Int] :: HNil] 找到一个隐含的值.

So we have to find an implicit value for Case[f.type, List[Int] :: HNil].

如果 fobject 搜索隐式的地方之一是 f 字段和方法.所以编译器会找到f中定义的Case.

In case f is an object one of the places to search for implicits is f fields and methods. So compiler will find Case defined in f.

这篇关于什么是“在"?在无形(scala)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆