Co to jest lambda (funkcja)?

743

Dla osoby bez wykształcenia specjalistycznego, czym jest lambda w świecie informatyki?

Brian Warshaw
źródło
3
Wyrażenie amda wyjaśnione tutaj pięknie.
Jameer Mulani,
1
zobaczyć to na jak lambda funkcje wyglądają w różnych językach, a co roku zostały one wprowadzone w tych językach.
Philip Schwarz

Odpowiedzi:

1081

Lambda pochodzi z Lambda Calculus i odnosi się do anonimowych funkcji w programowaniu.

Dlaczego to jest fajne? Pozwala pisać funkcje szybkiego wyrzucania bez nazywania ich. To także dobry sposób na pisanie zamknięć. Dzięki tej mocy możesz robić takie rzeczy.

Pyton

def adder(x):
    return lambda y: x + y
add5 = adder(5)
add5(1)
6

Jak widać z fragmentu Pythona, sumator funkcji przyjmuje argument x i zwraca funkcję anonimową lub lambda, która przyjmuje inny argument y. Ta anonimowa funkcja umożliwia tworzenie funkcji na podstawie funkcji. Jest to prosty przykład, ale powinien przekazać moc lambdas i zamknięć.

Przykłady w innych językach

Perl 5

sub adder {
    my ($x) = @_;
    return sub {
        my ($y) = @_;
        $x + $y
    }
}

my $add5 = adder(5);
print &$add5(1) == 6 ? "ok\n" : "not ok\n";

JavaScript

var adder = function (x) {
    return function (y) {
        return x + y;
    };
};
add5 = adder(5);
add5(1) == 6

JavaScript (ES6)

const adder = x => y => x + y;
add5 = adder(5);
add5(1) == 6

Schemat

(define adder
    (lambda (x)
        (lambda (y)
           (+ x y))))
(define add5
    (adder 5))
(add5 1)
6

C # 3.5 lub wyższy

Func<int, Func<int, int>> adder = 
    (int x) => (int y) => x + y; // `int` declarations optional
Func<int, int> add5 = adder(5);
var add6 = adder(6); // Using implicit typing
Debug.Assert(add5(1) == 6);
Debug.Assert(add6(-1) == 5);

// Closure example
int yEnclosed = 1;
Func<int, int> addWithClosure = 
    (x) => x + yEnclosed;
Debug.Assert(addWithClosure(2) == 3);

Szybki

func adder(x: Int) -> (Int) -> Int{
   return { y in x + y }
}
let add5 = adder(5)
add5(1)
6

PHP

$a = 1;
$b = 2;

$lambda = fn () => $a + $b;

echo $lambda();

Haskell

(\x y -> x + y) 

Java zobacz ten post

// The following is an example of Predicate : 
// a functional interface that takes an argument 
// and returns a boolean primitive type.

Predicate<Integer> pred = x -> x % 2 == 0; // Tests if the parameter is even.
boolean result = pred.test(4); // true

Lua

adder = function(x)
    return function(y)
        return x + y
    end
end
add5 = adder(5)
add5(1) == 6        -- true

Kotlin

val pred = { x: Int -> x % 2 == 0 }
val result = pred(4) // true

Rubin

Ruby różni się nieco tym, że nie można wywoływać lambda przy użyciu dokładnie takiej samej składni, jak wywoływanie funkcji, ale nadal ma lambdy.

def adder(x)
  lambda { |y| x + y }
end
add5 = adder(5)
add5[1] == 6

Ruby jako Ruby, istnieje skrót dla lambdas, więc możesz zdefiniować w adderten sposób:

def adder(x)
  -> y { x + y }
end

R

