繁体   English   中英

了解Scala中的功能

[英]Understanding function in scala

这个问题严格来说是关于Scala语法的,尽管它包含akka的一些代码(例如)。

我是Scala的新手。 深入研究akka的源代码,我想出了以下非常奇怪的方法:

def transform[C]
 (f: ExecutionContext ⇒ Materializer ⇒ Future[B] ⇒ Future[C]): Unmarshaller[A, C] =
Unmarshaller.withMaterializer { implicit ec ⇒ implicit mat ⇒ a ⇒ f(ec)(mat)(this(a)) }

其中Unmarshaller.withMaterializer定义为

  def withMaterializer[A, B](f: ExecutionContext ⇒ Materializer => A ⇒ Future[B]): Unmarshaller[A, B]

这里发生了什么? 什么是可怕的函数f: ExecutionContext => Materializer => Future[B] => Future[C] 对我来说,更奇怪的是implicit s的序列: implicit ec => implicit mat => a => f(ec)(mat)(this(a))尽管withMaterializer根本没有隐式参数。

在这样的序列中,隐式是什么意思?

f: ExecutionContext => Materializer => Future[B] => Future[C]只是一个咖喱函数,所以您像带有多个参数列表的f(ec)(mat)(this(a))一样调用它(很好,从技术上讲,参数列表不像def f(...)(...)属于同一个函数,但这些都是详细信息。 换句话说, f可以写成:

f: ExecutionContext => { Materializer => { Future[B] => Future[C] } }`

(返回一个函数的函数,返回另一个函数的函数)

现在,如果您看f(ec)(mat)(this(a))有一个调用this(a) ,它在transform

def apply(value: A)(implicit ec: ExecutionContext, materializer: Materializer): Future[B]

this(a)只是对this.apply(a)的调用)。 现在apply具有两个隐式参数,即ec: ExecutionContextmaterializer:Materializer ,因此要像this(a)这样调用它,您需要两个隐式值。 这正是implicit ec ⇒ implicit mat ⇒ a ⇒ f(ec)(mat)(this(a)) 它将ecmat声明为所有嵌套函数体的隐式对象,因此this(a)可以将它们拾取。 另一种可能性是写:

ec ⇒ mat ⇒ a ⇒ f(ec)(mat)(this(a)(ec, mat))

它是带有currying和隐式参数的lambda(应该在声明的范围之内)。

“可怕的”函数类型语法是易变的 :一个参数的函数接受ExecutionContext并返回一个参数的另一个函数,后者取回Materializer并返回另一个函数,……等等。另一件事是隐式参数

这是类似构造的一个简单示例:

implicit val implicitInt: Int = 5
implicit val implicitString: String = "0"

val f: Int => String => String = {
  implicit a => {
    implicit b => {
      a.toString + b
    }
  }
}

这里的f是一个咖喱函数,它接受Int并返回一个接受String并返回String的函数。 函数值声明的一般语法为val f = { argument => ... } ,因此,如果将此参数设为隐式,则意味着在作用域中必须有此类型的实例,它将作为默认值。 您仍然可以将f应用于某些参数: f(1)("") ,因为它仍然是一个函数。

您可以通过为每个步骤定义嵌套函数来更详细地重写您要查询的代码:

def transform[C](f: ExecutionContext ⇒ Materializer ⇒ Future[B] ⇒ Future[C]): Unmarshaller[A, C] = {

  def getExecutionContext(implicit ec: ExecutionContext): Materializer => (A => Future[B]) = {

    def getMaterializer(implicit mat: Materializer): A => Future[B] = {

      def applyF(a: A): Future[B] = f(ec)(mat)(this(a))
      applyF // : A => Future[B]
    }

    getMaterializer // : Materializer => (A => Future[B])
  }

  Unmarshaller.withMaterializer(
    getExecutionContext // : ExecutionContext => (Materializer => (A => Future[B]))
  )
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM