2017-06-12 7 views
4

F# Component Design Guidelinesを読んだ後、同じ名前を持つモジュール&を宣言する必要があるかどうかについてのコメントは表示されません。F#ガイドラインは、同じ名前のモジュールとタイプを宣言することをお勧めしますか?

通常、私のプロジェクトには周期的な依存関係がないため、すべてのタイプを1つの場所に入れるために新しいモジュール(例:InfrastructureTypesまたはDomainTypes)を作成する必要はありません。

たとえば、レコードタイプがSystemであり、その機能が多数ある場合、すべてを1つのモジュールファイルに入れる必要がありますか?これは私の試みです:のようにモジュール内の型を有するとは対照的に、

// System.fs 
module System 

type rec System = 
    { name : string 
     children : System list } 

let init() = { name = ""; children = [] } 

let addChild system child = 
    { system with system.children = child :: system.children } 

let removeChild system child = 
    let rec removeChild children acc child = 
     match children with 
     | c :: children -> 
      if c <> child then removeChild children (c :: acc) child 
      else removeChild children acc child 
     | [] -> List.rev acc 

    let children = removeChild system.Children [] child 
    { system with system.children = children } 

答えて

6

それは同じレベル(で同じ名前を持つモジュールと型を持つようにF#コアライブラリ自体に一般的なアプローチでありますあなたの例では)。たとえば、List<'a>タイプとそれに対応する関数を含む関数を含むListモジュールがあります。すでに与えられた名前のタイプを持っていた場合も同様OptionSetResultなど

で、あなたはコンパイルエラーなしで同じ名前のモジュールを作成できるようにするために追加することができます属性があります:[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]

しかし、F#4.1以降、これは暗黙的です。したがって、型と同じ名前のモジュールを定義するだけで動作し、コードがコンパイルされるときにはModuleという単語がモジュール名の最後になります。

これは、これがF#で使用する有効なパターンである可能性があると考えています。特にあなたが良い抽象を持っているとき。私がここに当てはめると思うように、「抽象データ型」を調べたいかもしれません。

私が上に示した例を見ると、これは通常はライブラリレベルのパターンですが、アプリケーションコードでもその効果があてはまります。私は、抽象境界について考え、実行し、コードを整理しておくのに役立つと想像することができます。

+2

@MiP - 型とモジュールは同じレベル*で定義されていることに注意してください。あなたの例では、ファイルは 'module System'で始まります。これは"このファイルの残りの部分は 'System'という名前のモジュールの中にあります。それに対して正しい方法は、タイプとモジュールの両方を同じレベルに定義することです。私はコメントボックスでそれを明確にすることはできませんので、私はこれを拡大して答えを投稿します。 – rmunn

+0

@rmunnありがとう、私はもう少し明確にした。 – TheQuickBrownFox

+0

@TheQuickBrownFoxあなたのソリューションでは、これらのモジュールとタイプを同じレベルにするためにマスターモジュールを作成する必要がありますか? – MiP

関連する問題