F# Tutorial on F# Discriminated Unions

unions, or discriminated unions allows you to build up complex data structures representing well-defined set of choices. for example, you need to build an implementation of a choice variable, which has two values yes and no. using the unions tool, you can design this.

syntax

discriminated unions are defined using the following syntax −

type type-name =
   | case-identifier1 [of [ fieldname1 : ] type1 [ * [ fieldname2 : ] 
type2 ...]
   | case-identifier2 [of [fieldname3 : ]type3 [ * [ fieldname4 : ]type4 ...]
...

our simple implementation of ,choice, will look like the following −

type choice =
   | yes
   | no

the following example uses the type choice −

type choice =
   | yes
   | no

let x = yes (* creates an instance of choice *)
let y = no (* creates another instance of choice *)
let main() =
   printfn "x: %a" x
   printfn "y: %a" y
main()

when you compile and execute the program, it yields the following output −

x: yes
y: no

example 1

the following example shows the implementation of the voltage states that sets a bit on high or low −

type voltagestate =
   | high
   | low

let toggleswitch = function (* pattern matching input *)
   | high -> low
   | low -> high

let main() =
   let on = high
   let off = low
   let change = toggleswitch off

   printfn "switch on state: %a" on
   printfn "switch off state: %a" off
   printfn "toggle off: %a" change
   printfn "toggle the changed state: %a" (toggleswitch change)

main()

when you compile and execute the program, it yields the following output −

switch on state: high
switch off state: low
toggle off: high
toggle the changed state: low

example 2

type shape =
   // here we store the radius of a circle
   | circle of float

   // here we store the side length.
   | square of float

   // here we store the height and width.
   | rectangle of float * float

let pi = 3.141592654

let area myshape =
   match myshape with
   | circle radius -> pi * radius * radius
   | square s -> s * s
   | rectangle (h, w) -> h * w

let radius = 12.0
let mycircle = circle(radius)
printfn "area of circle with radius %g: %g" radius (area mycircle)

let side = 15.0
let mysquare = square(side)
printfn "area of square that has side %g: %g" side (area mysquare)

let height, width = 5.0, 8.0
let myrectangle = rectangle(height, width)
printfn "area of rectangle with height %g and width %g is %g" height width (area myrectangle)

when you compile and execute the program, it yields the following output −

area of circle with radius 12: 452.389
area of square that has side 15: 225
area of rectangle with height 5 and width 8 is 40