Zoeken…


Syntaxis

  • foreach (f, xs)
  • kaart (f, xs)
  • filter (f, xs)
  • verkleinen (f, v0, xs)
  • vouw (f, v0, xs)
  • foldr (f, v0, xs)

Opmerkingen

Functies kunnen worden geaccepteerd als parameters en kunnen ook worden geproduceerd als retourtypen. Inderdaad, functies kunnen worden gecreëerd in het lichaam van andere functies. Deze innerlijke functies staan bekend als sluitingen .

Functies als argumenten

Functies zijn objecten in Julia. Net als alle andere objecten kunnen ze als argumenten aan andere functies worden doorgegeven. Functies die functies accepteren, worden functies van een hogere orde genoemd .

We kunnen bijvoorbeeld een equivalent van de foreach functie van de standaardbibliotheek implementeren door een functie f als eerste parameter te nemen.

function myforeach(f, xs)
    for x in xs
        f(x)
    end
end

We kunnen testen dat deze functie inderdaad werkt zoals we verwachten:

julia> myforeach(println, ["a", "b", "c"])
a
b
c

Door een functie als eerste parameter te nemen, in plaats van een latere parameter, kunnen we de do block-syntaxis van Julia gebruiken. De do block-syntaxis is slechts een handige manier om een anonieme functie door te geven als het eerste argument voor een functie.

julia> myforeach([1, 2, 3]) do x
           println(x^x)
       end
1
4
27

Onze bovenstaande implementatie van myforeach is ongeveer gelijk aan de ingebouwde foreach functie. Veel andere ingebouwde functies van hogere orde bestaan ook.

Hogere-orde functies zijn behoorlijk krachtig. Soms, wanneer u met functies van een hogere orde werkt, worden de exacte bewerkingen die worden uitgevoerd onbelangrijk en kunnen programma's vrij abstract worden. Combinators zijn voorbeelden van systemen met zeer abstracte functies van hogere orde.

In kaart brengen, filteren en verkleinen

Twee van de meest fundamentele functies van hogere orde in de standaardbibliotheek zijn map en filter . Deze functies zijn generiek en kunnen op elke iterabele manier worden gebruikt . In het bijzonder zijn ze goed geschikt voor berekeningen op arrays .

Stel dat we een dataset van scholen hebben. Elke school geeft een bepaald vak, heeft een aantal klassen en een gemiddeld aantal studenten per klas. We kunnen een school modelleren met het volgende onveranderlijke type :

immutable School
    subject::Symbol
    nclasses::Int
    nstudents::Int  # average no. of students per class
end

Onze dataset van scholen wordt een Vector{School} :

dataset = [School(:math, 3, 30), School(:math, 5, 20), School(:science, 10, 5)]

Stel dat we het totale aantal studenten willen vinden dat is ingeschreven voor een wiskundeprogramma. Om dit te doen, hebben we verschillende stappen nodig:

  • we moeten de dataset beperken tot alleen scholen die wiskunde onderwijzen ( filter )
  • we moeten het aantal studenten op elke school berekenen ( map )
  • en we moeten die lijst met studenten terugbrengen tot een enkele waarde, de som ( reduce )

Een naïeve (niet de meest performante) oplossing zou gewoon zijn om die drie functies van hogere orde direct te gebruiken.

function nmath(data)
    maths = filter(x -> x.subject === :math, data)
    students = map(x -> x.nclasses * x.nstudents, maths)
    reduce(+, 0, students)
end

en we controleren of er 190 wiskundestudenten in onze dataset zitten:

julia> nmath(dataset)
190

Er zijn functies om deze functies te combineren en zo de prestaties te verbeteren. We hadden bijvoorbeeld de mapreduce functie kunnen gebruiken om de mapping en reductie in één stap uit te voeren, wat tijd en geheugen zou besparen.

De reduce is alleen zinvol voor associatieve bewerkingen zoals + , maar soms is het nuttig om een reductie uit te voeren met een niet-associatieve bewerking. De hogere-orde functies foldl en foldr zijn aanwezig om een bepaalde reductie-volgorde te forceren.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow