2017-06-12 39 views
4

在閱讀F# Component Design Guidelines後,我看不到任何評論,我是否應該聲明模塊&其類型具有相同的名稱。F#指南建議聲明具有相同名稱的模塊和類型嗎?

通常我的項目沒有任何循環依賴性,所以我不需要創建一個新模塊(例如InfrastructureTypesDomainTypes)將每個類型放在一個地方。

例如,如果我有一個記錄類型System及其一堆功能,我應該將所有內容放入一個模塊文件中嗎?這是我的嘗試:

// 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#核心庫本身就是一種常見的方法有一個模塊具有相同名稱在同一水平(A型,而不是具有模塊內等種類在你的例子中)。例如,有一個List<'a>類型和一個List模塊,其中包含包含用於使用它的函數的函數。同樣與OptionSetResult

如果你已經有一個給定名稱的類型,有您可以添加到允許創建具有相同名稱的模塊,而不編譯器錯誤屬性:[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]

但是,由於F#4.1,這是隱含的。因此,定義一個與該類型名稱相同的模塊可以正常工作,並且在編譯代碼時,Module這個單詞將位於模塊名稱的末尾。

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

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

我認爲這一切都意味着這可以是一個有效的模式在F#中使用。特別是當你有一個很好的抽象。您可能想查看「抽象數據類型」,因爲我認爲它們適用於此處。

看看上面給出的例子,這通常是更多的庫級模式,但我聽說過它可以應用於應用程序代碼的良好效果。我可以想象它可以幫助您思考並強制抽象邊界並保持代碼的組織。

+2

@MiP - 請注意,類型和模塊在相同級別上定義*。在你的例子中,你的文件以'module System'開始,它是「該文件的全部其餘部分位於名爲'System'的模塊內的簡寫。鑑於正確的方法是將類型和模塊定義在同一級別。我無法在評論框中說清楚,所以我會發佈一個解答。 – rmunn

+0

@rmunn謝謝,我已經說得更清楚了。 – TheQuickBrownFox

+0

@TheQuickBrownFox通過您的解決方案,我需要製作一個主模塊,讓這些模塊和類型處於同一水平,不是嗎? – MiP

相關問題