跨多个文件拆分F#模块

时间:2009-04-27 13:41:19

标签: .net f# module

是否可以跨文件拆分F#模块?

根据我的书,但这本书可能已经过时了 (F#的基础)

5 个答案:

答案 0 :(得分: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是程序集的完全限定名称,包括名称空间部分。

答案 1 :(得分: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或其他类型,以及模块中的大量帮助程序。

答案 2 :(得分:4)

像Kurt所说,你可以为类型添加扩展方法,因此

// 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

既然它是一个阶级而不是一个模块,你就失去了“开矿”的能力(但是能够超载);因此,根据您正在做的事情,这可能是也可能不是您可接受的选择。

答案 3 :(得分: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和Bar位于不同的文件中。

答案 4 :(得分:3)

在我的一个项目中,目标是将操作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 =
...
相关问题