Что такое lambda (функция)?
Для человека без comp-sci фона, что такое lambda в мире компьютерных наук?
- Сбита ли математика с плавающей запятой?
- Алгоритм естественной сортировки
- Лучший способ найти точку на круге, ближайшем к данной точке
- Как измерить сходство между двумя изображениями?
- Для чего нужен пузырь?
- Как найти пару с k-й наибольшей суммой?
- Что такое непрозрачное значение в C ++?
- Является ли двойным действительно неподходящим для денег?
Лямбда исходит из исчисления Лямбды и относится к анонимным функциям программирования.
Почему это круто? Это позволяет вам писать быстро отбрасываемые функции, не называя их. Он также обеспечивает хороший способ записи замыканий. С этой силой вы можете делать такие вещи.
питон
def adder(x): return lambda y: x + y add5 = adder(5) add5(1) 6
Как видно из fragmentа Python, сумматор функции принимает аргумент x и возвращает анонимную функцию или lambda, которая принимает другой аргумент y. Эта анонимная функция позволяет вам создавать функции из функций. Это простой пример, но он должен передать мощность lambda и замыкания.
Примеры на других языках
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
Схема
(define adder (lambda (x) (lambda (y) (+ xy)))) (define add5 (adder 5)) (add5 1) 6
C # 3.5 или выше
Func> adder = (int x) => (int y) => x + y; // `int` declarations optional Func 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 addWithClosure = (x) => x + yEnclosed; Debug.Assert(addWithClosure(2) == 3);
стриж
func adder(x: Int) -> (Int) -> Int{ return { y in x + y } } let add5 = adder(5) add5(1) 6
PHP
$a = 1; $b = 2; $lambda = function () use (&$a, &$b) { echo $a + $b; }; echo $lambda();
Haskell
(\xy -> x + y)
Java см. Эту запись
// The following is an example of Predicate : // a functional interface that takes an argument // and returns a boolean primitive type. Predicate 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
Лямбда – это тип функции, определенный в строке. Наряду с лямбдой вы также обычно имеете какой-то тип переменной, который может содержать ссылку на функцию, lambda или иначе.
Например, вот кусок кода C #, который не использует 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); }
Это вызывает калькулятор, передавая не только два числа, но и какой метод вызывать внутри калькулятора для получения результатов расчета.
В C # 2.0 мы получили анонимные методы, которые сокращают код выше:
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; }); }
И затем в C # 3.0 мы получили lambdas, который делает код еще короче:
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); }
Это относится к lambda-исчислению , которое является формальной системой, которая имеет только lambda-выражения, которые представляют собой функцию, которая принимает функцию для своего единственного аргумента и возвращает функцию. Все функции в lambda-исчислении имеют такой тип, т. λ : λ → λ
.
Лисп использовал концепцию lambda, чтобы назвать ее анонимные литералы функций. Эта lambda представляет собой функцию, которая принимает два аргумента x и y и возвращает их произведение:
(lambda (xy) (* xy))
Он может быть применен как в строке ( 50 ):
((lambda (xy) (* xy)) 5 10)
Название «lambda» – это просто исторический артефакт. Все, о чем мы говорим, это выражение, значение которого является функцией.
Простой пример (использование Scala для следующей строки):
args.foreach(arg => println(arg))
где аргумент метода foreach
является выражением для анонимной функции. Вышеупомянутая строка более или менее такая же, как запись чего-то вроде этого (не совсем настоящий код, но вы получите идею):
void printThat(Object that) { println(that) } ... args.foreach(printThat)
за исключением того, что вам не нужно беспокоиться:
- Объявление функции в другом месте (и ее нужно искать, когда вы снова просмотрите код).
- Именование чего-то, что вы используете только один раз.
Как только вы привыкли использовать значения, необходимость обойтись без них кажется такой же глупой, как требуется для обозначения каждого выражения, например:
int tempVar = 2 * a + b ... println(tempVar)
вместо того, чтобы просто писать выражение там, где оно вам нужно:
println(2 * a + b)
Точная нотация варьируется от языка к языку; Греческий язык не всегда требуется! 😉
Лямбда-исчисление является последовательной математической теорией замещения. В школьной математике можно видеть, например, x+y=5
сопряженный с x−y=1
. Наряду с путями манипулирования отдельными уравнениями также можно объединить информацию из этих двух, при условии, что подстановки с поперечным уравнением выполняются логически. Исчисление Lambda кодирует правильный способ выполнения этих замещений.
Учитывая, что y = x−1
является действительной перестановкой второго уравнения, это: λ y = x−1
означает функцию, подставляющую символы x−1
для символа y
. Теперь представьте себе применение λ y
к каждому члену в первом уравнении. Если термин y
то выполните замену; в противном случае ничего не делать. Если вы сделаете это на бумаге, вы увидите, как применение этого λ y
сделает первое уравнение разрешимым.
Это ответ без какой-либо компьютерной науки или программирования.
Самый простой пример программирования, о котором я могу думать, – это http://en.wikipedia.org/wiki/Joy_(programming_language)#How_it_works :
вот как квадратная функция может быть определена на императивном языке программирования (C):
int square(int x) { return x * x; }
Переменная x является формальным параметром, который заменяется фактическим значением, которое должно быть квадратично при вызове функции. В функциональном языке (схема) будет определена одна и та же функция:
(define square (lambda (x) (* xx)))
Это по-разному, но по-прежнему использует формальный параметр x таким же образом.
Добавлено: http://imgur.com/a/XBHub
Немного упрощенно: функция lambda – это функция, которая может быть передана другим функциям и доступна для доступа к логике.
В синтаксисе C # lambda часто компилируется в простые методы так же, как анонимные delegates, но его также можно разбить и прочитать его логику.
Например (в C # 3):
LinqToSqlContext.Where( row => row.FieldName > 15 );
LinqToSql может читать эту функцию (x> 15) и преобразовывать ее в фактический SQL для выполнения с использованием деревьев выражений.
Вышеприведенное утверждение становится следующим:
select ... from [tablename] where [FieldName] > 15 --this line was 'read' from the lambda function
Это отличается от обычных методов или анонимных делегатов (которые действительно являются манерой компилятора), потому что их невозможно прочитать .
Не все методы в C #, использующие синтаксис lambda, могут быть скомпилированы в деревья выражений (т.е. фактические lambda-функции). Например:
LinqToSqlContext.Where( row => SomeComplexCheck( row.FieldName ) );
Теперь дерево выражений невозможно прочитать – SomeComplexCheck не может быть разбит. Оператор SQL будет выполняться без того, и каждая строка данных будет SomeComplexCheck
через SomeComplexCheck
.
Лямбда-функции не следует путать с анонимными методами. Например:
LinqToSqlContext.Where( delegate ( DataRow row ) { return row.FieldName > 15; } );
Это также имеет встроенную функцию, но на этот раз это всего лишь магия компилятора – компилятор C # разделит это на новый метод экземпляра с автогенерированным именем.
Анонимные методы не могут быть прочитаны, и поэтому логика не может быть переведена, как это возможно, для lambda-функций.
Мне нравится объяснение Lambdas в этой статье: Эволюция LINQ и ее влияние на дизайн C # . Это имело для меня большой смысл, поскольку он показывает реальный мир для Лямбдаса и создает его как практический пример.
Их быстрое объяснение: Lambdas – это способ обработки кода (функций) в качестве данных.
Пример lambda в Ruby выглядит следующим образом:
hello = lambda do puts('Hello') puts('I am inside a proc') end hello.call
Будет генерировать следующий результат:
Hello I am inside a proc
@Brian Я все время использую lambdas в C #, в операциях LINQ и non-LINQ. Пример:
string[] GetCustomerNames(IEnumerable customers) { return customers.Select(c=>c.Name); }
До C # я использовал анонимные функции в JavaScript для обратных вызовов для функций AJAX, прежде чем термин Ajax был даже придуман:
getXmlFromServer(function(result) {/*success*/}, function(error){/*fail*/});
Интересная вещь с синтаксисом lambda C #, однако, заключается в том, что сами по себе их тип не может быть выведен (т. Е. Вы не можете вводить var foo = (x, y) => x * y), но в зависимости от того, какой тип они они будут скомпилированы в виде делегатов или абстрактных синтаксических деревьев, представляющих выражение (как это делают магические объекты объектов LINQ для своей «языковой интеграции»).
Lambdas в LISP также может быть передан оператору котировки, а затем пройден как список списков. Некоторые мощные macros сделаны таким образом.
Ответ на этот вопрос формально ответил, поэтому я не буду пытаться добавить к этому больше.
В очень простых, неформальных словах кому-то, кто мало знает или ничего не говорит по математике или программированию, я бы объяснил это как небольшую «машину» или «ящик», которая вносит определенный вклад, делает некоторую работу и производит некоторый вывод, не имеет конкретного имени , но мы знаем, где это и только этим знанием, мы его используем.
Практически говоря, для человека, который знает, что такое функция, я бы сказал им, что это функция, которая не имеет имени, обычно помещается в точку в памяти, которая может использоваться только путем ссылки на эту память (обычно с использованием переменная – если они слышали о концепции указателей на функции, я бы использовал их в качестве аналогичной концепции). Этот ответ охватывает довольно общие основы (без упоминания о закрытии и т. д.), но можно легко получить смысл.
Вы можете думать об этом как анонимную функцию – вот еще информация: Wikipedia – анонимная функция
У меня проблемы с обмоткой вокруг lambda-выражений, потому что я работаю в Visual FoxPro, у которого есть подстановка Macro и функции ExecScript {} и Evaluate (), которые, похоже, выполняют те же самые цели.
? Calculator(10, 23, "a + b") ? Calculator(10, 23, "a - b"); FUNCTION Calculator(a, b, op) RETURN Evaluate(op)
Одно из преимуществ использования формальных лямбдов – это (я предполагаю) проверка времени компиляции: Fox не будет знать, если вы опечатаете текстовую строку выше, пока она не попытается ее запустить.
Это также полезно для кода, управляемого данными: вы можете хранить целые процедуры в полях memo в базе данных, а затем просто оценивать их во время выполнения. Это позволяет вам настроить часть приложения без фактического доступа к источнику. (Но это совсем другая тема).
Просто потому, что я не вижу здесь примера C ++ 11, я остановлюсь и опубликую этот хороший пример. После поиска это самый яркий пример, который я смог найти.
Привет, Lambdas, версия 1
template void Eval( const F& f ) { f(); } void foo() { Eval( []{printf("Hello, Lambdas\n");} ); }
Привет, Lambdas, версия 2:
void bar() { auto f = []{printf("Hello, Lambdas\n"); }; f(); }
Для человека без comp-sci фона, что такое lambda в мире компьютерных наук?
Я проиллюстрирую его интуитивно шаг за шагом в простых и читаемых кодах python.
Короче говоря, lambda – это просто анонимная и встроенная функция.
Давайте начнем с задания, чтобы понять lambdas
как первокурсника с фоном базовой арифметики.
Схема присвоения – это «имя = значение», см.
In [1]: x = 1 ...: y = 'value' In [2]: x Out[2]: 1 In [3]: y Out[3]: 'value'
‘x’, ‘y’ – это имена и 1, значение – значения. Попробуйте функцию в математике
In [4]: m = n**2 + 2*n + 1 NameError: name 'n' is not defined
Отчеты об ошибках,
вы не можете написать математику непосредственно в качестве кода, ‘n’ должно быть определено или присвоено значению.
In [8]: n = 3.14 In [9]: m = n**2 + 2*n + 1 In [10]: m Out[10]: 17.1396
Теперь он работает, что если вы настаиваете на объединении двух линий seperarte с одним. Наступает lambda
In [13]: j = lambda i: i**2 + 2*i + 1 In [14]: j Out[14]: >
Ошибок не сообщалось.
Это взгляд на lambda
, он позволяет вам писать функцию в одной строке, как и в математике, в компьютер напрямую.
Мы увидим это позже.
Давайте продолжим углубляться в «присвоение».
Как показано выше, символ равенства =
работает для простых данных (1 и «значение») и простого выражения (n ** 2 + 2 * n + 1).
Попробуй это:
In [15]: x = print('This is a x') This is ax In [16]: x In [17]: x = input('Enter ax: ') Enter ax: x
Он работает для простых операторов, в python имеется 11 типов . Простые операторы – документация Python 3.6.3
Как насчет составной инструкции,
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
Там появляется def
enable it working
In [23]: def m(n): ...: if n > 0: ...: return n**2 + 2*n + 1 ...: In [24]: m(2) Out[24]: 9
Tada, проанализируйте его, «m» – это имя, «n ** 2 + 2 * n + 1» – значение. :
является вариантом ‘=’.
Найдите его, если только для понимания, все начинается с назначения, и все назначается.
Теперь вернемся к lambda
, у нас есть функция с именем ‘m’
Пытаться:
In [28]: m = m(3) In [29]: m Out[29]: 16
Здесь есть два имени «m», функция m
уже имеет имя, дублируется.
Это форматирование:
In [27]: m = def m(n): ...: if n > 0: ...: return n**2 + 2*n + 1 SyntaxError: invalid syntax
Это не умная страtagsя, поэтому отчеты об ошибках
Мы должны удалить один из них, установить функцию без имени.
m = lambda n:n**2 + 2*n + 1
Это называется «анонимная функция»
В заключение,
-
lambda
в встроенной функции, которая позволяет вам написать функцию в одной прямой, как это делается в математике -
lambda
анонимно
Надеюсь это поможет.
Это функция, которая не имеет имени. Например, например, в c # вы можете использовать
numberCollection.GetMatchingItems(number => number > 5);
для возврата чисел, превышающих 5.
number => number > 5
здесь находится lambda-часть. Он представляет функцию, которая принимает параметр (число) и возвращает логическое значение (число> 5). Метод GetMatchingItems использует эту лямбду для всех элементов коллекции и возвращает соответствующие элементы.
Я тоже это понял. Я попробовал это в JS с этим:
var addAndMult = function(x) { return (function(y) { return (function(z) { return (x+y)*z; }); }); };
Он добавляет от 2 до 4, затем результат получается на 6. Однако мне иногда трудно читать 🙁
Также я сделал интересную функцию 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);
Этот метод выполняет итерацию массива и выполняет действие – в случае печати на консоли. Теперь я тоже понимаю, почему labmdas являются мощными.
Например, в Javascript функции рассматриваются как один и тот же смешанный тип, как и все остальные ( int
, string
, float
, bool
). Таким образом, вы можете создавать функции «на лету», назначать их вещам и называть их позже. Это полезно, но не то, что вы хотите использовать, или вы будете путать всех, кто должен поддерживать ваш код после вас …
Это какой-то код, с которым я играл, чтобы понять, насколько глубока эта кроличья дыра:
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]()()();
В контексте CS lambda-функция представляет собой абстрактную математическую концепцию, которая решает проблему символической оценки математических выражений. В этом контексте lambda-функция совпадает с lambda-термином .
Но в языках программирования это нечто другое. Это fragment кода, который объявлен «на месте», и его можно передать как «первоclassного гражданина». Эта концепция оказалась полезной, так что она вошла в почти все популярные современные языки программирования (см. Lambda functions everwhere post).
В компьютерном программировании lambda – это fragment кода (оператор, выражение или группа из них), который принимает некоторые аргументы из внешнего источника. Это не всегда должно быть анонимной функцией – у нас есть много способов их реализации.
У нас есть четкое разделение между выражениями, утверждениями и функциями, которых нет у математиков.
Слово «функция» в программировании также отличается – у нас есть «функция – это последовательность шагов» (от латинского «выполнить»). В математике это связано с корреляцией между переменными.
Функциональные языки стараются быть похожими на математические формулы, насколько это возможно, и их слова означают почти то же самое. Но на других языках программирования у нас все иначе.
На вопрос ответили полностью, я не хочу вдаваться в подробности. Я хочу поделиться использованием при написании численных вычислений в ржавчине.
Существует пример лямбды (анонимная функция)
let f = |x: f32| -> f32 { x * x - 2.0 }; let df = |x: f32| -> f32 { 2.0 * x };
Когда я писал модуль метода Ньютона-Рафсона, он использовался как производная первого и второго порядка. (Если вы хотите узнать, что такое метод Ньютона-Рафсона, посетите « https://en.wikipedia.org/wiki/Newton%27s_method ».
Выходной сигнал следующий
println!("f={:.6} df={:.6}", f(10.0), df(10.0)) f=98.000000 df=20.000000