10

高階関数の新しいアイデアだと思うものに名前を付けようとしています。重要な部分として、ここにPythonとHaskellのコードがあり、概念を示しています。これについては後で説明します。

Python:

>>> def pleat(f, l):
       return map(lambda t: f(*t), zip(l, l[1:]))
>>> pleat(operator.add, [0, 1, 2, 3])
[1, 3, 5]

Haskell:

Prelude> let pleatWith f xs = zipWith f xs (drop 1 xs)
Prelude> pleatWith (+) [0,1,2,3]
[1,3,5]

推測できるかもしれませんが、シーケンスは繰り返され、渡される関数のパラメーターとして隣接する要素を利用し、結果を新しいシーケンスに投影します。それで、誰かが私たちが作成した機能を見たことがありますか?これは、機能コミュニティの人々にはまったくなじみがありますか?そうでない場合、私たちはそれを何と名付けますか?

---- Update ----

プリーツが勝ちます!

Prelude> let pleat xs = zip xs (drop 1 xs)
Prelude> pleat [1..4]
[(1,2),(2,3),(3,4)]

Prelude> let pleatWith f xs = zipWith f xs (drop 1 xs)
Prelude> pleatWith (+) [1..4]
[3,5,7]
4

16 に答える 16

17

うーん...対位法。

(`ap` tail) . zipWith

名前に値しません。

ところで、クイックシルバーは次のように述べています。

 zip`ap`tail

アステカの連続数の神

于 2010-09-23T03:29:47.777 に答える
6

「fold」に似ていますが、リストを 1 つの値に折りたたまないので、「crease」はどうでしょうか。「折り目」を付け続けると、「折り目」になってしまいます。

料理の比喩を使って、パイの皮をつまむように「つまむ」と呼ぶこともできますが、これは、リストの最後の要素が最初の要素とペアになっている円形のジッパーを示唆しているかもしれません。

def pinch(f, l):
    return map(lambda t: f(*t), zip(l, l[1:]+l[:1]))

(「折り目」または「ピンチ」のいずれかのみが好きな場合は、コメントとしてその旨を記入してください。これらは別の提案でよいですか?)

于 2010-09-22T23:25:36.703 に答える
6

Python では、meld同等のものが itertools レシートにあり、pairwise と呼ばれます。

from itertools import starmap, izp, tee

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

だから私はそれを呼ぶでしょう:

def pairwith(func, seq):
    return starmap(func, pairwise(seq))

アイデンティティ関数で呼び出すと、ペアが返されるだけなので、これは理にかなっていると思います。

于 2010-09-23T01:25:04.967 に答える
5

lジェネレーターでもある場合に機能する Python の別の実装を次に示します。

import itertools as it

def apply_pairwise(f, l):
    left, right = it.tee(l)
    next(right)
    return it.starmap(f, it.izip(left, right))

apply_pairwiseのほうがいい名前だと思います

于 2010-09-22T23:18:03.127 に答える
4

Python のどこにも、これの成文化された名前は見当たりません。それは確かです。「Merge」は良いですが、他のさまざまなコンテキストで使用されます。「プラウ」は使用されない傾向があり、土のラインを着実に押し進める素晴らしいビジュアルを提供します。ガーデニングに時間をかけすぎたのかもしれません。

また、任意の数のパラメーターを受け取る関数を許可するように原則を拡張しました。

あなたも考慮するかもしれません: プリーツ. これは、リスト (布の長いストランドのようなもの) を取得し、そのセグメントをまとめる方法をよく説明しています。

import operator

def stagger(l, w):
    if len(l)>=w:
        return [tuple(l[0:w])]+stagger(l[1:], w)
    return []

def pleat(f, l, w=2):
    return map(lambda p: f(*p), stagger(l, w))

print pleat(operator.add, range(10))
print pleat(lambda x, y, z: x*y/z, range(3, 13), 3)
print pleat(lambda x: "~%s~"%(x), range(10), 1)
print pleat(lambda a, b, x, y: a+b==x+y, [3, 2, 4, 1, 5, 0, 9, 9, 0], 4)
于 2010-09-23T00:20:23.280 に答える
2