adder <- function(x) {
  function(y) x + y
}
add5 <- adder(5)
add5(1)
#> [1] 6
mk.
źródło
3
Jaka jest zatem różnica między funkcją lambda a funktorem ?
Maks.
1
@Maxpm funktor może być standardowym obiektem z polami i funkcjami instancji, podczas gdy funkcja lambda zasadniczo składa się tylko z jednej linii instrukcji. Oczywiście może się to różnić w zależności od języka.
zdimension 20.04.2018
1
Nie sądzę, że koniecznie poprawne jest stwierdzenie, że funkcje lambda są takie same jak funkcje anonimowe. W niektórych językach, takich jak JavaScript, wyrażenie lambda jest specyficzną formą anonimowej funkcji. Podany przykład JavaScript to anonimowa funkcja bez składni lambda, natomiast podany przykład JavaScript (ES6) to wyrażenie lambda.
Kyle Delaney
1
@KyleDelaney rzeczywiście anonimowy nie jest koniecznym warunkiem bycia lambda, w rzeczywistości istnieją funkcje lambda, które nie są anonimowe, jak
wskazano
@AliAnkarali lub przyzwyczaić się do korzystania z rubys lambda;)
Jimmy MG Lim
107

Lambda jest rodzajem funkcji zdefiniowanym wewnętrznie. Wraz z lambda zwykle masz też pewien rodzaj zmiennej zmiennej, która może zawierać odniesienie do funkcji, lambda lub innej.

Na przykład, oto fragment kodu C #, który nie używa lambda:

public Int32 Add(Int32 a, Int32 b)
{
    return a + b;
}

public Int32 Sub(Int32 a, Int32 b)
{
    return a - b;
}

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, Add);
    Calculator(10, 23, Sub);
}

To wywołuje Kalkulator, przekazując nie tylko dwie liczby, ale także metodę wywoływania wewnątrz Kalkulatora w celu uzyskania wyników obliczeń.

W C # 2.0 mamy anonimowe metody, które skracają powyższy kod do:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a + b;
    });
    Calculator(10, 23, delegate(Int32 a, Int32 b)
    {
        return a - b;
    });
}

A potem w C # 3.0 mamy lambdas, co czyni kod jeszcze krótszym:

public delegate Int32 Op(Int32 a, Int32 b);

public void Calculator(Int32 a, Int32 b, Op op)
{
    Console.WriteLine("Calculator: op(" + a + ", " + b + ") = " + op(a, b));
}

public void Test()
{
    Calculator(10, 23, (a, b) => a + b);
    Calculator(10, 23, (a, b) => a - b);
}
Lasse V. Karlsen
źródło
Zamiast wyraźnego zdefiniowania delegata Op, można po prostu użyćFunc<int, int>
Mateen Ulhaq
Sugerowałbym Console.WriteLine("Calculator: op " + op.Method.Name + " (" + a + ", " + b + ") = " + op(a, b));pierwszy przykład.
Marc.2377
Choć odpowiedź jest tak niesamowita, jak pomoc ludziom w wielu różnych językach, wydaje mi się, że ta odpowiedź pomaga mi lepiej zrozumieć zalety lambdas i odróżnić je od standardowej funkcji. Widzę tutaj wyraźnie przewagę lambda nad poprzednimi metodami uzyskiwania podobnego rezultatu.
RTHarston
Dziękuję za twój przykład, posiadanie bardziej złożonej funkcji pomaga znacznie lepiej zrozumieć zalety lambdas niż proste funkcje, w których wygląda na to, że nie uzyskujesz dużej optymalizacji
Sarah
71

Nazwa „lambda” jest tylko historycznym artefaktem. Mówimy tylko o wyrażeniu, którego wartość jest funkcją.

Prostym przykładem (użycie Scali do następnego wiersza) jest:

args.foreach(arg => println(arg))

gdzie argumentem foreachmetody jest wyrażenie dla funkcji anonimowej. Powyższa linia jest mniej więcej taka sama jak pisanie czegoś takiego (niezupełnie prawdziwy kod, ale wpadniesz na pomysł):

void printThat(Object that) {
  println(that)
}
...
args.foreach(printThat)

poza tym, że nie musisz zawracać sobie głowy:

  1. Zadeklarowanie funkcji gdzie indziej (i poszukiwanie jej przy ponownym odwiedzeniu kodu).
  2. Nazywanie czegoś, z czego korzystasz tylko raz.

Kiedy już przyzwyczaisz się do funkcji wartości, rezygnacja z nich wydaje się równie głupie, jak wymawianie nazw wszystkich wyrażeń, takich jak:

