- Learn Scala Programming
- Slava Schmidt
- 496字
- 2021-06-10 19:35:49
Function literals
We can inspect the type of the applyTwo function using REPL:
scala> :type Functions.applyTwo
(Int, Long) => Unit
This is what the type of a first-class function looks like! In general, the type of function has right and left parts separated by the =>. The left part defines the types of the arguments, the right part—the type of the result. The implementation follows the same pattern and is called function literal. Here is an example of the full definition for a function of four arguments:
val hash: (Int, Boolean, String, Long) => Int = (a, b, c, d) => {
val ab = 31 * a.hashCode() + b.hashCode()
val abc = 31 * ab + c.hashCode
31 * abc + d.hashCode()
}
On the implementation side, we have a code block which consists of three expressions and therefore is wrapped in curly braces. Please note that we define our function as a val.
Usually, the function literal can be defined using simplified syntax. For instance, the type inference allows leaving the definition of the result type. The type definition, in this case, disappears altogether, because the type definitions for the parameters will move close to the parameter names exactly as in the definition of a method:
val hashInferred = (a: Int, b: Boolean, c: String, d: Long) =>
// ... same implementation as before
On the application side, the compiler can help us to simplify the definition even more. Let's consider an example:
def printHash(hasher: String => Int)(s: String): Unit =
println(hasher(s))
We could have the following equal definitions for the hasher function. The full definition looks like the next code block:
val hasher1: String => Int = s => s.hashCode
val hasher2 = (s: String) => s.hashCode
printHash(hasher1)("Full")
printHash(hasher2)("Inferred result type")
This snippet illustrates four different ways to represent a function literal:
- Defined inline: printHash((s: String) => s.hashCode)("inline")
- Defined inline with type inference for the function parameter: printHash((s: String) => s.hashCode)("inline")
- Defined inline with type inference for the function parameter (this is known as target typing): printHash((s) => s.hashCode)("inline")
- The parentheses around single argument can be omitted: printHash(s => s.hashCode)("single argument parentheses")
- In the case, if an argument is used in the implementation of the function, at most once we can go further and use placeholder syntax: printHash(_.hashCode)("placeholder syntax")
In fact, the placeholder syntax is quite powerful and can also be used to define functions of multiple parameters as well as functions that are not in the target typing position. Here is an example of a function that calculates a hash code for four instances of Int using the placeholder syntax:
scala> val hashPlaceholder =
(_: Int) * 31^4 + (_: Int) * 31^3 + (_: Int) * 31^2 + (_: Int) * 31
scala> :type hashPlaceholder
(Int, Int, Int, Int) => Int
This syntax looks close to the partial application syntax, but represents a completely different language feature.
- ClickHouse性能之巔:從架構(gòu)設計解讀性能之謎
- Mastering RabbitMQ
- Arduino by Example
- Julia機器學習核心編程:人人可用的高性能科學計算
- JavaScript+Vue+React全程實例
- Mastering ServiceNow(Second Edition)
- 信息技術應用基礎
- PHP+MySQL+Dreamweaver動態(tài)網(wǎng)站開發(fā)從入門到精通(第3版)
- 蘋果的產(chǎn)品設計之道:創(chuàng)建優(yōu)秀產(chǎn)品、服務和用戶體驗的七個原則
- Java高并發(fā)核心編程(卷1):NIO、Netty、Redis、ZooKeeper
- SciPy Recipes
- Visual Studio Code 權(quán)威指南
- App Inventor 2 Essentials
- Python算法交易實戰(zhàn)
- WCF 4.5 Multi-Layer Services Development with Entity Framework(Third Edition)