Haskell Language
Składnia wywołania funkcji
Szukaj…
Wprowadzenie
Składnia wywołania funkcji Haskella, wyjaśniona w stosownych przypadkach w porównaniu do języków w stylu C. Jest to skierowane do osób, które przyjeżdżają do Haskell z doświadczenia w językach w stylu C.
Uwagi
Ogólnie rzecz biorąc, zasadą konwertowania wywołania funkcji w stylu C na Haskell, w dowolnym kontekście (przypisanie, powrót lub osadzenie w innym wywołaniu), jest zastąpienie przecinków na liście argumentów w stylu C spacjami i przesunięcie otwarcia nawias od wywołania w stylu C, zawierający nazwę funkcji i jej parametry.
Jeśli jakieś wyrażenia są całkowicie owinięte w nawiasach, te (zewnętrzne) pary nawiasów można usunąć dla ich czytelności, ponieważ nie wpływają one na znaczenie wyrażenia.
Istnieją inne okoliczności, w których można usunąć nawiasy, ale wpływa to tylko na czytelność i łatwość konserwacji.
Nawiasy w podstawowym wywołaniu funkcji
W przypadku wywołania funkcji w stylu C, np
plus(a, b); // Parentheses surrounding only the arguments, comma separated
Wówczas będzie równoważny kod Haskell
(plus a b) -- Parentheses surrounding the function and the arguments, no commas
W Haskell nawiasy nie są jawnie wymagane do zastosowania funkcji i służą jedynie do jednoznacznego wyrażenia, jak w matematyce; więc w przypadkach, gdy nawiasy otaczają cały tekst w wyrażeniu, nawiasy nie są w rzeczywistości potrzebne, a poniższe jest również równoważne:
plus a b -- no parentheses are needed here!
Ważne jest, aby pamiętać, że w językach w stylu C funkcja ta jest dostępna
Nawiasy w wbudowanych wywołaniach funkcji
W poprzednim przykładzie nie potrzebowaliśmy nawiasów, ponieważ nie wpłynęły one na znaczenie instrukcji. Często są one jednak konieczne w bardziej złożonym wyrażeniu, takim jak ten poniżej.
W C:
plus(a, take(b, c));
W Haskell staje się to:
(plus a (take b c))
-- or equivalently, omitting the outermost parentheses
plus a (take b c)
Pamiętaj, że nie jest to równoważne z:
plus a take b c -- Not what we want!
Można by pomyśleć, że ponieważ kompilator wie, że take
jest funkcją, wiedziałby, że chcesz zastosować ją do argumentów b
i c
, i przekazać jej wynik na plus
.
Jednak w Haskell funkcje często przyjmują inne funkcje za argumenty, a rzeczywiste rozróżnienie między funkcjami a innymi wartościami jest niewielkie; a więc kompilator nie może założyć twojej intencji po prostu dlatego, że take
jest funkcją.
Tak więc ostatni przykład jest analogiczny do następującego wywołania funkcji C:
plus(a, take, b, c); // Not what we want!
Częściowe zastosowanie - część 1
W Haskell funkcje można częściowo zastosować; możemy myśleć o wszystkich funkcjach jako o pobieraniu pojedynczego argumentu i zwracaniu zmodyfikowanej funkcji, dla której ten argument jest stały. Aby to zilustrować, możemy podzielić funkcje w następujący sposób:
(((plus) 1) 2)
Tutaj funkcja (plus)
jest stosowana do 1
uzyskując funkcję ((plus) 1)
, która jest stosowana do 2
, dając funkcję (((plus) 1) 2)
. Ponieważ plus 1 2
jest funkcją, która nie przyjmuje argumentów, możesz uznać ją za zwykłą wartość; jednak w Haskell rozróżnienie między funkcjami a wartościami jest niewielkie.
Aby uzyskać więcej szczegółów, funkcja plus
to funkcja, która dodaje swoje argumenty.
Funkcja plus 1
to funkcja, która dodaje 1
do argumentu.
Funkcja plus 1 2
to funkcja, która dodaje 1
do 2
, czyli zawsze wartość 3
.
Częściowe zastosowanie - część 2
Jako kolejny przykład mamy map
funkcji, która pobiera funkcję i listę wartości i stosuje tę funkcję do każdej wartości listy:
map :: (a -> b) -> [a] -> [b]
Powiedzmy, że chcemy zwiększyć każdą wartość na liście. Możesz zdecydować o zdefiniowaniu własnej funkcji, która dodaje jedną z jej argumentów i map
tę funkcję na twojej liście
addOne x = plus 1 x
map addOne [1,2,3]
ale jeśli spojrzysz na definicję addOne
z nawiasami dodanymi dla podkreślenia:
(addOne) x = ((plus) 1) x
Funkcja addOne
, zastosowana do dowolnej wartości x
, jest taka sama jak funkcja częściowo zastosowana plus 1
zastosowana do x
. Oznacza to, że funkcje addOne
i plus 1
są identyczne i możemy uniknąć zdefiniowania nowej funkcji, po prostu zastępując addOne
plus 1
, pamiętając o użyciu nawiasów w celu wyodrębnienia plus 1
jako podwyrażenie:
map (plus 1) [1,2,3]