Различие между модулями и пространствами имен в F#

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

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

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

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

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

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

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

Спасибо

2 ответа

Решение

Одно главное отличие:

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

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

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

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

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

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

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

Как говорит Инь Чжу, модули могут содержать значения. И вы можете открывать модули, такие как пространства имен. Эти две функции вместе, поэтому в 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

в верхней части файла.

Другие вопросы по тегам