函数式编程

C++ 中的函数式编程范式

functional-programming.cpp

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <memory>
#include <cmath>
#include <numeric>
#include <optional>

// 纯函数示例
int add(int a, int b) {
    return a + b;
}

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

// 高阶函数 - 接受函数作为参数
template<typename Func>
void applyToVector(std::vector<int>& vec, Func func) {
    std::transform(vec.begin(), vec.end(), vec.begin(), func);
}

// 高阶函数 - 返回函数
auto createMultiplier(int factor) {
    return [factor](int x) { return x * factor; };
}

// 函数组合
template<typename F, typename G>
auto compose(F f, G g) {
    return [f, g](auto x) { return f(g(x)); };
}

// 柯里化 (Currying)
auto curry_add(int a) {
    return [a](int b) { return a + b; };
}

// 偏应用 (Partial Application)
auto partial_add(int a) {
    return [a](int b) { return a + b; };
}

// 不可变数据结构模拟
class ImmutableVector {
private:
    std::vector<int> data;
    
public:
    ImmutableVector(std::vector<int> vec) : data(std::move(vec)) {}
    
    ImmutableVector add(int value) const {
        auto newData = data;
        newData.push_back(value);
        return ImmutableVector(newData);
    }
    
    ImmutableVector map(std::function<int(int)> func) const {
        std::vector<int> newData;
        std::transform(data.begin(), data.end(), std::back_inserter(newData), func);
        return ImmutableVector(newData);
    }
    
    ImmutableVector filter(std::function<bool(int)> predicate) const {
        std::vector<int> newData;
        std::copy_if(data.begin(), data.end(), std::back_inserter(newData), predicate);
        return ImmutableVector(newData);
    }
    
    void print() const {
        std::cout << "[";
        for (size_t i = 0; i < data.size(); ++i) {
            std::cout << data[i];
            if (i < data.size() - 1) std::cout << ", ";
        }
        std::cout << "]";
    }
    
    size_t size() const { return data.size(); }
};

// 递归函数示例
int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

// 尾递归优化版本
int factorial_tail(int n, int acc = 1) {
    if (n <= 1) return acc;
    return factorial_tail(n - 1, n * acc);
}

// 斐波那契数列 - 递归
int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

// 记忆化斐波那契
int fibonacci_memo(int n, std::vector<int>& memo) {
    if (n <= 1) return n;
    if (memo[n] != -1) return memo[n];
    memo[n] = fibonacci_memo(n - 1, memo) + fibonacci_memo(n - 2, memo);
    return memo[n];
}

// 函数式编程工具函数
namespace Functional {
    // Map 函数
    template<typename Container, typename Func>
    auto map(const Container& container, Func func) {
        using ValueType = decltype(func(*container.begin()));
        std::vector<ValueType> result;
        std::transform(container.begin(), container.end(), std::back_inserter(result), func);
        return result;
    }
    
    // Filter 函数
    template<typename Container, typename Predicate>
    auto filter(const Container& container, Predicate pred) {
        using ValueType = typename Container::value_type;
        std::vector<ValueType> result;
        std::copy_if(container.begin(), container.end(), std::back_inserter(result), pred);
        return result;
    }
    
    // Reduce 函数
    template<typename Container, typename Func, typename T>
    T reduce(const Container& container, Func func, T initial) {
        return std::accumulate(container.begin(), container.end(), initial, func);
    }
    
    // 管道操作符模拟
    template<typename T, typename Func>
    auto operator|(T&& value, Func&& func) {
        return func(std::forward<T>(value));
    }
}

