web-dev-qa-db-ja.com

関数型言語でのゲッターとセッター

関数型プログラミングの原則の1つは、純粋関数の使用です。 Pure関数は、副作用がなく、参照を透過的にする関数です。

ゲッターは参照透過ではありません-ゲッターの呼び出しの間にセッターが呼び出された場合、そのパラメーターがない(通常はパラメーターがない)場合でもゲッターの戻り値は変化します

セッター副作用を生成-セッターを呼び出すと、通常、戻り値ではない値が操作されます(実際、伝統的にセッターは何も返しません)。

私はScala)で知っています。Javaのような言語で行うように、2つのパラダイム(関数型とオブジェクト指向)をメッシュ化し、ゲッター/セッターを使用しているという事実を受け入れます。

Haskellのような言語(私は流暢ではありませんが、「純粋な」関数型言語に当てはまると言われています)では、ゲッターが参照透過でセッターであるようにオブジェクトのプロパティをモデル化する方法に興味があります副作用はありませんか?

解決策は、セッターが呼び出されたオブジェクトのコピーをセッターの戻り値として返すことであり、このコピーにはプロパティ値の変更が含まれていますか?

9
ThaDon

丁度。ケースクラスメソッドcopy、またはレンズの一般的な概念を参照してください。

特に、状態を変更する必要がある場合は、Stateモナドを使用します。その状態モナドへの変更は、レンズを介して行うことができます。これにより、「状態」からの情報の抽出と変更が容易になります。

「状態」のような深い構造とそれに変更を加えることから生じる一般的な問題については、 この質問 も参照してください。もっと深く知りたい場合は、レンズとジッパーの両方に適切なリンクがあります。

7

まあ、Haskellでは、オブジェクトは(通常)不変なので、ゲッター(レコード構文を使用すると取得されます)またはゲッターのように機能する関数are参照透過です。そして、オブジェクトに値を「設定」しません-何かを作成した場合、古いオブジェクトに似ているnewオブジェクトを作成しますが、いずれかのフィールドの値が異なります。これも純粋な関数です。

11
MatrixFrog