int tempVar = 2 * a + b
...
println(tempVar)

zamiast pisać wyrażenie tam, gdzie jest ono potrzebne:

println(2 * a + b)

Dokładna notacja różni się w zależności od języka; Grecki nie zawsze jest wymagany! ;-)

joel.neely
źródło
62

Odnosi się do rachunku lambda , który jest systemem formalnym, który ma tylko wyrażenia lambda, które reprezentują funkcję, która przyjmuje funkcję za swój jedyny argument i zwraca funkcję. Wszystkie funkcje w rachunku lambda są tego typu, tj λ : λ → λ.

Lisp użył pojęcia lambda do nazwania swoich anonimowych literałów funkcji. Ta lambda reprezentuje funkcję, która przyjmuje dwa argumenty, xiy, i zwraca ich produkt:

(lambda (x y) (* x y)) 

Można go zastosować w linii w ten sposób (ocenia na 50 ):

((lambda (x y) (* x y)) 5 10)
Mark Cidade
źródło
Myślę, że twoje użycie λ : λ -> λjest mylące (i faktycznie nieważne).
einpoklum
51

Rachunek lambda jest spójną matematyczną teorią podstawienia. W szkolnej matematyce widzi się na przykład w x+y=5połączeniu z x−y=1. Wraz ze sposobami manipulowania poszczególnymi równaniami można również łączyć informacje z tych dwóch razem, pod warunkiem, że podstawienia równania krzyżowego są wykonywane logicznie. Rachunek lambda kodyfikuje prawidłowy sposób dokonywania tych zamian.

Biorąc pod uwagę, że y = x−1jest to poprawna zmiana drugiego równania, λ y = x−1oznacza to: funkcję zastępującą symbole x−1symbolem y. Teraz wyobraź sobie, że możesz zastosować λ ydo każdego terminu w pierwszym równaniu. Jeśli termin jest ynastępnie, wykonaj podstawienie; w przeciwnym razie nic nie rób. Jeśli zrobisz to na papierze, zobaczysz, jak to zastosowaćλ y sprawi, że pierwsze równanie będzie możliwe do rozwiązania.

To odpowiedź bez informatyki i programowania.

Najprostszy przykład programowania, jaki mogę wymyślić, pochodzi z http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works :

oto jak można zdefiniować funkcję kwadratu w imperatywnym języku programowania (C):

int square(int x)
{
    return x * x;
}

Zmienna x jest parametrem formalnym, który jest zastępowany rzeczywistą wartością do podniesienia do kwadratu po wywołaniu funkcji. W języku funkcjonalnym (Schemacie) zdefiniowano by tę samą funkcję:

(define square
  (lambda (x) 
    (* x x)))

Różni się to na wiele sposobów, ale nadal używa parametru formalnego x w ten sam sposób.


Dodano: http://imgur.com/a/XBHub

lambda

izomorfizmy
źródło
14

Nieco uproszczone: funkcja lambda to taka, którą można przekazać do innych funkcji i uzyskać dostęp do logiki.

W języku C # składnia lambda jest często kompilowana do prostych metod w taki sam sposób, jak anonimowi delegaci, ale można ją również rozbić i odczytać jej logikę.

