我想知道為什么 Scala 不像其他函式式編程語言那樣對函式使用相同風格的部分應用程式?
多個引數串列背后的好處或想法是什么?
這是否與 Scala 基于點演算的事實有關,或者它是針對 JVM 的優化?
對我來說,如果有人將函式定義為:
def f(x: Int, y: Int): Int
而不是:
def f(x: Int)(y: Int): Int
我不能做部分應用,簡單的方法。
像這樣定義大多數函式是否是一種好習慣(這是一種默認方法):
def f(x: Int)(y: Int)(z: Int): Int
uj5u.com熱心網友回復:
Odersky 等人對此進行了Programming In Scala報道。
Scala 用于部分應用函式的語法突出了 Scala 和經典函式式語言(例如 Haskell 或 ML)在設計權衡方面的差異。在這些語言中,部分應用函式被認為是正常情況。此外,這些語言具有相當嚴格的靜態型別系統,通常會通過您可以制作的部分應用程式突出顯示每個錯誤。Scala [與諸如 Java 之類的語言有關],其中未應用于所有引數的方法被視為錯誤。此外,子型別和通用根型別的面向物件傳統接受一些在經典函式式語言中被認為是錯誤的程式。
例如,假設您弄錯了for的
drop(n: Int)方法,因此忘記了需要將數字傳遞給。你可能會寫。如果 Scala 采用了部分應用函式在任何地方都可以的經典函式式傳統,那么這段代碼就會進行型別檢查。但是,您可能會驚訝地發現[這樣做的副作用總是輸出] ![Since] 運算式將被視為任何函式物件并采用任何型別的物件,這將被編譯,但會產生意想不到的結果。Listtaildropprintln(drop)println<function>dropprintln
為避免這種情況,Scala 通常要求您指定明確省略的函式引數,即使指示很簡單,如
_. [然而_,可以省略] 僅在需要函式型別時。
f(x)(y)僅當對部分應用程式有明顯的實用性(或作為作者表示支持部分應用程式的信號)或為了利用與 Scala 其他方面的相互作用時,才傾向于使用該表示法:
型別推斷通過引數串列進行引數串列,因此可以根據第一個引數串列修復型別以用于后面的引數串列。這可以節省一些型別界限。考慮
Option.map(f).getOrElse(a)(其中a可以是f的結果型別的任何超型別的實體)與Option.fold(a)(f)(其中的型別a約束 的結果型別f)。在一個可能受 Perl 啟發的特性中,大括號 (
{}) 可以替換單個引數串列周圍的括號。這個特性促進了在呼叫站點看起來非常像 C 的語法:
// NB: doesn't support early exit (except by throwing an exception...)
def myWhile(condition: => Boolean)(body: => Unit): Unit = {
@annotation.tailrec
def spin: Unit =
if (condition) {
body
spin
} else ()
spin
}
var x: Int = 0
myWhile (x < 4) {
println("whee!")
x = 1
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/440182.html
