Extend enumerations types in F#

extension-methods, f#

Solution

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

Problem

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.

Original source