Na przykład (w C # 3):

LinqToSqlContext.Where( 
    row => row.FieldName > 15 );

LinqToSql może odczytać tę funkcję (x> 15) i przekonwertować ją na rzeczywisty SQL w celu wykonania za pomocą drzew wyrażeń.

Powyższe oświadczenie staje się:

select ... from [tablename] 
where [FieldName] > 15      --this line was 'read' from the lambda function

Różni się to od zwykłych metod lub anonimowych delegatów (które są tak naprawdę magią kompilatora), ponieważ nie można ich odczytać .

Nie wszystkie metody w języku C #, które używają składni lambda, można skompilować do drzew wyrażeń (tj. Rzeczywistych funkcji lambda). Na przykład:

LinqToSqlContext.Where( 
    row => SomeComplexCheck( row.FieldName ) );

Teraz nie można odczytać drzewa wyrażeń - SomeComplexCheck nie może zostać rozbity. Instrukcja SQL zostanie wykonana bez gdzie, a każdy wiersz w danych zostanie wprowadzony SomeComplexCheck.

Funkcji Lambda nie należy mylić z metodami anonimowymi. Na przykład:

LinqToSqlContext.Where( 
    delegate ( DataRow row ) { 
        return row.FieldName > 15; 
    } );

Ma również funkcję „wbudowaną”, ale tym razem jest to po prostu magia kompilatora - kompilator C # podzieli to na nową metodę instancji z automatycznie generowaną nazwą.

Nie można odczytać anonimowych metod, więc logika nie może zostać przetłumaczona tak jak w przypadku funkcji lambda.

Keith
źródło
7

Podoba mi się wyjaśnienie Lambdas w tym artykule: Ewolucja LINQ i jej wpływ na projekt C # . Ma to dla mnie wiele sensu, ponieważ pokazuje prawdziwy świat dla Lambdas i buduje go jako praktyczny przykład.

Szybkie wyjaśnienie: Lambda to sposób na traktowanie kodu (funkcji) jako danych.

Jon Galloway
źródło
7

Przykład lambda w Ruby jest następujący:

hello = lambda do
    puts('Hello')
    puts('I am inside a proc')
end

hello.call

Wygeneruje następujące dane wyjściowe:

Hello
I am inside a proc
CodingWithoutComments
źródło
5

@Brian Cały czas używam lambd w C #, w operatorach LINQ i innych niż LINQ. Przykład:

string[] GetCustomerNames(IEnumerable<Customer> customers)
 { return customers.Select(c=>c.Name);
 }

Przed C # użyłem anonimowych funkcji w JavaScript do wywołań zwrotnych funkcji AJAX, zanim jeszcze stworzono termin Ajax:

getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});

Interesującą rzeczą w składni lambda C # jest to, że same nie mogą być wpisane do ich typu (tzn. Nie można wpisać var ​​foo = (x, y) => x * y), ale w zależności od typu przypisane do nich zostaną skompilowane jako delegaty lub abstrakcyjne drzewa składniowe reprezentujące wyrażenie (w ten sposób mapujący obiekty LINQ wykonują swoją magię „zintegrowaną z językiem”).

Lambdas w LISP można również przekazać do operatora oferty, a następnie przejść jako listę list. Niektóre potężne makra są tworzone w ten sposób.

Mark Cidade
źródło
5

Odpowiedź na to pytanie jest bardzo formalna, więc nie będę próbował dodawać więcej na ten temat.

W bardzo prostych, nieformalnych słowach do kogoś, kto niewiele wie lub nic nie zna matematyki ani programowania, wytłumaczyłbym to jako małą „maszynę” lub „skrzynkę”, która pobiera dane wejściowe, działa i generuje dane wyjściowe, nie ma konkretnej nazwy , ale wiemy, gdzie to jest i dzięki tej wiedzy korzystamy z niej.

Praktycznie rzecz biorąc, dla osoby, która wie, co to jest funkcja, powiedziałbym jej, że jest to funkcja bez nazwy, zwykle umieszczona w pamięci, do której można się odwołać po prostu przez odwołanie się do tej pamięci (zwykle poprzez użycie zmienna - jeśli usłyszeli o koncepcji wskaźników funkcji, użyłbym ich jako podobnej koncepcji) - ta odpowiedź obejmuje ładne podstawy (bez wzmianki o zamknięciach itp.), ale można łatwo zdobyć punkt.

Nick Louloudakis
źródło
4

Tylko dlatego, że nie widzę tutaj przykładu w C ++ 11, napiszę ten miły przykład stąd . Po przeszukaniu jest to najczystszy przykład, jaki mogłem znaleźć w języku.

Witaj, Lambdas, wersja 1

template<typename F>

void Eval( const F& f ) {
        f();
}
void foo() {
        Eval( []{ printf("Hello, Lambdas\n"); } );
}

Witaj, Lambdas, wersja 2:

void bar() {
    auto f = []{ printf("Hello, Lambdas\n"); };
    f();
}
learnvst
źródło
3

