Scala Language
Funktion för högre ordning
Sök…
Anmärkningar
Scala strävar mycket efter att behandla metoder och funktioner som syntaktiskt identiska. Men under huven är de distinkta begrepp.
En metod är körbar kod och har inget värderepresentation.
En funktion är en verklig objektinstans av typen Function1
(eller en liknande typ av en annan arity). Dess kod finns i dess apply
. Effektivt fungerar det helt enkelt som ett värde som kan överföras.
Förresten, förmågan att behandla funktioner som värden är exakt vad som menas med ett språk som har stöd för funktioner med högre ordning. Funktionsinstanser är Skalas sätt att implementera denna funktion.
En faktisk funktion med högre ordning är en funktion som antingen tar ett funktionsvärde som ett argument eller returnerar ett funktionsvärde. Men i Scala, eftersom alla operationer är metoder, är det mer generellt att tänka på metoder som tar emot eller returnerar funktionsparametrar. Så map
, som definierats på Seq
kan tänkas vara en "funktion av högre ordning" på grund av att dess parameter är en funktion, men det är inte bokstavligen en funktion; det är en metod.
Använda metoder som funktionsvärden
Scala-kompilatorn konverterar automatiskt metoder till funktionsvärden för att överföra dem till högre ordning.
object MyObject {
def mapMethod(input: Int): String = {
int.toString
}
}
Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")
I exemplet ovan är MyObject.mapMethod
inte ett funktionssamtal utan skickas istället till map
som ett värde. I själva verket kräver map
ett funktionsvärde som skickas till det, vilket kan ses i dess signatur. Signaturen för map
över en List[A]
(en lista med objekt av typ A
) är:
def map[B](f: (A) ⇒ B): List[B]
f: (A) => B
delen indikerar att parametern till det här metodsamtalet är en funktion som tar ett objekt av typ A
och returnerar ett objekt av typ B
A
och B
definieras godtyckligt. Återgå till det första exemplet kan vi se att mapMethod
tar en Int
(som motsvarar A
) och returnerar en String
(som motsvarar B
). Således är mapMethod
ett giltigt funktionsvärde att överföra till map
. Vi kan skriva om samma kod så här:
Seq(1, 2, 3).map(x:Int => int.toString)
Detta sammanfattar funktionsvärdet, vilket kan lägga till tydlighet för enkla funktioner.
Högordningsfunktioner (funktion som parameter)
En funktion med högre ordning, i motsats till en första ordningsfunktion, kan ha en av tre former:
En eller flera av dess parametrar är en funktion, och den returnerar något värde.
Den returnerar en funktion, men ingen av dess parametrar är en funktion.
Båda ovanstående: En eller flera av dess parametrar är en funktion och den returnerar en funktion.
object HOF { def main(args: Array[String]) { val list = List(("Srini","E"),("Subash","R"),("Ranjith","RK"),("Vicky","s"),("Sudhar","s")) //HOF val fullNameList= list.map(n => getFullName(n._1, n._2)) } def getFullName(firstName: String, lastName: String): String = firstName + "." + lastName }
Här tar getFullName(n._1,n._2)
en getFullName(n._1,n._2)
-funktion som en parameter. Detta kallas HOF (Högre ordningsfunktion).
Argumenterar lat utvärdering
Scala stöder lat utvärdering av funktionsargument med notation: def func(arg: => String)
. Ett sådant funktionsargument kan ta ett vanligt String
objekt eller en högre ordningsfunktion med String
returtyp. I det andra fallet skulle funktionsargument utvärderas på värdeåtkomst.
Se exemplet:
def calculateData: String = {
print("Calculating expensive data! ")
"some expensive data"
}
def dumbMediator(preconditions: Boolean, data: String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
def smartMediator(preconditions: Boolean, data: => String): Option[String] = {
print("Applying mediator")
preconditions match {
case true => Some(data)
case false => None
}
}
smartMediator(preconditions = false, calculateData)
dumbMediator(preconditions = false, calculateData)
smartMediator
samtalet skulle returnera Inget värde och skriva ut meddelandet "Applying mediator"
.
dumbMediator
samtalet skulle returnera Inget värde och skriva ut meddelandet "Calculating expensive data! Applying mediator"
.
Lat utvärdering kan vara oerhört användbar när du vill optimera en omkostnad för beräkning av dyra argument.