型を定義し、その型で動作する関数(インスタンスメソッドではなく)を記述する機能的アプローチをとった場合、コードをどのように整理すればよいですか?F#:型とモジュールを構成するためのベストプラクティス
私は、一般的に、3つの方法のいずれかを行く:
(1):
module MyType =
type MyType (x : int) =
member val X = x with get
let myFunction myType y = myType.X + y
(2):
type MyType (x : int) =
member val X = x with get
[<RequireQualifiedAccess>]
module MyTypeOps =
let myFunction myType y = myType.X + y
(3):
type MyType =
{
x : int
}
static member MyFunction myType y = myType.x + y
プロof(1)は、関数がモジュール内で定義されていることです。 (1)の短所は、タイプがモジュールでも定義されているため、open MyType
をその冗長性の回避策として許可したい場合は、MyType.MyType
のインスタンス化時の冗長性との冗長性が得られません。
(2)の長所は、モジュールで定義された関数であり、モジュールタイプの冗長性はありません。 Conは、モジュールがその型と同じ名前になることはできません。
Pro of(3)は、メソッドが静的で、モジュールタイプの冗長性がないということです。この方法では、いくつかの型(非メソッド値やアクティブなパターンなど)を定義することはできません。
通常、私は(2)を好んでいますが、モジュールに名前を付けるのは嫌ですが、記述的で直感的ではないものがあります。 (2)は私がそれを行う必要があるまれなケースではtype ... and ...
を使用して相互に依存する型を作成することも可能にしますが、アプローチ(1)のような別々のモジュールで定義された型では不可能です。
私の仲間のF#プログラマーはどのようなアプローチを取っていますか?私は何か明白な(またはそれほど明白でない)ものを見落としているのだろうか、もしそうでなければ、モジュールに対応する型と同じ名前を内部に持たせることができないというコンベンションがあるかどうか同じ名前空間。
[F#標準ライブラリのコレクションの種類](https://github.com/Microsoft/visualfsharp/blob/master/src/fsharp/FSharp.Core/list.fs)も同じモジュール(たとえ型に等価なメソッドを持たなくても)型のパターンとして名前を指定します。 –
興味深い選択は、そのCompilationRepresentation属性を使用しています(これまでに見たことはありませんでした。私はC#の相互運用性が懸念されている(これは私の問題ですが)、私の質問に対する素晴らしい応答であるので、この答えのチェックマークを与えています。これは、リストにある3つの方法のうちの2番目と基本的に同じです。さらに、私はメンバメソッドに機能をコード化する必要はありません。私は対応するモジュールでそれを行うのが好きです。なぜなら、自分の型を単にプロパティの宣言に制限したいからです。 – MiloDC
ちょうど好奇心から、QueueがC#の慣用句を作成したいレコードタイプの場合(私は自分の関数を自分の型から離してしまうので、レコードをたくさん使います)、次に使用するアクティブなパターンをどのように定義しますか?メンバーメソッド? – MiloDC