Mam problem z owinięciem głowy wyrażeniami lambda, ponieważ pracuję w programie Visual FoxPro, który ma podstawienie makr oraz funkcje ExecScript {} i Evaluate (), które wydają się służyć temu samemu celowi.

? Calculator(10, 23, "a + b")
? Calculator(10, 23, "a - b");

FUNCTION Calculator(a, b, op)
RETURN Evaluate(op)

Jedną wyraźną korzyścią z używania formalnych lambdas jest (zakładam) sprawdzanie czasu kompilacji: Fox nie będzie wiedział, czy literówka powyżej, dopóki nie spróbuje go uruchomić.

Jest to również przydatne w przypadku kodu opartego na danych: możesz przechowywać całe procedury w polach notatek w bazie danych, a następnie po prostu je oceniać w czasie wykonywania. Pozwala to na dostosowanie części aplikacji bez faktycznego dostępu do źródła. (Ale to zupełnie inny temat.)

SarekOfVulcan
źródło
3

Dla osoby bez wykształcenia specjalistycznego, czym jest lambda w świecie informatyki?

Zilustruję go intuicyjnie krok po kroku w prostych i czytelnych kodach Pythona.

Krótko mówiąc, lambda jest po prostu anonimową i wbudowaną funkcją.

Zacznijmy od zadania, aby zrozumieć lambdasjako student pierwszego roku z podstawową arytmetyką.

Plan przypisania to „nazwa = wartość”, patrz:

In [1]: x = 1
   ...: y = 'value'
In [2]: x
Out[2]: 1
In [3]: y
Out[3]: 'value'

„x”, „y” to nazwy, a 1, „wartość” to wartości. Wypróbuj funkcję w matematyce

In [4]: m = n**2 + 2*n + 1
NameError: name 'n' is not defined

Raporty o błędach,
nie można pisać matematyki bezpośrednio jako kodu, należy zdefiniować „n” lub przypisać do wartości.

In [8]: n = 3.14
In [9]: m = n**2 + 2*n + 1
In [10]: m
Out[10]: 17.1396

Działa teraz, co jeśli nalegasz na połączenie dwóch oddzielnych linii w jedną. Nadchodzilambda

In [13]: j = lambda i: i**2 + 2*i + 1
In [14]: j
Out[14]: <function __main__.<lambda>>

Nie zgłoszono błędów.

To spojrzenie na lambda to, że pozwala napisać funkcję w jednym wierszu, podobnie jak w matematyce, bezpośrednio do komputera.

Zobaczymy to później.

Kontynuujmy głębsze kopanie „zadania”.

Jak pokazano powyżej, symbol równości =działa dla prostego typu danych (1 i „wartość”) i prostego wyrażenia (n ** 2 + 2 * n + 1).

Spróbuj tego:

In [15]: x = print('This is a x')
This is a x
In [16]: x
In [17]: x = input('Enter a x: ')
Enter a x: x

Działa dla prostych instrukcji, w Pythonie jest ich 11 rodzajów . Proste instrukcje - dokumentacja Python 3.6.3

Co powiesz na wyrażenie złożone,

In [18]: m = n**2 + 2*n + 1 if n > 0
SyntaxError: invalid syntax
#or
In [19]: m = n**2 + 2*n + 1, if n > 0
SyntaxError: invalid syntax

Istnieje możliwość defwłączenia

In [23]: def m(n):
    ...:     if n > 0:
    ...:         return n**2 + 2*n + 1
    ...:
In [24]: m(2)
Out[24]: 9

Tada, przeanalizuj to, „m” to nazwa, „n ** 2 + 2 * n + 1” to wartość. :jest wariantem „=”.
Znajdź, jeśli tylko dla zrozumienia, wszystko zaczyna się od zadania i wszystko jest zadaniem.

Teraz wróć do lambda, mamy funkcję o nazwie „m”

Próbować:

In [28]: m = m(3)
In [29]: m
Out[29]: 16

Istnieją tutaj dwie nazwy „m”, funkcja mma już nazwę, jest zduplikowana.

Formatuje jak:

