Listing 1: Werte und Funktionen mit let zuweisen

let netto : decimal = 19.99m

let als_Brutto netto =
 preis * 1.19m

let brutto = als_Brutto netto

let teuer =
 if brutto > 200 
 then "ja"
 else "nein"

Listing 2: Spezialzertifikate mit dem Typsystem von F# implementieren

type Level =
 | OpenWaterDiver
 | AdventureDiver
 | AdvancedOpenWaterDiver

type Speciality =
 | BoatDiver
 | NightDiver
 | DeepDiver
 | WreckDiver
 | CavernDiver
 | IceDiver

Listing 3: Level, Speciality und Course einbinden

 {
   Level : Option<Level>
   Speciality : Option<Speciality>
   Course : Option<System.Guid>
 }

Listing 4: Eine DU initialisieren

let level = AdventureDiver

// Instantiierung eines Records
let workflowResult : CourseRegistrationWorkflow =
 {
   Level = Some level
   Speciality = Some DeepDiver
   Course = Some (Guid.Parse("f9b91bea-5424-41de-a385-5f13d821bb1e"))
 }

Listing 5: Records initialisieren

let step0 =
 {
   Level = None
   Speciality = None
   Course = None
 }

let step1 =
 {
   Level = Some AdventureDiver
   Speciality = None
   Course = None
 }

let step2 =
 {
   Level = Some AdventureDiver
   Speciality = Some DeepDiver
   Course = None
 }

let step3 =
 {
   Level = Some AdventureDiver
   Speciality = Some DeepDiver
   Course = Some (Guid.Parse("f9b91bea-5424-41de-a385-5f13d821bb1e"))
 }

Listing 6: Repräsentation illegaler Zustände

let sollte_nie_passieren =
 {
   Level = None
   Speciality = None
   Course = Some (Guid.Parse("f9b91bea-5424-41de-a385-5f13d821bb1e"))
 }

Listing 7: CourseRegistrationWorkflowStep

type CourseRegistrationWorkflowStep =
 | ChooseLevel
 | ChooseSpeciality of Level
 | ChooseCourse of Level * Speciality

let step1 = ChooseLevel
let step2 = ChooseSpeciality AdvancedOpenWaterDiver 
let step3 = ChooseCourse (AdvancedOpenWaterDiver ,DeepDiver)

let showRegistrationStep step =
  match step with
  | ChooseLevel ->
      showLevelStep

  | ChooseSpeciality level ->
      showSpecialityStep level

  | ChooseCourse (level,speciality) ->
      showCourseStep level speciality

Listing 8: Illegale Zustände mit DUs vermeiden

type Level =
 | OpenWaterDiver
 | AdventureDiver
 | AdvancedOpenWaterDiver

type OpenWaterDiverSpeciality =
 | BoatDiver
 | NightDiver

type AdventureDiverSpeciality = 
 | DeepDiver
 | WreckDiver

type AdvancedOpenWaterDiverSpeciality = 
 | CavernDiver
 | IceDiver  

type LevelWithSpeciality =
 | OpenWaterDiver of OpenWaterDiverSpeciality
 | AdventureDiver of AdventureDiverSpeciality
 | AdvancedOpenWaterDiver of AdvancedOpenWaterDiverSpeciality


type CourseRegistrationWorkflow =
 | ChooseLevel
 | ChooseSpeciality of Level
 | ChooseStart of LevelWithSpeciality

// kompiliert nicht
let step3 = ChooseCourse (AdvancedOpenWaterDiver DeepDiver)

// kompiliert
let step3 = ChooseCourse (AdvancedOpenWaterDiver CavernDiver)

Listing 9: Illegale Zustände mit DUs vermeiden

type RegistrationResult =
 | Accepted
 | Course_Full


let registerForCourse (course : Guid) (trainer : Guid) =
 if not (isFull course trainer) then
    // store in DB, send verification mail etc.
   Accepted
  else
   Course_Full


let registerCoursePage trainer course =
 match registerForCourse course with
 | Accepted ->
     renderConfirmationPage trainer course

 | Course_Full ->
     renderCourseFullPage course 

Listing 10: Typen definieren und benutzen

// Single Case Discriminated Unions
type Trainer = Trainer of System.Guid
type Course = Course of System.Guid


// verpacken der Guid mit DU-Konstruktor
let trainer = Trainer (System.Guid.NewGuid())


let registerForCourse (course : Course) (trainer : Trainer) =
  //...


// direktes auspacken von Single-Case DUs in der Funktionsdeklaration
let registerCoursePage (Trainer trainer) (Course course) =
  // die verpackten Guids stehen hier in trainer und course zur Verfügung



