2

私は Scala は初めてですが、古い習慣を捨てて関数型スタイルに乗ろうとしている経験豊富なプログラマーです。私が設計している単純なプログラムには、質問/回答オブジェクトが含まれており、成功に関するいくつかの基本的な事実が保持されています。不変オブジェクトを使用すると、これだけでも十分に簡単ですが、私の目的の一部は、関連する事実をリンクすることです。(例: 「ナイト ライダー カーは?」、「インパラが登場するテレビ番組は?」)

Java では、以下に記述したように、関連付けられたオブジェクトをリンクしただけかもしれませんが、不変の法則がこれを防ぎます (A-> B をリンクし、B -> A をインスタンス化することはできません。

そして、これはおそらく良いことであることを認めなければなりません。関数型スタイルは、この種の循環参照を防ぐように設計されているのかもしれません。しかし、私は問題を修正する方法に途方に暮れています。質問が尋ねられると、私の設計は失敗します。これは、「right 、asked」の新しい値を持つコピー オブジェクトを返すため、オブジェクト リンクは再び落とし穴のように見えます。私の最善の推測は、Q/A データのみに基づいて、ヘルパー オブジェクトでリレーション セットを構築することですが、別のデータ パターン オブジェクトをジャグリングすることは避けたいと思います。

ありがとうございました - オハイオ州コロンバスのティム

case class FactItem (

    q:String, a:String,
    right: Double = 0.0,
    asked: Double = 0.0,
    linked: List[FactItem] = List[FactItem]()

    ) { 

  def rP = right / asked //right per

  def subLink( l:List[FactItem] ) : FactItem =  {
    this.copy( linked = l-this)

  } 
4

2 に答える 2

2

これを不変に行う方法については、この質問を参照してください: scala: 基本的な親子関係をモデル化する方法

ヒント: アイテムのリストを含めないようにオーバーライドしない限り、ケース クラスでこれを行わないでくださいtoString(このアイテムの toString にはリスト内の他のすべての toString が含まれているため、循環参照があるとスタックがオーバーフローします)。 )。

private varListを作成し、リスト項目への参照を取得したら、すべての項目を作成するコンパニオン オブジェクトのファクトリ メソッドからすべてのインスタンスを更新することで、多くの頭痛の種を回避できます。public セッターがなくても、事実上不変です。

同様の、おそらく理論的にはより適切なアプローチはStream、コンパニオン オブジェクトのマップから値を取得するリストを作成することです。アイテムが作成されている間、マップは可変でなければなりませんが、少なくともアイテムは完全に不変です。

于 2012-06-06T00:09:42.143 に答える
2

本当の答えは、そうしないことです。両方を指す「関係」オブジェクトを作成します。

ここで、"Relation" を指しているオブジェクトから "Relation" 自体に移動し、次に別のオブジェクトに移動するにはどうすればよいのか疑問に思われることでしょう。これはジッパーを使用して行います。オブジェクト「a」に直接移動する代わりに、ツリー/グラフを取得し、ジッパーを「a」に移動します。そこから「関係」に戻って「b」に進むか、ジッパーが横方向の動きを認識している場合は「a」から「b」に直接移動できます。

残念ながら、便利なジッパーに関しては、Scala は Haskell に大きく遅れをとっています。ただし、概念を理解していれば、いつでもデータ構造用に作成できます (これについては、調査するために残します)。

適用される可能性のある別の答えがまだあります。他のオブジェクトを分解して (変更を加えて) 組み合わせる方法を知っているオブジェクトである「レンズ」がある場合があります。クラスの基本的な設計では、(可変性または遅延のトリックを使用して) それを許可する必要がありますが、レンズは操作自体の醜さを隠します (他の多くの気の利いた機能を提供する以上に)。

最後に、Scala が純粋な関数型ではないのには正当な理由があることを強調したいと思います。Odersky は、純粋な関数型言語以外にも価値があると考えており、その力を利用できるようにしてほしいと考えています。

于 2012-06-06T03:24:03.987 に答える