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 stati
As Robert Jeppeson pointed out, a "static class" in C# is just short-hand for making a class that cannot be instantiated or inherited from, and has only static members. Here's how you can accomplish exactly that in F#:
[<AbstractClass; Sealed>]
type MyStaticClass private () =
static member SomeStaticMethod(a, b, c) =
(a + b + c)
static member SomeStaticMethod(a, b, c, d) =
(a + b + c + d)
This might be a little bit of overkill, as both the AbstractClass
and the private constructor will prevent you from creating an instance of the class, however, this is what C# static classes do - they are compiled to an abstract class with a private constructor. The Sealed
attribute prevents you from inheriting from this class.
This technique won't cause a compiler error if you add instance methods the way it would in C#, but from a caller's point of view there is no difference.
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.
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
.
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.
I think the problem here is trying to make F# into C#. If the problem can't be solved in a non imperative fashion use C# or write an object oriented library and use it in F#.