数週間、私はオブジェクト間の関係について考えてきました - 特に OOP のオブジェクトではありません。たとえば、C++ では、他のオブジェクトへのアクセスが必要な構造内のポインターまたはポインターのコンテナーをレイヤー化することによってそれを表すことに慣れています。オブジェクトA
に へのアクセスが必要な場合、 inB
を見つけることは珍しくありません。B *pB
A
しかし、私はもうC++プログラマーではありません。関数型言語を使用してプログラムを作成しています。特に、純粋な関数型言語であるHaskellを使用しています。ポインタとか参照とかそういうのも使えるんですけど、「Haskellじゃないやり方」とか、ちょっと違和感があって。
それから、私はそのすべての関係についてもう少し深く考え、ポイントに達しました:
「なぜ、このような関係を重ねることで表現するのでしょうか?
私はすでにそれについて考えている何人かの人々を読みました(ここ)。私の見解では、明示的なグラフを介して関係を表現する方がはるかに優れています。これにより、型のコアに焦点を当てることができ、後でコンビネーターを介して関係を表現できるからです (SQL と少し似ています)。
コアとは、 を定義するときに、 が何に依存するかではなく、 で構成さA
れるものを定義することを期待するということA
です。たとえば、ビデオ ゲームで 型がある場合、やその種類について話すのは正当ですが、 や について話す場合はどうなるでしょうか。もうよくわかりません。それで:Character
Trait
Skill
Weapon
Items
data Character = {
chSkills :: [Skill]
, chTraits :: [Traits]
, chName :: String
, chWeapon :: IORef Weapon -- or STRef, or whatever
, chItems :: IORef [Item] -- ditto
}
私にはデザインの面で本当に間違っているように聞こえます。私はむしろ次のようなものを好むだろう:
data Character = {
chSkills :: [Skill]
, chTraits :: [Traits]
, chName :: String
}
-- link our character to a Weapon using a Graph Character Weapon
-- link our character to Items using a Graph Character [Item] or that kind of stuff
さらに、新しい機能を追加する日が来たら、新しいタイプ、新しいグラフ、およびリンクを作成するだけです。最初の設計では、型を壊すCharacter
か、何らかの回避策を講じて拡張する必要がありました。
その考えについてどう思いますか。純粋関数型言語であるHaskellでそのような問題に対処するには、何が最善だと思いますか?