开发者

Can you help me understand this example of fibonacci using C# closures?

开发者 https://www.devze.com 2022-12-18 18:53 出处:网络
Attempting to learn functional C#, I ported Dustin Campbell\'s fibonacci example to C#3. My solution works but I have trouble understanding the last line of Nth_Fib. Isn\'t it weird that the agrument

Attempting to learn functional C#, I ported Dustin Campbell's fibonacci example to C#3. My solution works but I have trouble understanding the last line of Nth_Fib. Isn't it weird that the agrument to formula doesn't matter? n gets instantly bound in the expression "fn => Nth_Fib(n - 1) + Nth_Fib(n - 2)" but I can't change the return type of build to Func<int>. This means I have to pass a redundant argument later?

note: the test passes

[TestFixture]
public class TestFibClosure{
    [Test]
    public void test_fib(){
        Assert.AreEqual(8, new FibClosure().Nth_Fib(5));
        Assert.AreEqual(1597, new FibClosure().Nth_Fib(16));
    }
}

public class FibClosure{
    private Func<int, int>[] formulaCache;

    public int Nth_Fib(int n){
        if (n <= 2) return n;
        if(formulaCache == null) formulaCache = new Func<int, int>[(n + 1)];
        Func<int, int> formula = build(n);
        //doesn't matter, n is already bound !! ??
        return formula(334567);//same as formula(n)
    }

    private Func<int, int> build(int n){开发者_开发知识库
        if (formulaCache[n] == null)
            formulaCache[n] = (fn => Nth_Fib(n - 1) + Nth_Fib(n - 2));
        return formulaCache[n];
    }
}


You can change the type to Func<int> - you've just got to do it everywhere:

public class FibClosure{
    private Func<int>[] formulaCache;

    public int Nth_Fib(int n){
        if (n <= 2) return n;
        if(formulaCache == null) formulaCache = new Func<int>[(n + 1)];
        Func<int> formula = build(n);
        return formula();
    }

    private Func<int> build(int n){
        if (formulaCache[n] == null)
            formulaCache[n] = () => Nth_Fib(n - 1) + Nth_Fib(n - 2);
        return formulaCache[n];
    }
}

You don't need an argument for the function, because the Fibonacci value it's computing is fixed - basically formulaCache[x] will compute fib(x). The clue to this was the fact that you didn't use fn within the lambda expression in build anyway.

I'm not sure I'd say this is a terribly clear way of structuring things, admittedly...

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号