你会如何在 C 中进行咖喱

How would you curry in C

我正在尝试学习 C 和 Currying(前几天学习了一些 Haskell 之后),我想知道是否可以在 C 中做类似的事情。

这纯粹是为了“好玩”,我查看了 GCC,发现它支持嵌套函数(非标准),所以想知道这种方法是否可行。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

uint32_t (*addCur(uint32_t ad))(uint32_t ad) {
    uint32_t add(uint32_t to) {
        return ad + to;
    }
    return add;
}

int main(int argc, char **argv) {
    uint32_t a = 1, b = 2;

    if(argc > 1)
        a = atoi(argv[1]);
    if(argc > 2)
        b = atoi(argv[2]);

    uint32_t result = addCur(a)(b);
    printf("result: %d\n", result);

    return 0;
}

当 运行 给了我想要的效果时。

./Currying 5 7
result: 12

我想做的是实现一个“乘加”方法。所以本质上有三个嵌套函数,其中每个函数 returns 函数但将必要的范围留给适当的变量。

即在 JavaScript 中,您可以执行以下操作:

let multiplyAndAdd = (x) => (y) => (z) => (x*y) + z;
multiplyAndAdd(3)(4)(5);

给出 17。

这就是我一直在寻找的答案。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

/* Type defining the function returns */
typedef uint32_t (*addCur)(uint32_t ad);
typedef addCur (*multiply)(uint32_t m);

multiply multiplyAndAdd(uint32_t x) {
    addCur doMultiply(uint32_t m) {
        uint32_t mx = m*x;

        uint32_t doAdd(uint32_t c) {
            return mx + c;
        }

        return doAdd;
    }

    return doMultiply;
}

int main(int argc, char **argv) {
    uint32_t a = 4, b = 5, c = 6;

    if(argc > 1)
        a = atoi(argv[1]);
    if(argc > 2)
        b = atoi(argv[2]);
    if(argc > 3)
        c = atoi(argv[3]);

    uint32_t result = multiplyAndAdd(a)(b)(c);
    printf("result: %d\n", result);

    return 0;
}

它有助于类型定义每个方法的 return 类型。这使方法更易读。反过来,这让我可以更轻松地链接每个方法的 return。

如评论中所述,这是具有潜在危险的代码,因为无法保证在函数 returns 时堆栈分配的函数甚至会存在。但我只是在思考是否可以在理论上完成而无需大量代码的前景。