我理解Y Combinator是什么,但我不理解维基百科页面中这个"小说"组合子的例子:
Yk = (L L L L L L L L L L L L L L L L L L L L L L L L L L)
Where:
L = ?abcdefghijklmnopqstuvwxyzr. (r (t h i s i s a f i x e d p o i n t c o m b i n a t o r))
这是如何运作的?
我的大脑似乎是在自虐模式,所以在之后被淹死这个,这个和这个,它想勾搭C#一些DIY.
我想出了下面,我不认为是Y组合子,但它确实似乎设法使非递归函数的递归,没有提及自己:
Func<Func<dynamic, dynamic>, Func<dynamic, dynamic>> Y = x => x(x);
Run Code Online (Sandbox Code Playgroud)
所以给出这些:
Func<dynamic, Func<dynamic, dynamic>> fact =
self => n => n == 0 ? 1 : n * self(self)(n - 1);
Func<dynamic, Func<dynamic, dynamic>> fib =
self => n => n < 2 ? n : self(self)(n-1) + self(self)(n-2);
Run Code Online (Sandbox Code Playgroud)
我们可以生成这些:
Func<dynamic, dynamic> Fact = Y(fact);
Func<dynamic, dynamic> Fib = Y(fib);
Enumerable.Range(0, 10)
.ToList()
.ForEach(i => Console.WriteLine("Fact({0})={1}", i, Fact(i)));
Enumerable.Range(0, …Run Code Online (Sandbox Code Playgroud) 更新:我尝试编写它而不会使它变弱,并且似乎没有泄漏.所以也许问题不再是必要的.
在Objective-C ARC中,当你想让一个闭包能够在闭包内部使用它时,该块不能捕获对它自身的强引用,或者它将是一个保留循环,所以你可以使闭包捕获一个对自身的弱引用,如下:
// This is a simplified example, but there are real uses of recursive closures
int (^fib)(int);
__block __weak int (^weak_fib)(int);
weak_fib = fib = ^(int n) {
if (n < 2)
return n;
else
return weak_fib(n-1) + weak_fib(n-2);
};
Run Code Online (Sandbox Code Playgroud)
我试图将其转换为Swift:
var fib: (Int -> Int)?
fib = { [weak fib] (n: Int) in // 'weak' cannot be applied to non-class type 'Int -> Int'
if n < 2 {
return n
} else {
return fib!(n-1) …Run Code Online (Sandbox Code Playgroud) closures weak-references objective-c-blocks retain-cycle swift
这是一个非常简单的递归函数:
func lap (n: Int) -> Int {
if n == 0 { return 0 }
return lap (n - 1)
}
Run Code Online (Sandbox Code Playgroud)
如果我想将其转换为闭包:
let lap = {
(n: Int) -> Int in
if n == 0 { return 0 }
return lap (n - 1)
}
Run Code Online (Sandbox Code Playgroud)
我收到一个编译器错误:"变量在其自己的初始值中使用"
我对使用定点组合器的实际例子很感兴趣(例如C++中的y-combinator.你有没有使用带有egg的固定点组合器或绑定真实的实时代码?
我在蛋中发现这个例子有点密集:
void egg_example()
{
using bll::_1;
using bll::_2;
int r =
fix2(
bll::ret<int>(
// \(f,a) -> a == 0 ? 1 : a * f(a-1)
bll::if_then_else_return( _2 == 0,
1,
_2 * lazy(_1)(_2 - 1)
)
)
) (5);
BOOST_CHECK(r == 5*4*3*2*1);
}
Run Code Online (Sandbox Code Playgroud)
你能解释一下这一切是怎么回事吗?
是否有一个很好的简单例子,或许使用bind可能比这个更少的依赖?
如果在"use strict"中不允许arguments.callee,我们就做不到
var f = function g() {
//g
}
Run Code Online (Sandbox Code Playgroud)
因为在IE中不起作用(或者说"奇怪")http://kangax.github.com/nfe/#jscript-bugs,那么我们还有哪些其他选项可以引用函数中的匿名函数本身?
在构建一个基于lambda的小型元编程库时,我有必要在C++ 14泛型lambda中使用递归来实现左折叠.
我自己的解决方案是将lambda本身作为其参数之一传递,如下所示:
template <typename TAcc, typename TF, typename... Ts>
constexpr auto fold_l_impl(TAcc acc, TF f, Ts... xs)
{
// Folding step.
auto step([=](auto self)
{
return [=](auto y_acc, auto y_x, auto... y_xs)
{
// Compute next folding step.
auto next(f(y_acc, y_x));
// Recurse if required.
return static_if(not_empty(y_xs...))
.then([=]
{
// Recursive case.
return self(self)(next, y_xs...);
})
.else_([=]
{
// Base case.
return next;
})();
};
});
// Start the left-fold.
return step(step)(acc, xs...);
}
Run Code Online (Sandbox Code Playgroud)
step是从递归开始的"主要"lambda.它返回一个具有所需左折签名的函数(累加器,当前项,剩余项......) …
我想知道 F# 是如何实现的let rec,但我找不到答案。作为前言,我将介绍一下 Scheme 是如何实现的letrec:
let只是lambda定义和应用的语法糖:(let ((x 1)) (+ x 2))
变换为
((lambda (x) (+ x 2)) 1)
(在每种情况下,表达式的计算结果为3)。
letrec也是语法糖,但#f作为初始参数传递给 lambda 的参数,并且set!表达式在主体之前注入letrec,就像在这个转换中一样:(letrec ((x 1)) (+ x 2)) => ((lambda (x) (begin (set! x 1) (+ x 2))) #f)。
考虑到F#没有与Scheme等效的运算符set!,它是如何实现的let rec?它是否将函数的参数声明为mutable,然后在函数体内对它们进行变异?
在另一个问题中,Bob 为无类型lambda演算提供了以下解释器.
data Expr = Var String | Lam String Expr | App Expr Expr
data Value a = V a | F (Value a -> Value a)
interpret :: [(String, Value a)] -> Expr -> Value a
interpret env (Var x) = case lookup x env of
Nothing -> error "undefined variable"
Just v -> v
interpret env (Lam x e) = F (\v -> interpret ((x, v):env) e)
interpret env (App e1 e2) = case …Run Code Online (Sandbox Code Playgroud) 我在工作广告上看到了这个(在SO上):
lambda f: (lambda a: a(a))(lambda b: f(lambda *args: b(b)(*args)))
Run Code Online (Sandbox Code Playgroud)
所以我理解的是它是一个匿名(未命名)函数,它由两个进一步嵌套的匿名函数组成.最里面的函数采用变量的争论列表(*args).
我无法弄清楚它应该做什么.如果没有看到实际的args列表,这实际上是否有效或无法分辨?
我的关闭保留了它自己。它会导致捕获内部的所有其他对象。我可以使用弱引用传递这样的对象,但它并不能解决保留循环的问题。在没有保留周期的情况下使用闭包进行递归的正确方法是什么?
class Foo {
var s = "Bar"
deinit {
print("deinit") // Won't be executed!
}
}
class TestVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let foo = Foo() // Weak works, but not the right solution.
var closure: () -> Void = { return }
closure = {
print(foo.s)
if true {
return
} else {
closure()
}
}
}
}
Run Code Online (Sandbox Code Playgroud) y-combinator ×4
swift ×3
c++ ×2
function ×2
recursion ×2
bind ×1
c# ×1
c++14 ×1
callbyname ×1
closures ×1
combinators ×1
dynamic ×1
f# ×1
haskell ×1
ios ×1
javascript ×1
lambda ×1
lisp ×1
parameters ×1
python ×1
retain-cycle ×1
scheme ×1
scoping ×1