高尔夫定点组合器


9

用您选择的语言编写尽可能少的字符的定点组合器。

  • 自由形式(即最短的形式):整个程序,实际功能,代码段
  • 如果您有一个标准库,则可能无法使用
  • 但是,您可能希望从其他高级函数中提取它,而不是从基础上构造它

请包括将其用作演示的递归阶乘或斐波那契。

在这个问题中,自引用是可以接受的,其目的仅仅是将其从递归函数中删除。


惰性语言实现可以吗?(您接受(define Y(lambda(f)(f(Y f))))吗?)
— Eelvex 2011年

您可以使用所要求的示例之一进行演示的任何实现都可以。
— JB

1
如果我没记错的话,严格来说,术语“ Y组合器”专门指Haskell Curry发现的单个定点组合器λf。(λx.f(xx))(λx.f(xx))。
— 乔伊·亚当斯

@Eelvex:到目前为止,显然两个答案(包括OP自己的答案)都使用作弊方式,因此,我认为这样还可以。:-P就个人而言,我宁愿使用@Joey的方法,并说只有真正的(非自我引用)Y组合器才能使用。;-)
— Chris Jester-Young

@克里斯:天哪。最初我就是这样想的,然后我...一路上忘记了。现在进行更改为时已晚,我们将不得不提出另一个问题。
— JB

Answers:


13

Haskell:10个字符

y f=f$y f

用于创建阶乘或nth-Fibonacci的递归定义的示例:

> map ( y(\f n->if n <= 1 then 1 else n*f(n-1)) ) [1..10]
[1,2,6,24,120,720,5040,40320,362880,3628800]

> map ( y(\f n->if n <= 1 then 1 else f(n-1)+f(n-2)) ) [0..10]
[1,1,2,3,5,8,13,21,34,55,89]

不过,更常见的使用y方式是直接生成这些序列,而不是将其作为函数:

> take 10 $ y(\p->1:zipWith (*) [2..] p)
[1,2,6,24,120,720,5040,40320,362880,3628800]

> take 11 $ y(\f->1:1:zipWith (+) f (tail f))
[1,1,2,3,5,8,13,21,34,55,89]

当然,对于Haskell,这有点像在桶中射鱼!该Data.Function库具有称为的功能,fix但实现起来较为详细。


4

Perl,37岁

sub f{my$s=$_[0];sub{$s->(f($s),@_)}}

析因演示:

sub fact {
  my ($r, $n) = @_;
  return 1 if $n < 2;
  return $n * $r->($n-1);
}
print "Factorial $_ is ", f(\&fact)->($_), "\n" for 0..10;

斐波那契演示:

sub fib {
  my ($r, $n) = @_;
  return 1 if $n < 2;
  return $r->($n-1) + $r->($n-2);
}
print "Fibonacci number $_ is ", f(\&fib)->($_), "\n" for 0..10;

3

GNU C-89个字符

#define fix(f,z)({typeof(f)__f=(f);typeof(__f(0,z))x(typeof(z)n){return __f(x,n);}x(z);})

例:

#define lambda2(arg1, arg2, expr) ({arg1;arg2;typeof(expr)__f(arg1,arg2){return(expr);};__f;})

int main(void)
{
    /* 3628800 */
    printf("%ld\n", fix(lambda2(
        long factorial(int n), int n, 
            n < 2 ? 1 : n * factorial(n-1)
        ), 10));

    /* 89 */
    printf("%ld\n", fix(lambda2(
        long fibonacci(int n), int n, 
            n < 2 ? 1 : fibonacci(n-1) + fibonacci(n-2)
        ), 10));

    return 0;
}

1

k2,12个字符

明显的自引用实现最短。这是良好的语言设计的标志。不幸的是,K不是很懒,所以我们只能按值管理电话。

Y:{x[Y[x]]y}

尽管我在下面的示例中假定为k2,但该定义也应该在k4和q中正常工作。

  Y:{x[Y[x]]y}
  fac: {[f;arg] :[arg>0; arg*f[arg-1]; 1]}
  Y[fac] 5
120
  fib: {[f;arg] :[arg>1; f[arg-1] + f[arg-2]; arg]}
  Y[fib]' !10
0 1 1 2 3 5 8 13 21 34

适度的18个字符可以让我们准确地转录(λx. x x) (λxyz. y (x x y) z)为K。

{x[x]}{y[x[x;y]]z}

也许有一天(k7?),看起来可能像Y:{x Y x}。


0

Python 3,30字节

Y=lambda f:lambda a:f(Y(f))(a)

演示:

Y=lambda f:lambda a:f(Y(f))(a)
quicksort = Y(
lambda f:
    lambda x: (
        f([item for item in x if item < x[0]])
        + [y for y in x if x[0] == y]
        + f([item for item in x if item > x[0]])
    ) if x
    else []
)
print(quicksort([1, 3, 5, 4, 1, 3, 2]))

学分:https : //gist.github.com/WoLpH/17552c9508753044e44f


Python 3具有过滤器。我也很抱歉忽略了此评论是一个玩笑
— Cyoce '16

Python 3的过滤器返回过滤器对象而不是列表。使用过滤器将较不易读或Python式。
— Labo

这将是较少的Pythonic,但更多的是函数式编程,这就是我的观点
— Cyoce '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.