Another question related to F# feature called "Type extensions".
It seems impossible to extend enumerations in F#. I use C# Extensions Methods a lot for extending enums: add range validation logic, method that returns string representation etc.
Unfortunately it seems possible extend only discriminated union but impossible to extend simple enumerations:
1. Intrinsic extension
// CustomEnum.fs
module CustomEnumModule
type CustomEnum =
| Value1 = 1
| Value2 = 2
// Trying to split definition of the enum
type CustomEnum with
| Value3 = 3
Error: "error FS0010: Unexpected symbol '|' in member definition"
2. Optional extension
// CustomEnumEx.fs
open CustomEnumModule
type CustomEnum with
member public x.PrintValue() =
printfn "%A" x
Error: "error FS0896: Enumerations cannot have members"
It seems weird for me because (1) we can treat simple enumerations as a special case of full-featured discriminated union and we can extend discriminated unions and (2) extending .NET enums is a good way to add some features (including FP-features) to existing infrastructure.
Is this behavior intentional or this is simple bug in implementation?
P.S. Unfortunately F# Spec is silent in this regard, or at least I can't find any proofs for one or another behavior there.
No, there is not. enum are really the poor thing in C++, and that's unfortunate of course. Even the class enum introduced in C++0x does not address this extensibility issue (though they do some things for type safety at least).
Enum and has several static members. Therefore, enum cannot extend any other class or enum : there is no multiple inheritance. Class cannot extend enum , as well. This limitation is enforced by the compiler.
Enumerated (enum) types are data types that comprise a static, ordered set of values. They are equivalent to the enum types supported in a number of programming languages. An example of an enum type might be the days of the week, or a set of status values for a piece of data.
Since it's not a class, it cannot be extended and its defined values are limited to a small set of primitive types ( byte , sbyte , short , ushort , int , uint , long , ulong ). For instance, sometimes it is very convenient to get the list of enum values and display it in a combobox.
It is possible to create a module with the same name as a type which is similar to extending the type:
type CustomEnum = Value1 = 1 | Value2 = 2
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module CustomEnum =
let Print = function
| CustomEnum.Value1 -> "One"
| CustomEnum.Value2 -> "Two"
| _ -> invalidArg "" ""
let value = CustomEnum.Value1
let s = CustomEnum.Print value
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