int main() {
    std::cout << "=== C++ 函数式编程示例 ===" << std::endl;
    
    // 1. 纯函数
    std::cout << "\n--- 纯函数 ---" << std::endl;
    std::cout << "add(3, 4) = " << add(3, 4) << std::endl;
    std::cout << "square(5) = " << square(5) << std::endl;
    
    // 2. 高阶函数
    std::cout << "\n--- 高阶函数 ---" << std::endl;
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    std::cout << "原始数组: ";
    for (int n : numbers) std::cout << n << " ";
    std::cout << std::endl;
    
    // 使用 Lambda 作为高阶函数的参数
    applyToVector(numbers, [](int x) { return x * 2; });
    std::cout << "乘以2后: ";
    for (int n : numbers) std::cout << n << " ";
    std::cout << std::endl;
    
    // 3. 函数返回函数
    std::cout << "\n--- 函数返回函数 ---" << std::endl;
    auto doubleIt = createMultiplier(2);
    auto tripleIt = createMultiplier(3);
    std::cout << "doubleIt(5) = " << doubleIt(5) << std::endl;
    std::cout << "tripleIt(5) = " << tripleIt(5) << std::endl;
    
    // 4. 函数组合
    std::cout << "\n--- 函数组合 ---" << std::endl;
    auto addOne = [](int x) { return x + 1; };
    auto multiplyByTwo = [](int x) { return x * 2; };
    auto addOneThenDouble = compose(multiplyByTwo, addOne);
    std::cout << "addOneThenDouble(5) = " << addOneThenDouble(5) << std::endl;
    
    // 5. 柯里化
    std::cout << "\n--- 柯里化 ---" << std::endl;
    auto addFive = curry_add(5);
    std::cout << "addFive(3) = " << addFive(3) << std::endl;
    
    // 6. 不可变数据结构
    std::cout << "\n--- 不可变数据结构 ---" << std::endl;
    ImmutableVector vec({1, 2, 3});
    std::cout << "原始向量: ";
    vec.print();
    std::cout << std::endl;
    
    auto doubled = vec.map([](int x) { return x * 2; });
    std::cout << "映射后: ";
    doubled.print();
    std::cout << std::endl;
    
    auto filtered = vec.filter([](int x) { return x % 2 == 1; });
    std::cout << "过滤奇数: ";
    filtered.print();
    std::cout << std::endl;
    
    // 7. 递归函数
    std::cout << "\n--- 递归函数 ---" << std::endl;
    std::cout << "factorial(5) = " << factorial(5) << std::endl;
    std::cout << "factorial_tail(5) = " << factorial_tail(5) << std::endl;
    std::cout << "fibonacci(10) = " << fibonacci(10) << std::endl;
    
    // 8. 记忆化
    std::cout << "\n--- 记忆化 ---" << std::endl;
    std::vector<int> memo(50, -1);
    std::cout << "fibonacci_memo(40) = " << fibonacci_memo(40, memo) << std::endl;
    
    // 9. 函数式编程工具
    std::cout << "\n--- 函数式编程工具 ---" << std::endl;
    std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // 使用 map
    auto squares = Functional::map(data, [](int x) { return x * x; });
    std::cout << "平方数: ";
    for (int n : squares) std::cout << n << " ";
    std::cout << std::endl;
    
    // 使用 filter
    auto evens = Functional::filter(data, [](int x) { return x % 2 == 0; });
    std::cout << "偶数: ";
    for (int n : evens) std::cout << n << " ";
    std::cout << std::endl;
    
    // 使用 reduce
    int sum = Functional::reduce(data, [](int a, int b) { return a + b; }, 0);
    std::cout << "总和: " << sum << std::endl;
    
    // 10. 管道操作
    std::cout << "\n--- 管道操作 ---" << std::endl;
    auto evenSquares = Functional::map(
        Functional::filter(data, [](int x) { return x % 2 == 0; }),
        [](int x) { return x * x; }
    );
    int result = Functional::reduce(evenSquares, [](int a, int b) { return a + b; }, 0);
    
    std::cout << "偶数的平方和: " << result << std::endl;
    
    // 11. 函数式编程模式
    std::cout << "\n--- 函数式编程模式 ---" << std::endl;
    
    // Maybe/Optional 模式
    auto safeDivide = [](int a, int b) -> std::optional<double> {
        if (b == 0) return std::nullopt;
        return static_cast<double>(a) / b;
    };
    
    auto result1 = safeDivide(10, 2);
    auto result2 = safeDivide(10, 0);
    
    if (result1) {
        std::cout << "10 / 2 = " << *result1 << std::endl;
    }
    if (!result2) {
        std::cout << "10 / 0 = 错误(除零)" << std::endl;
    }
    
    std::cout << "\n函数式编程示例完成!" << std::endl;
    
    return 0;
}

Run Result

$ g++ -std=c++23 functional-programming.cpp -o functional-programming
$ ./functional-programming
=== C++ 函数式编程示例 ===

--- 纯函数 ---
add(3, 4) = 7
square(5) = 25

--- 高阶函数 ---
原始数组: 1 2 3 4 5 
乘以2后: 2 4 6 8 10 

--- 函数返回函数 ---
doubleIt(5) = 10
tripleIt(5) = 15

--- 函数组合 ---
addOneThenDouble(5) = 12

--- 柯里化 ---
addFive(3) = 8

--- 不可变数据结构 ---
原始向量: [1, 2, 3]
映射后: [2, 4, 6]
过滤奇数: [1, 3]

--- 递归函数 ---
factorial(5) = 120
factorial_tail(5) = 120
fibonacci(10) = 55

--- 记忆化 ---
fibonacci_memo(40) = 102334155

--- 函数式编程工具 ---
平方数: 1 4 9 16 25 36 49 64 81 100 
偶数: 2 4 6 8 10 
总和: 55

--- 管道操作 ---
偶数的平方和: 220

--- 函数式编程模式 ---
10 / 2 = 5
10 / 0 = 错误(除零)

函数式编程示例完成!

Code Explanation

  • 纯函数 - 相同输入总是产生相同输出,无副作用
  • 高阶函数 - 接受函数作为参数或返回函数的函数
  • Lambda 表达式 - 匿名函数,支持闭包和捕获
  • 函数组合 - 将多个函数组合成新的函数
  • 柯里化 - 将多参数函数转换为单参数函数序列
  • 不可变数据结构 - 创建新对象而不是修改现有对象
  • 递归 - 函数调用自身解决问题
  • 记忆化 - 缓存函数结果避免重复计算
  • Map/Filter/Reduce - 函数式编程的核心操作
  • 管道操作 - 将数据通过一系列函数传递