In [27]: m = def m(n):
    ...:         if n > 0:
    ...:             return n**2 + 2*n + 1
    SyntaxError: invalid syntax

To nie jest inteligentna strategia, więc raporty o błędach

Musimy usunąć jeden z nich, ustawić funkcję bez nazwy.

m = lambda n:n**2 + 2*n + 1

Nazywa się to „funkcją anonimową”

Podsumowując

  1. lambda w funkcji wbudowanej, która umożliwia pisanie funkcji w jednej linii prostej, podobnie jak w matematyce
  2. lambda jest anonimowy

Mam nadzieję że to pomoże.

Rachunek różniczkowy
źródło
2

Jest to funkcja, która nie ma nazwy. Na przykład w c # możesz użyć

numberCollection.GetMatchingItems<int>(number => number > 5);

aby zwrócić liczby większe niż 5.

number => number > 5

jest tutaj część lambda. Reprezentuje funkcję, która przyjmuje parametr (liczbę) i zwraca wartość logiczną (liczba> 5). Metoda GetMatchingItems używa tej lambda do wszystkich elementów w kolekcji i zwraca pasujące elementy.

Serhat Ozgel
źródło
2

W JavaScripcie, na przykład, są traktowane jako funkcje tego samego typu mieszanego, jak wszystkiego innego ( int, string, float, bool). Jako takie, możesz tworzyć funkcje w locie, przypisywać je do rzeczy i oddzwaniać później. Jest to przydatne, ale nie jest to coś, co chcesz nadużywać, inaczej wprowadzisz w błąd wszystkich, którzy muszą utrzymywać kod po tobie ...

Oto kod, z którym bawiłem się, aby zobaczyć, jak głęboko schodzi ta królicza nora:

var x = new Object;
x.thingy = new Array();
x.thingy[0] = function(){ return function(){ return function(){ alert('index 0 pressed'); }; }; }
x.thingy[1] = function(){ return function(){ return function(){ alert('index 1 pressed'); }; }; }
x.thingy[2] = function(){ return function(){ return function(){ alert('index 2 pressed'); }; }; }

for(var i=0 ;i<3; i++)
    x.thingy[i]()()();
Michael - Where's Clay Shirky
źródło
2

W kontekście CS funkcja lambda jest abstrakcyjną koncepcją matematyczną, która rozwiązuje problem symbolicznej oceny wyrażeń matematycznych. W tym kontekście funkcja lambda jest taka sama jak termin lambda .

Ale w językach programowania jest coś innego. Jest to fragment kodu, który jest zadeklarowany jako „na miejscu” i który można przekazać jako „obywatel pierwszej klasy”. Ta koncepcja wydawała się przydatna, ponieważ pojawiła się w prawie wszystkich popularnych współczesnych językach programowania (patrz funkcje lambda w dowolnym miejscu).

battlmonstr
źródło
2

A Lambda Functionlub a Small Anonymous Functionto samodzielny blok funkcjonalności, który można przekazać i wykorzystać w kodzie. Lambda ma różne nazwy w różnych językach programowania - Lambdaw Python i Kotlin , Closurew Swift lub Blockw C i Objective-C . Chociaż znaczenie lambdy jest dość podobne dla tych języków, czasami ma niewielkie rozróżnienie.

Zobaczmy, jak działa Lambda (zamknięcie) w Swift 4.2 z metodą sorted () - od normalnej funkcji do najkrótszego wyrażenia:

let coffee: [String] = ["Cappuccino", "Espresso", "Latte", "Ristretto"]

1. Funkcja normalna

func backward(_ n1: String, _ n2: String) -> Bool {
    return n1 > n2
}
var reverseOrder = coffee.sorted(by: backward)


// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

2. Wyrażenie zamknięcia

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in
    return n1 > n2
})

3. Wyrażenie zamknięcia w linii

reverseOrder = coffee.sorted(by: { (n1: String, n2: String) -> Bool in return n1 > n2 } )

4. Wnioskowanie typu z kontekstu

reverseOrder = coffee.sorted(by: { n1, n2 in return n1 > n2 } )