これは、画像処理からの畳み込みを思い出させます。しかし、これが数学的に正しいかどうかはわかりません。

于 2010-09-23T10:57:01.063 に答える
2

C ++標準テンプレートライブラリでは、これは隣接する_differenceと呼ばれます(ただし、演​​算子は減算だけでなく、任意の操作にすることができます)

于 2010-09-24T07:20:22.620 に答える
2

これはルビーのようですeach_cons

ruby-1.9.2-p0 > (1..10).each_cons(2).to_a

=> [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10]] 
于 2010-09-23T06:18:28.917 に答える
2

あなたがリスト全体で操作を汚したり汚したりしているように見えるので、私はsmearWithまたはに投票します。smudgeWith

于 2010-09-23T01:17:56.667 に答える
2

これの単純な zip バージョンの一般化されたバリアントは、私がwindow. 現在ghci端末ではありませんが、window n = take n . tails. 次に、関数はzipWith (\[x,yj -> f x y) . window 2です。この種のスタイルは、 f が type の場合に自然にうまく機能します[a] -> b

于 2010-09-23T11:55:21.770 に答える
2

zipWithTailまたはadjacentPairs

于 2010-09-23T00:49:46.237 に答える
1

いいイディオム!Perl でこれを使用して、連続するイベント間の時間を決定する必要がありました。これが私が最終的に得たものです。

sub pinch(&@) {
  my ( $f, @list ) = @_;
  no strict "refs";

  use vars qw( $a $b );

  my $caller = caller;
  local( *{$caller . "::a"} ) = \my $a;
  local( *{$caller . "::b"} ) = \my $b;

  my @res;
  for ( my $i = 0; $i < @list - 1; ++$i ) {
    $a = $list[$i];
    $b = $list[$i + 1];
    push( @res, $f->() );
  }
  wantarray ? @res : \@res;
}

print join( ",", pinch { $b - $a } qw( 1 2 3 4 5 6 7 ) ), $/;
# ==> 1,1,1,1,1,1

List::Utilに依存するようにすれば、実装はおそらくもっときれいになるかもしれませんが、まあ!

于 2010-09-29T15:57:54.327 に答える
1

Mathematica の使用

プラス @@@ パーティション[{0, 1, 2, 3}, 2, 1] またはこれらのより冗長な代替手段のいずれか

Apply[Plus, Partition[{0, 1, 2, 3}, 2, 1], {1}]
Map[Apply[Plus, #] &, Partition[{0, 1, 2, 3}, 2, 1]]

私はこの高階関数を多くの言語で使用して楽しんできましたが、Mathematica で最も楽しんでいました。levelspecオプションを使用して、パーティションと適用に分割すると、簡潔で柔軟に見えます。

于 2010-09-23T05:37:14.427 に答える
1

したがって、これには名前がないように思われるため、隣接する値を一緒にマージしているため、「マージ」または単純な「マージ」をお勧めします。

したがって、マージはすでに行われているので、「メルド」を提案します (または「マージ」はまだですが、「マージ」に近すぎる可能性があります)。

例えば:

meld :: (a -> a -> b) -> [a] -> [b]
meld _ [] = []
meld f xs = zipWith f (init xs) (tail xs)

次のように使用できます。

> meld (+) [1..10]
[3,5,7,9,11,13,15,17,19]
> meld compare "hello world"
[GT,LT,EQ,LT,GT,LT,GT,LT,GT,GT]

2 番目の例はあまり意味がありませんが、クールな例です。

于 2010-09-22T23:35:12.327 に答える
1

私はそれを音楽ソフトウェアの「輪郭」処理に使用していたので、輪郭と呼びたくなるでしょう。

また、音楽処理には「輪郭」と呼ばれる特定の名前が 2 つあります。もう1つは、輪郭が上、下、跳躍、または跳躍のいずれかである洗練された輪郭ですが、跳躍するために半音の差がどれだけ大きくなければならないかについての参照を見つけることができないようです.

于 2010-09-23T17:18:09.103 に答える
0

BinaryOperate または BinaryMerge

于 2010-09-23T01:22:01.247 に答える