当前位置:  开发笔记 > 编程语言 > 正文

什么是lambda(函数)?

如何解决《什么是lambda(函数)?》经验,为你挑选了10个好方法。

对于没有comp-sci背景的人来说,计算机科学领域的lambda是什么?



1> mk...:

Lambda来自Lambda微积分,指的是编程中的匿名函数.

为什么这很酷?它允许您在不命名的情况下编写快速丢弃功能.它还提供了一种编写闭包的好方法.有了这种力量,你就可以做到这样的事情.

蟒蛇

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

正如您从Python的片段中看到的那样,函数加法器接受参数x,并返回一个匿名函数或lambda,它接受另一个参数y.该匿名函数允许您从函数创建函数.这是一个简单的例子,但它应该传达lambda和闭包的力量.

其他语言的例子

JavaScript的

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

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

JavaScript(ES6)

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

方案

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

C#3.5或更高

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

迅速

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);

PHP

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

哈斯克尔

$a = 1;
$b = 2;

$lambda = function () use (&$a, &$b) {
    echo $a + $b;
};

echo $lambda();

Java看到这篇文章

(\x y -> x + y) 

LUA

// 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

科特林

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

红宝石

Ruby略有不同,因为你不能使用与调用函数完全相同的语法来调用lambda,但它仍然有lambdas.

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

Ruby是Ruby,有一个lambdas的简写,所以你可以这样定义adder:

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


那么,lambda函数和[函子](http://stackoverflow.com/a/356993/497934)之间有什么区别?

2> angry person..:

lambda是一种函数,内联定义.除了lambda之外,你通常还有一些变量类型可以保存对函数,lambda或其他函数的引用.

例如,这是一段不使用lambda的C#代码:

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);
}

这会调用Calculator,不仅传递两个数字,而且调用Calculator内部的方法来获取计算结果.

在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中我们得到了lambda,它使代码更短:

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);
}



3> joel.neely..:

"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)

确切的表示法因语言而异; 希腊语并不总是必需的!;-)



4> Mark Cidade..:

它指的是lambda演算,它是一个只有lambda表达式的正式系统,它表示一个函数,它为其唯一的参数获取一个函数并返回一个函数.lambda演算中的所有函数都属于那种类型,即? : ? ? ?.

Lisp使用lambda概念来命名它的匿名函数文字.这个lambda代表一个函数,它接受两个参数x和y,并返回它们的产品:

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

它可以像这样在线应用(评估为50):

((lambda (x y) (* x y)) 5 10)



5> isomorphisme..:

lambda演算是一种一致的数学替代理论.在学校数学中,人们看到例如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)中定义square函数:

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

变量x是形式参数,在调用函数时由实际值替换为平方.在函数式语言(Scheme)中,将定义相同的函数:

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

这在许多方面是不同的,但它仍然以相同的方式使用形式参数x.


补充: http ://imgur.com/a/XBHub

拉姆达



6> Keith..:

略微过度简化:lambda函数是一个可以传递给其他函数并且可以访问逻辑的函数.

在C#中,lambda语法通常以与匿名委托相同的方式编译为简单方法,但它也可以被分解并读取其逻辑.

例如(在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语句将在没有where的情况下执行,并且数据中的每一行都将被接通SomeComplexCheck.

Lambda函数不应与匿名方法混淆.例如:

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

这也有一个'内联'函数,但这次它只是编译器魔术 - C#编译器会将其拆分为具有自动生成名称的新实例方法.

匿名方法无法读取,因此逻辑无法转换为lambda函数.



7> Jon Galloway..:

我喜欢本文中对Lambdas的解释:LINQ的演变及其对C#设计的影响.它对我来说很有意义,因为它展示了Lambdas的真实世界,并将其作为一个实际例子构建出来.

他们的快速解释:Lambdas是一种将代码(函数)视为数据的方法.



8> CodingWithou..:

Ruby中lambda的一个例子如下:

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

hello.call

将生成以下输出:

Hello
I am inside a proc



9> Mark Cidade..:

@Brian我一直在C#中使用lambdas,在LINQ和非LINQ运算符中.例:

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

在C#之前,我使用JavaScript中的匿名函数来回调AJAX函数,之后创建了Ajax这个术语:

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

然而,C#的lambda语法的有趣之处在于它们自己的类型不能被推测(即,你不能输入var foo =(x,y)=> x*y)但是它们取决于它们的类型分配给它们,它们将被编译为表示表达式的委托或抽象语法树(这是LINQ对象映射器如何进行"语言集成"魔术).

LISP中的Lambdas也可以传递给报价运算符,然后作为列表列表遍历.一些强大的宏是以这种方式制作的.



10> Nick Louloud..:

这个问题正式得到了很好的回答,所以我不会试图在此上添加更多内容.

对于那些对数学或编程知之甚少或根本不知道的人来说,非常简单,非正式的话,我会把它解释为一个小的"机器"或"盒子",需要一些输入,做一些工作并产生一些输出,没有特别的名字,但我们知道它在哪里,只有这些知识,我们才能使用它.

实际上,对于一个知道函数是什么的人,我会告诉他们这是一个没有名字的函数,通常放在内存中只能通过引用该内存来使用(通常是通过使用一个变量 - 如果他们已经听说过函数指针的概念,我会将它们用作类似的概念) - 这个答案涵盖了漂亮的基础知识(没有提到闭包等),但是人们可以很容易地理解它.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有