How do you decide between writing a function inside a module or as a static member of some type?
For example, in the source code of F#, there are lots of types that are defined along with a equally named module, as follows:
type MyType = // ...
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module MyType = // ...
Why don't you simply define the operations as static members of type MyType?
Here are some notes about the technical distinctions.
Modules can be 'open'ed (unless they have RequireQualifiedAccessAttribute). That is, if you put functions (F
and G
) in a module (M
), then you can write
open M ... F x ... G x ...
whereas with a static method, you'd always write
... M.F x ... M.G x ...
Module functions cannot be overloaded. Functions in a module are let-bound, and let-bound functions do not permit overloading. If you want to be able to call both
X.F(someInt) X.F(someInt, someString)
you must use member
s of a type, which only work with 'qualified' calls (e.g. type.StaticMember(...)
or object.InstanceMember(...)
).
(Are there other differences? I can't recall.)
Those are the main technical differences that influence the choice of one over the other.
Additionally, there is some tendency in the F# runtime (FSharp.Core.dll) to use modules only for F#-specific types (that are typically not used when doing interop with other .Net languages) and static methods for APIs that are more language-neutral. For example, all the functions with curried parameters appear in modules (curried functions are non-trivial to call from other languages).
In F# I prefer a static member on a type over a function in a module if ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With