我在Visual Studio中摆弄,我发现了
delegate RecursiveDelegate RecursiveDelegate();
是一个有效的委托定义.
我没有大量的函数式编程经验,但我想知道这种模式是否在函数式编程中真正有用,或者它是否仅仅是一种语义的好奇心.我想以两种方式提出这个问题:
>在有副作用的情况下.我可以看到这实际上是一种在函数式语言中模拟迭代学习算法的中途方式,其中算法的实际任务作为副作用执行,并且函数的新版本是返回值.这样做了吗?
>在没有副作用的情况下.我认为这原则上没用,但如果我错了,我会非常好奇.如果我们假设RecursiveDelegate()的实现没有副作用,这可能有用吗?
解决方法
我有一个类似代码的例子,它不是一个递归委托,但它很接近. “Y-Combinator”非常接近 – 坦率地说,我不知道它在实践中是如何工作的,但它用于定义递归函数.
这是您需要定义的时髦代码:
public delegate T S<T>(S<T> s); public static T U<T>(S<T> s) { return s(s); } public static Func<A,Z> Y<A,Z>(Func<Func<A,Z>,Func<A,Z>> f) { return U<Func<A,Z>>(r => a => f(U(r))(a)); }
现在,您可以在一行中定义递归函数.
阶乘:
var fact = Y<int,int>(_ => x => x == 0 ? 1 : x * _(x - 1)); var fact5 = fact(5); // == 120 var fact6 = fact(6); // == 720 var fact7 = fact(7); // == 5040
斐波那契:
var fibo = Y<int,int>(_ => x => x <= 1 ? 1 : _(x - 1) + _(x - 2)); var fibo5 = fibo(5); // == 8 var fibo6 = fibo(6); // == 13 var fibo7 = fibo(7); // == 21
代码中我最喜欢的行是调用s(s).说真的,如果有人能够把头脑中的那个拉直,那么他们就是天才!更不用说整个U< Func< A,Z>>(r => a => f(U(r))(a)).
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。