2009-04-27 78 views
20

是否可以在文件間拆分F#模塊?跨多個文件拆分F#模塊

按照書上的我是,但是這本書可能是過時的 (F#基礎)

+1

這個問題是一種誤導,不清晰和http://stackoverflow.com/questions的DUP/172888/f-defined-and-using-a-type-module-in-the-the-project-in-the-the-project其中有更好的答案。國際海事組織,這是... – 2013-10-07 23:32:18

回答

11

顯然並非如此:

C:\temp\Tim>type 1.fs 2.fs 

1.fs 


#light 
module Module 

let sayHello1 = printfn "Hello, " 

2.fs 


#light 
module Module 

let sayHello2 = printfn "world!" 

C:\temp\Tim>fsc 1.fs 2.fs 
Microsoft F# Compiler, (c) Microsoft Corporation, All Rights Reserved 
F# Version 1.9.6.2, compiling for .NET Framework Version v2.0.50727 

2.fs(2,1): error FS0191: An implementation of the file or module Module has already been given. 

更新:錯誤在F#4.0已經改變,它現:

錯誤FS0248:命名爲「模塊」兩個模塊發生在該組件的兩個部分

其中Module是程序集的完全限定名稱,包括名稱空間部分。

+2

這是不好的,因爲我正在做數據解析,並有許多不同的數據結構,所以我生成一個非常非常非常長的F#文件... – TimothyP 2009-04-27 14:01:31

+0

時間把它分解成常規的.NET類而不是模塊?或者多個F#模塊? – 2009-04-27 14:20:41

+3

不幸的是F#不支持部分類,所以你甚至不能在幾個源文件中分割一個普通的.NET類。 – 2009-04-27 14:21:33

3

我有時在幾個地方分割式,像這樣:

module Foo 

type Partial = Bar | BarInt of int 

module Bar 

type Foo.Partial with 
    member x.Extend = 5 


let b = Foo.Bar.Extend 

其中模塊Foo和酒吧都在不同的文件。

4

像庫爾特說,你可以添加擴展方法類型,從而

// File1.fs 
namespace Foo 

type Mine() = 
    static member f1() =() 

然後

// File2.fs 
type Foo.Mine with 
    static member f2() =() 

Foo.Mine. // both f1 and f2 here 

因爲它是一個類,而不是一個模塊,你失去了做「開放的能力我的'(但獲得超載的能力);因此這可能或可能不是您可以接受的替代方案,具體取決於您所做的事情。

6

類型的擴展很酷,並希望他們將允許跨文件,,而仍然是內部。如果您在同一個文件中執行類型擴展,它將編譯爲一個類,並且該擴展可以訪問私有成員等。如果你在另一個文件中執行它,它只是一個「可選」擴展,就像C#靜態擴展方法一樣。 (儘管F#規格有所不同)。

如果僅在設計人員支持時未解決某些問題,我會感到驚訝。如果內部類型的擴展可能在程序集中的任何地方,那就很漂亮了。

另一種選擇,你想要什麼這可能不是,是創建一個類型和模塊,調用模塊相同的名稱,然後添加ModuleSuffix標誌它:

type Foo() = 
    static member Bar = 1 

[<CompilationRepresentationAttribute(CompilationRepresentationFlags.ModuleSuffix)>] 
module Foo = 
    let Baz = 2 

printfn "%d %d" Foo.Bar Foo.Baz 

這是用來在F#庫中,所以它們可以有一個List類型或其他類型,以及模塊中的大量輔助函數。

1

在我的一個項目中,我們的目標是將操作CpRm分開模塊,但不要求用戶爲兩個任務打開兩個名稱空間。

open Xake.FileTasks 
... 
do! Cp "*/*.exe" "deploy/*.exe" 
do! Rm "*/*.exe" 

我這裏還有我的模塊:

namespace Xake.FileTasks 

[<AutoOpen>] 
module RmImpl = 
    let Rm filemask target = 
... 

,另一種:

namespace Xake.FileTasks 

[<AutoOpen>] 
module CpImpl = 
    let Cp filemask target = 
...