質問

私は私の現在のOOP状態の概念、そしてそれはHaskellのか、Clojureのような関数型言語で行われるような方法の違いのまわりで私の頭を取得助けが必要。

陳腐な例を使用するには、我々はどのような/単純化された銀行口座のオブジェクト/構造体を扱っているとしましょう。 OOP言語では、私は、金利のようなもののためにインスタンス変数を持っているでしょうBankAccountの、への参照を保持しているいくつかのクラスを持っているだろう、と一般的にオブジェクトの状態を変更し、setInterestRateのようなメソッド()は何も返しません。 Clojureのを言うのでは、私は銀行口座の構造体(見せかけのハッシュマップ)、および銀行口座のパラメータやその他の情報を取る特別な機能を持っており、新しい構造体を返すと思います。だからではなく、元のオブジェクトの状態を変更するので、私は今、必要な変更で返される新しいものを持っています。

だから... ...私はそれで何をしますか?どんな変数古い銀行口座を参照して上書きしますか?もしそうなら、それは状態変化OOPのアプローチに比べて利点がありますか?最後に、両方のケースでは、1つが必要な変更を持つオブジェクトを参照する変数を持っているようです。私はとして薄弱、私は何が起こっているの唯一の漠然とした概念を持っています。

私は任意の助けのために、感謝の意味を成していたことを願っています!

役に立ちましたか?

解決

純粋な機能的なスタイルで、あなたは、任意の変数を上書きすることは決してないだろう。

アナロジーは物理学の時空になります。あなたは、3Dとして世界を考える場合には、オブジェクトが固定位置を持っていない - 彼らは時間をかけて移動します。物理的な世界に負担する数学をもたらすために、我々はそのための時間の次元を追加して、特定の時間にさまざまなプロパティの値を検討します。そうすることで、我々は、定数に我々の研究のオブジェクトを作りました。同様に、プログラミング中、不変の値と協力していたべき概念単純があります。現実世界のアイデンティティを持つオブジェクトは、不変の値(増加時間にオブジェクトの状態)のシーケンスとしてではなく変化する単一の値としてモデル化することができる。

もちろん、「オブジェクトID」への値のシーケンスを関連付ける方法の詳細については、少し毛深いことができます。 Haskellはモナドのあなたのモデルの状態を聞かせてそれを持っています。 官能性反応性プログラミングにはIという、純粋な機能の更新と、世界でモデリングオブジェクトでより多くのリテラルの試みでありますプログラミングのための非常に有望な方向だと思います。

私はClojureのは、Haskellのとは異なり、純粋ではないことに注意し、あなたが示唆したように、あなたは、変数を更新することができます。あなただけの高いレベルでいくつかの変数を更新している場合、あなたはおそらくまだ関数型プログラミングの概念を簡単にする利点の多くをお楽しみいただけます。

他のヒント

おそらく、OOの世界で、あなたはループを持っており、要求に応じて何度も何度もこれらの銀行口座を変更しています。あなたがアカウントの全体のポートフォリオを持っており、これらはタイプのポートフォリオを持っているとしましょう。そして、Haskellであなたは純粋な機能を記述します。

updatePortfolio :: Request -> Portfolio -> Portfolio

そして、あなたのメインループは、標準入力からの要求を読んで、最新のあなたのポートフォリオを維持することがあります。 (例では、あなたが同様のポートフォリオを書くことができない限り、多くの使用ではありませんが、それは簡単です。)

readRequest :: IO Request  -- an action that, when performed, reads a Request with side effects

main :: Portfolio -> IO ()  -- a completely useless program that updates a Portfolio in response to a stream of Requests

main portfolio = do req <- readRequest
                    main (updatePortfolio req)

と、今私はあなたの可変状態に何が起こったのかを見願っています:一般的な機能のプログラムでは、変更の状態は、関数にパラメータとして渡されます。状態changessは、新しい関数呼び出しを行うと。コールは末尾位置(あなたが検索できる「適切な末尾呼び出し」)であるので、それは、追加のリソースを使用しないと、コンパイラはアセンブリ・コードを生成し、実際にそれがループを生成し、それを指すポインタを保持しますレジスタにポートフォリオを刻々と変化する。

これは非常におもちゃの例ですが、私はそれはあなたの関数型言語の風味の少しを与える願っています。

だから... ...私はそれで何をしますか?古い銀行口座を参照してどんな変数上書きしますか?

はい

その場合、状態変化OOPのアプローチに勝る利点を持っていないこと?

あなたは、その構造体上で行うどんなアクションの計算に時間がかかるし、何かが途中で起こり、あなたは元の構造体に戻す必要があるか計算がエラーが発生したとしましょう。解釈を使用すると、オブジェクト指向の私に提示してきたのに十分な情報が失敗した関数呼び出しから与えられた場合を除き、データが破損している--itの未知の可能性(あなたは不変のオブジェクト指向言語を持つことができるので、参照を使用して)、それが失敗した提案することができますひどく。機能的なアプローチでは、あなたが最初にコピーを作っ--becauseあなたの元のデータ構造が正しいことを確かに知っています。

マルチスレッドアプリケーションでこのシナリオを拡張します。我々はすべてそれを私たち自身のバージョンを持っているので、私たちは、誰も私たちがしているデータ構造を使用していないことを保証することができます。

さらに、我々はからコピーされた他の構造体からのデータを使用してスペースを節約することができます。リストの先頭に要素を追加するときに典型的な例です。我々は、第二の要素へのポインタ、我々は最初のサイズだけで両方のリストを参照することができる最初の要素へのポインタを持っている場合(以下を参照)。不変性がなければ、私たちはこれを保証することはできません。

        b__
           |  
a -> [6|] -+-> [5|] -> [4|] -> [3|] -> [2|] -> [1|x]

純粋な機能であるHaskellの、見言語は一切再割り当てだけでなく、無他の副作用を持っていません。の<のhref = "HTTPで、IOを行うために:/ /www.haskell.org/haskellwiki/IO_inside#Welcome_to_the_RealWorld.2C_baby_:.29" のrel = "nofollowをnoreferrer"> IOモナドののそれは実際の現実世界と持っている世界の新しいインスタンス、例えば、コンソールに表示される新しいテキストます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top