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...
精彩评论