3

コレクション A が 1 つあり、コレクション A からコレクション B を作成する必要があります。最も単純なケースでは、このmap方法を使用することができますが、B の要素を作成する各ステップで、コレクション内に既にある要素にアクセスするには、 が必要です。

B を作成する複数の可能性を念頭に置いています。

  • B の可変コレクションを使用してから、それを不変に変えます
  • コレクション B の基礎となるビルダーの使用
  • 空の B で foldLeft を使用し、クロージャ内で成長させます

慣用的なアプローチはありますか、または少なくともさまざまなユースケースに応じてピックアップする方法はありますか?

4

2 に答える 2

6

最も慣用的なのはfoldLeft-- です。折り畳みは、関数型プログラミングでは非常に自然に行われます。別の可能性はscanLeft、簿記をわずかに減少させる可能性がある です。

一方、これが実際にどのように見えるかは、Stateモナドの反復です。『 Functional Programming in Scala』という本には、演習の 1 つとして、これによく似た内容があります。

Stateモナドは基本的に の関数のモナド オーバー タイプですAS => (S, A)、通常は一般的な操作を容易にするいくつかの特殊なメソッドを備えた適切なタイプとして宣言されます。

あなたの例では、状態は最後の結果のSになりますOption[A](または、適切な場合は の「ゼロ」A)。次に、コレクションをその型Tから関数S => (S, A)(または状態モナド型) にマップし、Coll[S => (S, A)].

そこから、 を取得し、初期状態をフィードしてから、を取得することができsequenceます (これはモナドの場合に変わりsequenceます-- The Essence of the Iterator Pattern を参照してください) 。M[N[A]]N[M[A]]MNS => (S, Coll[A])Coll[A]

Web 上には状態モナドに関するリソースがたくさんありますが、個人的には他のほとんどのモナドよりも扱いが難しいと感じました。「状態」モナドの名前が間違っている可能性があると誰かが私に言いましたが、それは実際には「状態プロセッサ」モナドであり、私には理にかなっています。

とにかく、あなたの選択肢からfoldLeftは最も慣用的ですが、状態モナドアプローチはこのタスクに非常に適しています。

于 2013-09-09T10:16:41.853 に答える