'Defining static classes in F#
Is it possible to define a static class that contains overloadable members in F#? let module bindings cannot be overloaded, even though they are compiled into static static members in static classes.
type declerations can contain static members, but I don't know if the type itself can be made static.
My current solution is to define a type with a private constructor and just use that. I'm wondering if there is a way I can define a static type as I want.
Solution 1:[1]
This is explained in The F# Component Design Guidelines.
[<AbstractClass; Sealed>]
type Demo =
static member World = "World"
static member Hello() = Demo.Hello(Demo.World)
static member Hello(name: string) = sprintf "Hello %s!" name
let s1 = Demo.Hello()
let s2 = Demo.Hello("F#")
It is still possible to define instance methods, but you can't instantiate the class when there is no constructor available.
edit Jan 2021 : See the comment from Abel, and the linked issue. Joel Mueller's answer seems to be the best advice so far, but things will perhaps change in the future.
Solution 2:[2]
There is no facility for defining static types in F#.
The first alternative is to define a module, but it lacks the capability of overloading functions (which is what you're after). The second alternative is to declare a normal type with static members.
Regarding the second approach, it is exactly what the accepted answer to your old question described. I refactor the code to explain it easier. First, a dummy single-case discreminated unions is defined:
type Overloads = Overloads
Second, you exploit the fact that static members can be overloaded:
type Overloads with
static member ($) (Overloads, m1: #IMeasurable) = fun (m2: #IMeasurable) -> m1.Measure + m2.Measure
static member ($) (Overloads, m1: int) = fun (m2: #IMeasurable) -> m1 + m2.Measure
Third, you propagate constraints of these overloaded methods to let-bounds using inline keyword:
let inline ( |+| ) m1 m2 = (Overloads $ m1) m2
When you're able to overload let-bounds using this method, you should create a wrapper module to hold these functions and mark your type private.
Solution 3:[3]
I'm not sure there is such a thing as a static class. 'static' on class level in C# was introduced in 2.0, I believe, mostly as convenience (avoid private constructors and compile-time checking that no instance members are present). You can't examine the type and conclude that it is static: http://msdn.microsoft.com/en-us/library/system.reflection.typeinfo.aspx
Update: MSDN declares a static class is a class that is sealed and has only static members: http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
So, what you're doing at the moment is the way to do it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Aage |
| Solution 2 | Community |
| Solution 3 |
