Scala Language
Hogere orderfunctie
Zoeken…
Opmerkingen
Scala doet er alles aan om methoden en functies als syntactisch identiek te behandelen. Maar onder de motorkap zijn het verschillende concepten.
Een methode is uitvoerbare code en heeft geen waardepresentatie.
Een functie is een werkelijke objectinstantie van het type Function1
(of een vergelijkbaar type van een andere arity). De code is opgenomen in de methode van apply
. In feite fungeert het gewoon als een waarde die kan worden doorgegeven.
Overigens is de mogelijkheid behandelen functioneert als waarden wat wordt bedoeld met een taal met ondersteuning voor hogere orde functies. Functie-instanties zijn Scala's benadering van het implementeren van deze functie.
Een werkelijke functie van hogere orde is een functie die een functiewaarde als argument neemt of een functiewaarde retourneert. Maar in Scala, omdat alle bewerkingen methoden zijn, is het algemener om te denken aan methoden die functieparameters ontvangen of retourneren. Dus map
, zoals gedefinieerd op Seq
kan worden gezien als een "hogere orde functie" vanwege de parameter die een functie is, maar het is niet letterlijk een functie; het is een methode.
Methoden gebruiken als functiewaarden
De Scala-compiler converteert methoden automatisch naar functiewaarden om ze door te geven aan functies van een hogere orde.
object MyObject {
def mapMethod(input: Int): String = {
int.toString
}
}
Seq(1, 2, 3).map(MyObject.mapMethod) // Seq("1", "2", "3")
In het bovenstaande voorbeeld is MyObject.mapMethod
geen functieaanroep, maar in plaats daarvan doorgegeven aan map
als een waarde. Inderdaad, map
vereist een functie waarde die eraan is doorgegeven, zoals te zien is in zijn handtekening. De handtekening voor de map
van een List[A]
(een lijst met objecten van type A
) is:
def map[B](f: (A) ⇒ B): List[B]
Het gedeelte f: (A) => B
geeft aan dat de parameter voor deze methode-aanroep een functie is die een object van type A
en een object van type B
retourneert. A
en B
zijn willekeurig gedefinieerd. Terugkerend naar het eerste voorbeeld, kunnen we zien dat mapMethod
een Int
(die overeenkomt met A
) en een String
retourneert (die overeenkomt met B
). Zo is mapMethod
een geldige functiewaarde die aan map
moet worden doorgegeven. We kunnen dezelfde code als volgt herschrijven:
Seq(1, 2, 3).map(x:Int => int.toString)
Dit onderstreept de functiewaarde, wat duidelijkheid kan toevoegen voor eenvoudige functies.
Hoge orderfuncties (functie als parameter)
Een hogere-orde functie, in tegenstelling tot een eerste-orde functie, kan een van drie vormen hebben:
Een of meer van zijn parameters is een functie en geeft een waarde terug.
Het retourneert een functie, maar geen van de parameters is een functie.
Beide bovenstaande: een of meer van zijn parameters is een functie en retourneert een functie.
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 }
Hier neemt de getFullName(n._1,n._2)
de functie getFullName(n._1,n._2)
als parameter. Dit wordt HOF (hogere orde functie) genoemd.
Argumenten luie evaluatie
Scala ondersteunt luie evaluatie voor functieargumenten met behulp van notatie: def func(arg: => String)
. Een dergelijk functieargument kan een normaal String
object of een hogere orde-functie met String
retourtype aannemen. In het tweede geval zou het functieargument worden geëvalueerd op waardetoegang.
Zie het voorbeeld:
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
oproep zou geen waarde retourneren en het bericht "Applying mediator"
afdrukken.
dumbMediator
oproep zou geen waarde retourneren en het bericht "Calculating expensive data! Applying mediator"
afdrukken.
Luie evaluatie kan zeer nuttig zijn wanneer u een overhead van dure argumentenberekening wilt optimaliseren.