在Lisp中实现streams as delayed lists recommended以使用Lisp宏。
(defmacro cons-stream (a b)
(cons ,a (delay ,b)))
(defmacro delay (expr)
`(memo-proc (lambda () ,expr)))
Python和Perl的做法是什么?
EDIT。是否可以使用像流这样的酷构造
(define primes (sieve (integers-starting-from 2)))
用Python和Perl等语言
答案 0 :(得分:5)
在Python中,最接近的结构可能是生成器表达式。
在Perl中,没有本机惰性列表,但该语言提供了构建一个所需的所有原语。我编写了一个名为List::Gen的惰性列表库,可以在CPAN上使用。
use List::Gen '*';
my $primes = <2..>->filter(\&is_prime); # where you provide &is_prime
say "@$primes[0..10]"; # lazily finds the first 11 primes
<2..>
位可以详细地写为range(2, 9**9**9)
答案 1 :(得分:4)
runrig suggested马克多米努斯出色的Higher Order Perl技巧。使用HOP免费提供的示例代码中的Stream module,Eratosthenes的筛子
#! /usr/bin/env perl
use strict;
use warnings;
use Stream qw/ filter head node promise show tail upfrom /;
use subs 'sieve'; # no parens on recursive calls
sub sieve {
my($s) = @_;
my $n = head $s;
node $n, promise { sieve filter { $_[0] % $n != 0 } tail $s };
}
sub primes { sieve upfrom 2 }
show primes, 10;
输出:
$ ./primes 2 3 5 7 11 13 17 19 23 29
从gist by alexbowe借用代码,使用流的Python筛选
#! /usr/bin/env python
null_stream = (None, None)
def reduce(f, result, stream):
if stream is null_stream: return result
return reduce(f, f(result, head(stream)), tail(stream))
def take(N, stream):
if N <= 0 or stream is null_stream: return null_stream
return (head(stream), lambda: take(N-1, tail(stream)))
def filter(pred, stream):
if stream is null_stream: return null_stream
if pred(head(stream)):
return (head(stream), lambda: filter(pred, tail(stream)))
return filter(pred, tail(stream))
def integers_from(N): return (N, lambda: integers_from(N+1))
def head((H, _)): return H
def tail((_, T)): return T()
def to_array(stream): return reduce(lambda a, x: a + [x], [], stream)
def sieve(stream):
if stream is null_stream: return null_stream
h = head(stream)
return (h, lambda: sieve(filter(lambda x: x%h != 0, tail(stream))))
def primes(): return sieve(integers_from(2))
print to_array(take(10, primes()))
输出:
$ ./prymes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
在某些语言中,流模式是不可见的。例如,延迟评估是Haskell的一个特性,因此您可以将primes
定义为
primes = sieve [2 ..]
where sieve (x:xs) =
let remains = filter (not . isMultipleOf x) xs
in x : sieve remains
isMultipleOf a b = b `mod` a == 0
答案 2 :(得分:3)
在perl中,您将使用匿名子例程(如LISP的lambda)。 chapter 6的Higher Order Perl
中有很多示例答案 3 :(得分:1)
虽然很难说出你实际想要什么,但由于很多东西在不同语言之间略有不同,所以你所寻找的Python等效物可能是生成器 ,这是一种可以被要求产生下一个值然后暂停自身的函数。它们之前已被涵盖(例如)What can you use Python generator functions for?,并且其他地方有很多示例和教程可用 - 例如,http://www.dabeaz.com/generators/index.html