4

Lispで遅延リストとしてストリームを実装するには、 Lispマクロを使用することをお勧めします。

(defmacro cons-stream (a b)
   (cons ,a (delay ,b)))

(defmacro delay (expr)
  `(memo-proc (lambda () ,expr)))

PythonとPerlが同じことをする方法は何でしょうか?

編集。ストリームのようなクールな構成を使用することは可能ですか?

(define primes (sieve (integers-starting-from 2)))

PythonやPerlなどの言語で

4

4 に答える 4

5

Pythonでは、最も近い構造はおそらくジェネレータ式です。

Perlには、ネイティブのレイジーリストはありませんが、言語は、それを構築するために必要なすべてのプリミティブを提供します。私はCPANで利用できるList::Genと呼ばれる怠惰なリストライブラリを書きました。

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)

于 2011-06-27T20:51:27.503 に答える
4

Perl

runrigは、MarkDominusの優れた高次Perlの手法を提案しました。HOPの無料で入手可能なサンプルコードのStreamモジュールを使用すると、エラトステネスのふるいは

#! /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

Python

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
于 2011-06-27T21:13:41.490 に答える
3

perlでは、匿名サブルーチン(LISPのラムダなど)を使用します。高次Perl第6章にはたくさんの例があります

于 2011-06-27T19:31:16.823 に答える
1

実際に何が欲しいかを判断するのは難しいですが、言語によって多くのことが微妙に異なるため、探しているPythonに相当するものはおそらくジェネレーターです。これは、次の値を生成するように要求できる一種の関数です。その後、自分自身を一時停止します。以前は(たとえば)Pythonジェネレーター関数を何に使用できますか?、および他の場所で利用可能なそれらの例とチュートリアルがたくさんあります-たとえば、http://www.dabeaz.com/generators/index.html

于 2011-06-27T19:25:58.880 に答える