将F#模块拆分为同一文件中的多个部分
我有以下工作F#源文件将F#模块拆分为同一文件中的多个部分,f#,F#,我有以下工作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() const
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是一个值,因此必须位于模块内部
- 因此,文件中的时间必须较晚;我希望它在名称空间中,而不是在模块中,因此它是非缩进的
- 最后,greet是一个函数,所以它必须在一个模块中,我想使用相同的模块M1。它还使用Greeter,因此它必须位于类型定义之后
module M1 =
let greet name = Greeter(name).Greet()
我得到了M1的重复定义错误
我该怎么做
编辑
有人建议使用属性CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)修复重复定义错误,这是正确的,因此感谢您的帮助
然而,我的请求是关于扩展M1。我希望能够使用M1.greet,就好像函数是在M1中定义的一样。
例如,如果我尝试在外部使用定义(例如,另一个源文件),我可以使用M2.greet,因此我想使用M1.greet,这在属性中是不可能的,这可以通过将
compilementrepresentation
属性设置为。像这样扩展模块不是预期的用例,因此第二个模块定义需要移动到单独的源文件中
第一个文件:
namespace Namspa1
[<AutoOpen>]
module M1 =
let [<Literal>] constant1 = "Hello, "
type Greeter(name) =
member x.Greet() = sprintf "%s%s" constant1 name
名称空间Namspa1
[]
模块M1=
让[]constant1=“你好,”
类型迎宾员(姓名)=
成员x.Greet()=sprintf“%s%s”名称
第二个文件:
namespace Namspa1
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module M1 =
let greet name = Greeter(name).Greet()
名称空间Namspa1
[]
模块M1=
让greet name=Greeter(name).greet()
从技术上讲,它会生成一个名为M1Module的模块,该模块将影响其他.NET语言的访问。您可以使用。声明名称空间时,请注意
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
namespace rec Namspa1
[]
模块M1=
让[]constant1=“你好,”
让greet name=Greeter(name).greet()
类型迎宾员(姓名)=
成员x.Greet()=sprintf“%s%s”名称
我需要重构Greeter
以便它在构造函数中接受该常量值。为什么要将其行为与模块中的编译时常量耦合?为什么不直接内联这个常量呢?@Taylor Wood重构它的方法有很多,但我想知道是否有可能按照我的要求去做,或者这是编译器或语言的限制。此外,M1可以包含许多元素,而不仅仅是一个常量,这是一个简单的特别示例,用ModuleSuffix编译表示法清楚而简洁地说明了我的问题,M1.greet可以从其他F#源文件中访问。不过递归名称空间是一个更好的解决方案。@cadull我使用的是VS 2017,我只能从不同的文件访问M1.constant1,M1.greet只能在同一个文件中访问。如果我使用我的原始源代码,那么M2.greet也可以从不同的文件访问。我已经用一种变通方法更新了我的答案,但似乎不支持为此目的使用该功能。
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