Различие между модулями и пространствами имен в F # - PullRequest
8 голосов
/ 12 февраля 2011

У меня проблема с пониманием точной разницы между модулями и пространствами имен в F # и при использовании одного или другого.Ну, оба они рассматриваются для инкапсуляции кода и определения иерархии, чтобы наши проекты были хорошо организованы.

Модули имеют много особенностей: они могут содержать значения, типы всех типов, и эти элементы могут быть определены public, protected или internal тоже.

Но при использовании модулей?

Я также понял, что модули, наконец, отображаются как классы в MSIL (Intermediate Language).Таким образом, модуль - это класс, это тип .... Величина моих сомнений улучшается ....

При использовании модулей ???Они полезны?

D.Сайм также утверждает, что модули являются расширяемыми, поэтому я предполагаю, что они подобны пространствам имен с этой точки зрения.

Я не могу понять причину их использования.

Спасибо

Ответы [ 2 ]

9 голосов
/ 12 февраля 2011

Одно существенное отличие:

.Net пространства имен не могут содержать значения (пусть определения), в то время как модули могут.

На уровне IL / Bytecode модуль компилируется в класс .net, а не в пространство имен .net.

Когда использовать модули?

Для небольшой и конкретной задачи F # и другие FP обычно следуют шаблону программирования снизу вверх: вы разбиваете свою задачу на набор небольших функций, а затем группируете эти функции в модуль.

Ответ заключается в том, что вполне естественно использовать модуль для группировки набора связанных функций и других значений и типов F # вместе.

Хотя пространство имен используется для группировки больших объектов: например, все классы для матричных операций.

Модуль не является статическим классом (в смысле C #) Модули могут содержать специальные значения F #, например функции карри; в то время как статический класс не может.

6 голосов
/ 12 февраля 2011

Как говорит Инь Чжу, модули могут содержать значения. И вы можете открывать модули, такие как пространства имен. Эти две функции вместе, поэтому в F # вы можете делать такие вещи, как

let z = max x y

тогда как на языке, подобном C #, вы всегда должны говорить что-то вроде

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

и используйте полное имя (SomeClass.Method), а не просто имя (letBoundFunction). Таким образом, вы можете использовать модули, когда хотите, чтобы люди могли открывать вам модуль Foo и вызывать bar, просто сказав bar вместо Foo.bar везде. (Это особенно полезно для операторов, например, если вы определяете набор пользовательских операторов (таких как +++ или еще много чего) в библиотеке, помещая их в модуль, люди могут открыть модуль, а затем просто использовать, например, x +++ y, а не громоздкие вещи вроде (Foo.+++) x y или что-то в этом роде.)

Обратите внимание, что, хотя F # по умолчанию помещает код в файл .fs в модуле (с именем файла), вы можете изменить это, указав в качестве первого кода в файле объявление пространства имен, например,

namespace Yadda
// declare some types or whatnot, they go in namespace Yadda

или объявив свой собственный модуль

module Blah
// stuff goes in Blah module

вверху файла.

...