2013-06-13 16 views
7

私の質問は、F#で機能的な方法で継承を処理する方法に関するものです。それを少し説明するために、私は簡単な例を挙げます。様々な種類の動物からなる世界をモデル化したいとします。各動物種は、他の種類(例えば、名前、サイズなど)といくつかの属性を共有します。さらに、各種類には、他人が共有していない他の種類があるかもしれません(例えば、子どもの数は犬や猫には関係しますが、例えばスパイダーではありません)。また、各動物種に関連する方法または機能が存在し得るが、これは2種の動物種について同じであってもなくてもよい。すなわち、特定の種類に対して過剰になるかもしれないデフォルトの実施が存在する。各動物種は、その種のためにのみ定義された方法を有することができる。F#および継承のモデリング

さて、OOPの世界では、これはおそらく、各動物種の派生クラスに続いて、共通の属性と抽象メソッドを持つ抽象クラスにつながります。 F#でドメインモデルを機能的に指定する方法がわかりません。ここでは: Which to use , abstract class or interface in F#?は「慣用的なF#コードは、関数/インタフェースを引数として取るなど、C#とは異なる拡張ポイントを使用するため、抽象クラスは本当に必要ない」と主張しています。

これが採用すべき方法であれば、これのいくつかの基本的な例を提供することは可能でしょうか?

これについて私がさらに考えているように、属性はいくつかの構造体にカプセル化されている必要があります。そして、F#のこの点で最も慣用的な構造が記録されています。それは、特定の「子」に対応する他のレコード、すなわち継承ではなく合成に含まれる親レコードがあることを意味しますか?しかし、これは慣用的ではなく、特に優雅でもない回避策として私には思われます。

F#での継承をどのようにモデル化するのが好ましいかは、差別化された共用体であると思います。しかし、これは属性やメソッドの共有の問題を解決するものではありません。暗黙的に、ほとんどのエンタープライズアプリケーションに含まれているので、前述したのと同様の

モデルは、私の見解ではかなり頻繁にあります。したがって、どのようにこれを機能的な方法で扱うことができるかについての提案はありますか(上記のリンクまたは他の提案の中で示唆されている方法の例)?あるいは、これは機能的アプローチを用いて容易にモデル化できる領域ではないと言うでしょうか?

ありがとうございます。

答えて

9

この例の説明は、すでにオブジェクト指向プログラミングモデルを前提としています。特定のタイプの動物に対して定義されたオーバーライドやメソッドなど、オブジェクト指向の用語で問題を記述しています。これは、あなたの質問がすでにオブジェクト指向の概念を答えていると仮定しているので、あなたに賢明な代替機能表現を与えるのが難しくなります。

まず、彼らが(あなたの質問の例は単なるおもちゃのサンプルなので、これはしてもしなくてもよい場合があります)意味をなさないときF#でのオブジェクト指向構文を使用するように完全に罰金です。重要なアイデアはF#が継承よりも構図を好んでいるため、おそらく継承(複雑なオブジェクト階層につながる可能性があります)を避け、さまざまな側面から動物を構成しようとします。

第二に、あなたが別の方法であなたの問題を説明している場合、その後、判別共用体を使用して完全に罰金関数表現があるかもしれません。たとえば:

type MammalKind = Cat | Dog 
type MammalInfo = { Legs : int; Children : int } 

type Animal = 
    | Mammal of MammalKind * MammalInfo 
    | Spider of (...) 

アイデアは、動物の種類は、(あなたが別の方法で処理できることを)自分のタイプを持つようにタイプを構築することです。例えば、MammalInfoをとる関数を書くことができ、犬や猫にしか意味をなさない(スパイダーではない)いくつかの計算を実行することができます。しかし、前述したように、問題の説明は本質的にオブジェクト指向であるため、これがどのように行われるのかを知ることは難しいかもしれません。

+0

良い質問、素晴らしい答え! – mydogisbox

+0

Tomas Petricekの答えはとても良いものです。ノーマン・ラムゼイの次の回答をお勧めします。http://stackoverflow.com/a/2079678/631115 – Shredderroy

+0

Tomas、この例をありがとう。それは素敵でシンプルです。 私が書いた記述に関しては、記述と可能な実装(抽象クラ​​ス)とを明確に区別しようとしました。 一般的な機能(動物の名前をすべての哺乳類のすべての動物またはいくつかの子供の係数に変換するなど)は、特定のタイプ(AnimalInfo - まだ作成されていない - MammalInfo)をメンバーとして宣言するか、自由に宣言するか(割り当てられていないかどうか)を定義します。また、これは型の構成と排他的に関連していないより一般的な問題です。 – user2039784