[英]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: ExecutionContext
和materializer:Materializer
,因此要像this(a)
這樣調用它,您需要兩個隱式值。 這正是implicit ec ⇒ implicit mat ⇒ a ⇒ f(ec)(mat)(this(a))
。 它將ec
和mat
聲明為所有嵌套函數體的隱式對象,因此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.