Различие между модулями и пространствами имен в 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
в верхней части файла.