Разделение между модулями и пространствами имен в F #
У меня есть проблема в понимании точной разницы между модулями и пространствами имен в F # и при использовании того или другого.
Ну, они оба рассматриваются для того, чтобы инкапсулировать код и определить иерархию, чтобы наши проекты были хорошо организованы.
Модули имеют множество функций: они могут содержать значения, типы всех видов, и эти элементы могут быть определены public
, protected
или internal
тоже.
Но при использовании модулей?
Я понял также, что модули, наконец, отображаются как классы в MSIL (промежуточный язык). Таким образом, модуль является классом, является типом....
Мощь моих сомнений улучшается....
При использовании модулей???
Полезны ли они?
Д. Syme также утверждает, что модули расширяемы, поэтому я предполагаю, что они подобны пространствам имен с этой точки зрения.
Я не могу понять причину их использования.
Thankyou
Ответы
Ответ 1
Одно важное отличие:
. Пространства имен .NET не могут содержать значения (пусть определения), пока модули могут.
На уровне IL/Bytecode модуль компилируется в класс .net, а не в пространстве имен .net.
Когда использовать модули?
Для небольшой и конкретной задачи F # и другие FP обычно следуют схеме восходящего программирования: вы разлагаете свою задачу на набор небольших функций, а затем группируете эти функции в модуль.
Ответ заключается в том, что вполне естественно использовать модуль для группировки набора связанных функций и других значений и типов F # вместе.
В то время как пространство имен используется для группировки больших вещей: например, все классы для операций Матрицы.
Модуль не является статическим классом (в смысле С#)
Модули могут содержать специальные значения F #, например. токарные функции; а статический класс не может.
Ответ 2
Как говорит Инь Чжу, модули могут содержать значения. И вы можете открывать такие модули, как пространства имен. Эти две функции вместе - вот почему в F # вы можете делать такие вещи, как
let z = max x y
тогда как на языке, подобном С#, вы всегда должны сказать что-то вроде
var z = Math.Max(x,y)
// ^^^^^ can't call methods from elsewhere without a qualifier
и используйте квалифицированное имя (SomeClass.Method
), а не просто имя (letBoundFunction
). Поэтому вы можете использовать модули, когда хотите, чтобы люди могли открыть вам модуль Foo
и называть bar
, просто говоря bar
, а не Foo.bar
всюду. (Это особенно полезно для операторов, например, если вы определяете в библиотеке множество пользовательских операторов (таких как +++
или whatnot), помещая их в модуль, люди могут открыть модуль, а затем просто использовать, например, 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
в верхней части файла.