F#中模块和命名空间之间的差异

And*_*dry 8 .net f# namespaces module

我在理解F#中的模块和命名空间之间的确切区别以及使用其中一个时遇到了问题.好吧,它们都被认为是为了封装代码并定义层次结构以使我们的项目井井有条.

模块有许多特点:他们可以包含值,类型的各类和这些元素可以被定义public,protected或者internal太.

但是,在使用模块时?

我也理解模块最终被映射为MSIL(中间语言)中的类.所以一个模块是一个类,是一个类型....我的怀疑'幅度提高....

使用模块时??? 它们有用吗?

D. Syme还认为模块是可扩展的,所以我认为从这个角度看它们就像命名空间一样.

我无法理解使用它们的原因.

谢谢

Yin*_*Zhu 9

一个主要区别:

.Net名称空间不能保存(让定义)而模块可以.

在IL/Bytecode级别,模块被编译为.net类,而不是.net名称空间.

什么时候使用模块?

对于一个小而具体的任务,F#和其他FP通常遵循自下而上编程的模式:将任务分解为一组小函数,然后将这些函数分组到一个模块中.

答案是,使用模块将一组相关函数和其他F#值和类型组合在一起是非常自然的.

虽然命名空间用于分组更大的东西:例如Matrix操作的所有类.

模块不是静态类(在C#意义上) 模块可以保存特殊的F#值,例如curried函数; 虽然静态类不能.


Bri*_*ian 6

正如尹朱所说,模块可以保持价值.您可以打开名称空间等模块.这两个功能在一起就是为什么在F#中你可以做的事情

let z = max x y
Run Code Online (Sandbox Code Playgroud)

而在像C#这样的语言中,你总是要说些像

var z = Math.Max(x,y)
//      ^^^^^   can't call methods from elsewhere without a qualifier
Run Code Online (Sandbox Code Playgroud)

并使用限定名称(SomeClass.Method)而不仅仅是名称(letBoundFunction).所以你可以使用模块,当你希望人们能够打开你的模块Foobar通过说bar而不是Foo.bar到处都打电话.(这对于操作员特别有用,例如,如果您在库中定义了一堆用户定义的操作符(例如+++或者诸如此类),通过将它们放在模块中,人们可以打开模块然后只使用例如x +++ y而不是繁琐的东西喜欢(Foo.+++) x y什么的.)

请注意,虽然默认情况下F#将代码放在模块中的.fs文件中(带有文件名),但您可以通过将文件中的第一个代码作为名称空间声明来更改此项,例如

namespace Yadda
// declare some types or whatnot, they go in namespace Yadda
Run Code Online (Sandbox Code Playgroud)

或者通过声明自己的模块

module Blah
// stuff goes in Blah module
Run Code Online (Sandbox Code Playgroud)

在文件的顶部.