Haskell Language
Syntaxis van functieoproepen
Zoeken…
Invoering
Haskell's functie-oproepsyntaxis, uitgelegd met vergelijkingen met C-stijl talen waar van toepassing. Dit is bedoeld voor mensen die naar Haskell komen vanuit een achtergrond in C-stijl talen.
Opmerkingen
Over het algemeen is de regel voor het converteren van een functieaanroep in C-stijl naar Haskell, in elke context (toewijzing, terugkeer of ingebed in een andere aanroep), om de komma's in de argumentlijst in C-stijl te vervangen door witruimte en de opening te verplaatsen haakjes van de aanroep in C-stijl om de functienaam en de bijbehorende parameters te bevatten.
Als expressies volledig tussen haakjes zijn ingepakt, kunnen deze (externe) haakjesparen worden verwijderd voor leesbaarheid, omdat ze de betekenis van de expressie niet beïnvloeden.
Er zijn enkele andere omstandigheden waarin haakjes kunnen worden verwijderd, maar dit heeft alleen invloed op de leesbaarheid en onderhoudbaarheid.
Haakjes in een basisfunctieaanroep
Voor een functieoproep in C-stijl, bijv
plus(a, b); // Parentheses surrounding only the arguments, comma separated
Dan is de equivalente Haskell-code
(plus a b) -- Parentheses surrounding the function and the arguments, no commas
In Haskell zijn haakjes niet expliciet vereist voor functietoepassing en worden alleen gebruikt om uitdrukkingen eenduidig te maken, zoals in de wiskunde; dus in gevallen waarin de haakjes alle tekst in de uitdrukking omringen, zijn de haakjes eigenlijk niet nodig en het volgende is ook equivalent:
plus a b -- no parentheses are needed here!
Het is belangrijk om te onthouden dat, in C-stijltalen, de functie
Haakjes in ingesloten functieaanroepen
In het vorige voorbeeld hadden we de haakjes niet nodig, omdat ze de betekenis van de verklaring niet beïnvloedden. Ze zijn echter vaak nodig in een meer complexe uitdrukking, zoals die hieronder.
In C:
plus(a, take(b, c));
In Haskell wordt dit:
(plus a (take b c))
-- or equivalently, omitting the outermost parentheses
plus a (take b c)
Merk op dat dit niet gelijk is aan:
plus a take b c -- Not what we want!
Je zou kunnen denken dat omdat de compiler weet dat take
een functie is, hij zou kunnen weten dat je hem op de argumenten b
en c
wilt toepassen en het resultaat wilt doorgeven aan plus
.
In Haskell nemen functies echter vaak andere functies als argumenten en wordt er eigenlijk weinig onderscheid gemaakt tussen functies en andere waarden; en dus kan de compiler uw intentie niet aannemen, simpelweg omdat take
een functie is.
En dus is het laatste voorbeeld analoog aan de volgende C-functie-aanroep:
plus(a, take, b, c); // Not what we want!
Gedeeltelijke toepassing - Deel 1
In Haskell kunnen functies gedeeltelijk worden toegepast; we kunnen denken dat alle functies een enkel argument aannemen en een gewijzigde functie retourneren waarvoor dat argument constant is. Om dit te illustreren, kunnen we functies als volgt koppelen:
(((plus) 1) 2)
Hier wordt de functie (plus)
toegepast op 1
wat de functie oplevert ((plus) 1)
, die wordt toegepast op 2
, waardoor de functie (((plus) 1) 2)
. Omdat plus 1 2
een functie is waarvoor geen argumenten nodig zijn, kunt u het als een gewone waarde beschouwen; in Haskell is er echter weinig onderscheid tussen functies en waarden.
Om meer in detail te gaan, is de functie plus
een functie die zijn argumenten toevoegt.
De functie plus 1
is een functie die 1
toevoegt aan het argument.
De functie plus 1 2
is een functie die 1
tot 2
toevoegt, wat altijd de waarde 3
.
Gedeeltelijke toepassing - Deel 2
Een ander voorbeeld: we hebben de functie map
, die een functie en een lijst met waarden neemt, en de functie is van toepassing op elke waarde van de lijst:
map :: (a -> b) -> [a] -> [b]
Laten we zeggen dat we elke waarde in een lijst willen verhogen. U kunt besluiten om je eigen functie, die men toevoegt aan haar betoog te definiëren en map
die functie over uw lijst
addOne x = plus 1 x
map addOne [1,2,3]
maar als je de definitie van addOne
nog eens bekijkt, met nadruk tussen haakjes:
(addOne) x = ((plus) 1) x
De functie addOne
, wanneer toegepast op elke waarde x
, hetzelfde als de gedeeltelijk toegepaste functie plus 1
toegepast op x
. Dit betekent dat de functies addOne
en plus 1
identiek zijn, en we kunnen voorkomen dat we een nieuwe functie definiëren door addOne
vervangen door plus 1
, waarbij we onthouden om haakjes te gebruiken om plus 1
te isoleren als een subexpressie:
map (plus 1) [1,2,3]