10

私の質問は、F# で機能的な方法で継承を処理する方法に関連しています。少し説明するために、簡単な例を挙げます。さまざまな種類の動物からなる世界をモデル化するとします。各動物の種類は、いくつかの属性を他の種類と共有しています (名前、サイズなど)。さらに、それぞれの種類には、他の種類と共有されていない他の種類があります (たとえば、子供の数は犬や猫には関係がありますが、クモには関係ありません)。また、各動物の種類に関連付けられたメソッドまたは関数が存在する場合があり、これらは 2 つの動物の種類で同じである場合と異なる場合があります。つまり、特定の種類に対してオーバーライドされるデフォルトの実装があります。動物の種類ごとに、その種類だけに定義されたメソッドが存在する場合があります。

さて、OOPの世界では、これはおそらく、共通の属性と抽象メソッドを持つ抽象クラスにつながり、その後に動物の種類ごとに派生したクラスが続きます。よくわからないのは、F# でドメイン モデルを機能的に指定する方法です。ここ: F# で抽象クラスとインターフェイスのどちらを使用するか? 「慣用的な F# コードは、C# とは異なる拡張ポイントを使用する (たとえば、関数/インターフェイスを引数として取る) ため、抽象クラスは実際には必要ない」と主張されています。

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

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

F# で継承をモデル化する好ましい方法は、判別共用体だと思います。ただし、これは共有属性とメソッドの問題を解決しません。

上記のモデルに類似したモデルは、ほとんどのエンタープライズ アプリケーションに暗黙的に含まれているため、私の見解では非常に頻繁に使用されます。したがって、これを機能的な方法でどのように処理できるかについての提案はありますか (上記のリンクの下で提案されている方法やその他の提案の例)? それとも、これは機能的アプローチを使用して簡単にモデル化できるドメインではないと言えますか?

ありがとうございました。

4

1 に答える 1

13

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

まず、F# でオブジェクト指向の構造が意味をなす場合に使用してもまったく問題ありません (質問の例はおもちゃのサンプルにすぎないため、そうである場合とそうでない場合があります)。重要な考え方は、F# は継承よりも合成を好むため、(複雑なオブジェクト階層につながる可能性がある) 継承を避け、代わりにさまざまな側面から動物を合成しようとすることです。

第二に、問題を別の方法で説明した場合、判別共用体を使用した完全に優れた関数表現が存在する可能性があります。例えば:

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

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

アイデアは、さまざまな種類の動物 (さまざまな方法で処理できる) が独自の型を持つように型を構造化することです。たとえば、MammalInfo犬と猫に対してのみ意味のある計算を行って実行する関数を作成できます (ただし、クモには意味がありません)。しかし、先に述べたように、問題の説明は本質的にオブジェクト指向であるため、これがどのように行われるかを理解するのは難しいかもしれません.

于 2013-06-13T11:43:10.493 に答える