5. Domniemane zwroty z zamknięć z pojedynczym wyrażeniem

reverseOrder = coffee.sorted(by: { n1, n2 in n1 > n2 } )

6. Skrócone nazwy argumentów

reverseOrder = coffee.sorted(by: { $0 > $1 } )

// $0 and $1 are closure’s first and second String arguments.

7. Metody operatora

reverseOrder = coffee.sorted(by: >)

// RESULT: ["Ristretto", "Latte", "Espresso", "Cappuccino"]

Mam nadzieję że to pomoże.

Andy
źródło
1

Ja też to mam. Próbowałem tego w JS z tym:

var addAndMult = function(x) {
        return (function(y) {
            return (function(z) {
                return (x+y)*z; 
                });
            });
        };

Dodaje 2 do 4, a następnie zwielokrotnia wynik przez 6. Jednak czasami trudno mi to przeczytać :(

Stworzyłem również ciekawą funkcję forEach:

var forEach = function(arr) {
            return (function(x) {
            for (var i=0; arr[i]; i++) {
                 x(arr[i]);
             }
        });
    }

forEach ([1,2,3,4,5]) (console.log);

Ta metoda iteruje tablicę i wykonuje akcję - w przypadku drukowania na konsoli. Teraz też rozumiem, dlaczego labmdas są potężne.

Ilian Zapryanov
źródło
1

W programowaniu komputerowym lambda to fragment kodu (instrukcja, wyrażenie lub ich grupa), który pobiera pewne argumenty z zewnętrznego źródła. Nie zawsze musi to być funkcja anonimowa - mamy wiele sposobów na ich wdrożenie.

Mamy wyraźny rozdział między wyrażeniami, stwierdzeniami i funkcjami, których matematycy nie mają.

Słowo „funkcja” w programowaniu jest również inne - mamy „funkcja” to seria kroków do zrobienia (od łacińskiego „perform”). W matematyce chodzi o korelację między zmiennymi.

Języki funkcjonalne starają się być jak najbardziej podobne do formuł matematycznych, a ich słowa oznaczają prawie to samo. Ale w innych językach programowania jest inaczej.

konmik
źródło
0

Odpowiedź na pytanie jest wyczerpująca, nie chcę wchodzić w szczegóły. Chcę podzielić się użytkowaniem podczas pisania obliczeń numerycznych w rdzeniu.

Istnieje przykład lambda (funkcja anonimowa)

let f = |x: f32| -> f32 { x * x - 2.0 };
let df = |x: f32| -> f32 { 2.0 * x };

Kiedy pisałem moduł metody Newtona – Raphsona, był on używany jako pochodna pierwszego i drugiego rzędu. (Jeśli chcesz wiedzieć, co to jest metoda Newtona – Raphsona, odwiedź „ https://en.wikipedia.org/wiki/Newton%27s_method ”.

Dane wyjściowe są następujące

println!("f={:.6}      df={:.6}", f(10.0), df(10.0))

f=98.000000       df=20.000000
madeinQuant
źródło
0

Wyobraź sobie, że masz restaurację z opcją dostawy i masz zamówienie, które musi zostać zrealizowane w mniej niż 30 minut. Chodzi o to, że klienci zwykle nie dbają o to, czy wysyłasz jedzenie na rowerze samochodem lub boso, o ile danie jest ciepłe i związane. Przekształćmy więc ten idiom w JavaScript z anonimowymi i zdefiniowanymi funkcjami transportowymi.

Poniżej zdefiniowaliśmy sposób dostarczania aka, definiujemy nazwę funkcji:

// ES5 
var food = function withBike(kebap, coke) {
return (kebap + coke); 
};

Co jeśli użyjemy funkcji strzałek / lambda do wykonania tego transferu:

// ES6    
const food = (kebap, coke) => { return kebap + coke };

Widzisz, nie ma różnicy dla klienta i nie marnujesz czasu na zastanawianie się, jak wysłać jedzenie. Po prostu to wyślij.

Przy okazji, nie polecam kebapa z colą, dlatego górne kody dadzą ci błędy. Baw się dobrze.

akinov
źródło