Lambda 表达式学习(2) ——lambda 变换

回顾λ-calculus语法:

t ::=      terms:

  x      variable

  λx.t    abstraction

  t t     application

 

λ-变换:保持λ-项含义的同时对其进行变换。

 

1. α-变换:改变被绑定变量的名称,所代表的含义仍是一样的。

λx.t → λy.t(x:=y)

(将表达式的body t中的所有x的自由出现替换称y)

两个lambda表达式如果可以通过α-变换(可能应用到子项)从一个变换到另外一个,则称他们是全等的。

 

2. β-规约:对application的变换,表示函数作用的概念。

 

t1中所有的自由的x替换为t2作为结果。

不允许任何beta归约的lambda表达式被称为Beta范式。不是所有的表达式都可以归约到范式。

 

3. η-变换

Eta-conversion expresses the idea of extensionality, which in this context is that two functions are the same if and only if they give the same result for all arguments. Eta-conversion converts between λx.(f x) and f whenever x does not appear free in f.

转载于:https://www.cnblogs.com/zhaohouhou/p/4354706.html

### C++ Lambda 表达式与谓词逻辑实现 #### 基本概念 Lambda 表达式是一种匿名函数,在 C++11 中被引入,用于简化代码并提高可读性和效率[^3]。它允许开发者在需要的地方直接定义小型函数而无需显式命名它们。 谓词是一个返回布尔值的函数对象或表达式,通常用于 STL 算法中作为条件判断依据[^2]。通过结合 Lambda 表达式和谓词逻辑,可以高效地完成复杂的筛选、排序或其他操作。 --- #### 定义 Lambda 表达式的语法结构 C++ 的 Lambda 表达式遵循以下通用形式: ```cpp [capture](parameters) -> return_type { body } ``` - **capture**: 指定如何捕获外部变量(按值、按引用等)。 - **parameters**: 函数参数列表。 - **return_type**: 返回类型(如果未指定,则由编译器推导)。 - **body**: 函数主体部分。 例如,一个简单的 Lambda 表达式如下所示: ```cpp auto add = [](int a, int b) { return a + b; }; std::cout << add(3, 4); // 输出 7 ``` --- #### 使用 Lambda 实现谓词逻辑的例子 以下是几个常见的场景及其对应的 Lambda 和谓词逻辑实现方式: ##### 场景一:使用 `std::sort` 进行自定义排序 假设有一个整数数组,希望按照降序排列。可以通过提供一个 Lambda 表达式来实现这一目标: ```cpp #include <vector> #include <algorithm> #include <iostream> int main() { std::vector<int> numbers = {5, 2, 9, 1, 5, 6}; // 自定义排序规则 (降序) std::sort(numbers.begin(), numbers.end(), [](const int& a, const int& b) { return a > b; }); for(auto num : numbers){ std::cout << num << " "; // 输出: 9 6 5 5 2 1 } return 0; } ``` 此示例展示了如何将 Lambda 表达式作为第三个参数传递给 `std::sort` 来改变默认行为。 --- ##### 场景二:过滤容器中的元素 借助 `std::copy_if` 或其他算法,可以根据特定条件保留满足要求的数据项。这里展示了一个例子——仅复制偶数值到另一个向量中: ```cpp #include <vector> #include <algorithm> #include <iterator> #include <iostream> int main(){ std::vector<int> source = {1, 2, 3, 4, 5, 6, 7, 8, 9}; std::vector<int> target; // 将源数据集中符合条件的部分拷贝至目标集合 std::copy_if(source.begin(), source.end(), std::back_inserter(target), [](int value){ return value % 2 == 0; }); for(int val : target){ std::cout << val << ' '; // 输出: 2 4 6 8 } return 0; } ``` 上述程序片段说明了如何运用 Lambda 构建复杂查询条件,并将其嵌入标准模板库(STL)方法之中[^1]。 --- ##### 场景三:计算累积总和 有时我们需要遍历整个序列并对每一步的结果应用某种变换后再累加起来。下面演示的是求平方根之后再相加的过程: ```cpp #include <numeric> #include <cmath> #include <vector> #include <iostream> int main(){ std::vector<double> data = {1.0, 4.0, 9.0, 16.0}; double sum_of_roots = std::accumulate(data.begin(), data.end(), 0.0, [](double acc, double elem){ return acc + sqrt(elem); }); std::cout << "Sum of square roots is: " << sum_of_roots << '\n'; return 0; } ``` 这段代码体现了当面对连续处理任务时,Lambda 如何帮助我们构建紧凑且高效的解决方案。 --- #### 关于生命周期与闭包关系的理解 值得注意的一点在于,Lambda 表达式的实际运行依赖其背后生成的一个临时类实例即所谓的“闭包”。因此,在设计涉及长时间存活或者跨线程共享状态的应用场合下,应当特别留意这些细节以免引发潜在错误[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值