C# 匿名函数递归

C# anonymous function recursion

如果我错了请纠正我,但我在网上找不到像这样直接的东西。 假设您有以下内容:

        static Func<int,int> GetInt(int n)
        {
            return (int y) =>
            {
                if (y < 2)
                    return (y);
                return 
                    GetInt(n - 1)(y) - GetInt(n - 2)(y);
            };
        }

尝试通过调用此匿名函数来获取结果 returning 类似于 System.Func`2[System.Int32,System.Int32]。 如何使用匿名函数实现递归。我如何转换 return 值,这是实际函数以获得结果?

您似乎是按如下方式调用函数:

var result = GetInt(valueOfN);

注意上面的GetInt方法returns本身就是一个函数。因此,要获得内部函数返回的结果,您需要执行以下操作:

var result = GetInt(valueOfN)(valueOfY);

看来您已经修改了函数。

变量 n 未以任何方式用于创建 Func<int, int>,并且变量 y 未被修改。 Func<int, int> 因此只会导致堆栈溢出。

如果我假设 yn 是同一个变量,那么您的方法实际上可以归结为:

static Func<int,int> GetInt()
{
    Func<int, int> f = y =>
    {
        if (y < 2)
            return y;
        return 
            f(y - 1) - f(y - 2);
    };
    return f;
}

但这给了我一个错误:

Use of unassigned local variable 'f'

这让我们回到你的问题:

How can you achieve recursion using anonymous functions?

很简单。只需先将null赋值给函数,然后就可以使用递归了。

这给了我:

static Func<int,int> GetInt()
{
    Func<int, int> f = null;
    f = y =>
    {
        if (y < 2)
            return y;
        return 
            f(y - 1) - f(y - 2);
    };
    return f;
}

这非常有效。

正如其他答案中提到的问题中的代码

  • 不调用结果函数而是打印结果类型 ToString() 确实是 System.Func'2[System.Int32,System.Int32] ( by Ousmane D.
  • 代码是无限递归的,因为它从不检查 n 的值 (answer by Optional Option)

您可能追求的是Y-combinator (or fixed-point combinator) which can be said converts non-recursive function into recursive one. That covered in many articles and SO questions like Do we need fixed point combinators in C#?, Have I implemented Y-combinator using C# dynamic, and if I haven't, what is it?

您可能可以从不太复杂的变体开始,它出现在提出 y 组合器的完整代码的中间步骤中:

  • 递归函数可以表示为带参数和函数递归调用的函数。请注意,GetInt 不会递归调用 自身 ,它会递归调用 "some" 函数,因此这不是严格的 "safe" 方法 - 完整实现请参见链接以上。

    static int GetInt(Func f, int n) { return n < 2 ? 1 : f(n - 1) - f(n - 2); }

  • 要用自身调用该函数,我们需要将该函数(其类型为 Func<Func<int,int>, int, int>)转换为 Func<int, int> 并将其作为第一个参数传递。所以我们可以创建完成它的辅助方法。在下面的方法中 r 是 "function that recursive function should call to do recursion"。请注意,我们必须先初始化它,因为我们使用它的值来定义结果函数:

    Func<int, int> Rec(Func<Func<int, int>, int, int> f)
    {
        Func<int, int> r = null; 
        r = n => f(r, n);
    
        return r;
    }
    
  • 现在我们可以创建匿名递归函数了:

    Func<int,int> recursiveGetInt = Rec(GetInt);
    Console.WriteLine(recursiveGetInt (5));
    
    Func<int,int> anonymousFactorial = Rec((f, n)=> n == 1 ? 1 : n * f(n-1));
    Console.WriteLine(anonymousFactorial (5));
    
    Console.WriteLine("Anonymous Fibonacci of 5: {0}",
         ((f, n)=> n == 1 ? 1 : f(n-1) + f(n-2)) (5));