我有以下工作的F#源文件
namespace Namspa1
[<AutoOpen>]
module M1 =
let [<Literal>] constant1 = "Hello, "
type Greeter(name) =
member x.Greet() = sprintf "%s%s" constant1 name
module M2 =
let greet name = Greeter(name).Greet()
这有效,但是我要定义的功能是在定义了constant1的同一模块M1中打招呼。 换句话说,我只想使用一个文件即可获取
Namspa1.M1.constant1
Namspa1.Greeter
Namspa1.M1.greet //not Namspa1.M2.greet
如果我尝试将greet函数定义更改为
module M1 =
let greet name = Greeter(name).Greet()
我收到M1的重复定义错误。
我该怎么做?
编辑
建议使用属性CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)修复重复定义错误,这是正确的,因此谢谢。
但是我的请求是关于扩展M1。我希望能够像在M1中定义函数一样使用M1.greet。 例如,如果我尝试在外部使用定义(例如另一个源文件),则可以使用M2.greet,因此我想使用M1.greet,这对于属性是不可能的
答案 0 :(得分:3)
可以通过将CompilationRepresentation
属性设置为CompilationRepresentationFlags.ModuleSuffix
来实现。像这样扩展模块不是预期的用例,因此第二个模块定义需要移到单独的源文件中。
第一个文件:
namespace Namspa1
[<AutoOpen>]
module M1 =
let [<Literal>] constant1 = "Hello, "
type Greeter(name) =
member x.Greet() = sprintf "%s%s" constant1 name
第二个文件:
namespace Namspa1
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module M1 =
let greet name = Greeter(name).Greet()
从技术上讲,它会生成一个名为M1Module的模块,这将影响从其他.NET语言的访问。
答案 1 :(得分:2)
使用recursive namespace可以实现您想要的目标。在声明名称空间时,请注意rec
关键字。
namespace rec Namspa1
[<AutoOpen>]
module M1 =
let [<Literal>] constant1 = "Hello, "
let greet name = Greeter(name).Greet()
type Greeter(name) =
member x.Greet() = sprintf "%s%s" constant1 name