F# Snippet – Enums and Discriminated Unions


I was writing some F# code this week and ran into problem. Consider the following code:


 


type Thingey = This | That | SomethingElse


 


Which looks like an enum. So I assumed that, like things inheriting from System.Enum, an instance of the type had a ToString method which did the right thing. But, alas, when I type it into the F# Interactive Console I get:


 


> (Thingey.That).ToString();;


val it : string = “FSI_0002+Thingey”


 


The reason being is that the type Thingey is actually a Discriminated Union. In F#, to produce an Enumeration type you use the same syntax except you must explicitly provide an integer value for each member. Discriminated Unions can do a lot more than Enums in F#, but there are situations in which to use both.


 


The following snippet shows you how to use Enums and simple Discriminated Union types in F#.


 


#light


 


open System


 


// Enum type.


type FruitEnum =


    | Apple   = 0


    | Pear    = 1


    | Orange  = 2


    | Bananna = 3


 


// Enums have nice built in methods to parse and get their values.


// Note the “typeof<FruitEnum>” syntax to get get the typeof an F# object.


let favoriteFruit = Enum.Parse(typeof<FruitEnum>, “Pear”)


let allFruit = Enum.GetValues(typeof<FruitEnum>)


 


// You can even do some pattern matching…


let isGreen (day : FruitEnum) =


    match day with


    | FruitEnum.Apple | FruitEnum.Pear -> true


    | _ -> false


   


// Consider the following. Leads to undefined results, but


// is valid! This is because any int can be cast to/from an


// enum.


isGreen (Enum.of_int 99999)


 


// Now consider Discriminated Unions. One of their nice features is that the compiler can enforce


// some nice constraints when pattern matching; such as incomplete or too complete matchings.


type Shape =


    | Circle


    | Square


    | Triangle


 


// Warning: too few items. Pattern Matching incomplete.


let isRound x =


    match x with


    | Circle -> true


    | Square -> false


    // Warning FS0025: Incomplete pattern matches on this expression.


 



// Warning: too many items. (Matches more than every item.)


let isSquare x =


    match x with


    | Circle -> false


    | Square -> true


    | Triangle -> false


    | _ -> false


    // Warning FS0026: This rule will never be matched.

Comments (1)

  1. I was writing some F# code this week and ran into problem. Consider the following code: type Thingey