anchor.diff:  
   *)
   
  -type PersonenName = { Vorname:string; Nachname:string; }
  -//type Person = { Id:int; Name:PersonalName }
  -
  -type Person = 
  -    | Angestellter of Id:int * Name:PersonenName * Department: Abteilung
  -    | Externer of Id:int * Name:PersonenName * Customer:Kunde
  -
  -(**
  -
  -' Wenn ich ab jetzt nur noch mit 
  -
  ----
  -### DDD und F#
  -- Model für einen Namen
  -
  -' In OO wäre es möglich dass MiddleName ein null wäre. Das ist zulässig und idiomatisch.
  -' Aber wie wir gesehen haben, wäre es auch möglich Length gegen einen null pointer vom Type String zu verwenden
  -' dies kann ich verhindern in dem ich die Option nutze, hier muss der String angegeben werden (wenn auch Empty auch möglich wäre)
  +type PersonenName = { Titel: string option; Vorname:string; Nachname:string; }
  +
  +type Angestellter = { Id:int; Name:PersonenName; Department: Abteilung;}
  +
  +type Externer = { Id:int; Name:PersonenName; Customer:Kunde;}
  +
  +type Person' = 
  +    | Angestellter of Angestellter
  +    | Externer of Externer
  +
  +(**
  +
  +' - ACHTUNG: string kann nicht mit nullable kombiniert werden, da diese nur Werttypen unterstützt
  +' - Ein ORM hätte an der Stelle den Wert null gewählt als mapping
  +' - string option hingegen erlaubt den Verzicht auf null, bei Einhaltung der 
  +' Bedenken: Ich habe weiterhin nur einen Typ für Person, keine zwei.  Nur bei jedem Zugriff auf Person, muss ich jetzt beide Fälle explizit berücksichtigen
  +' Operationen die nur vom Angestellten/Externen ausgeführt werden müssen, können jetzt auf Typ Ebene beschränkt werden
  +' Datenhaltung: Command Query Seperation, dass eine Tabelle sich 1:1 zu einem objekt mappen soll ist problematisch. Also besser ist es wenn ich mich damit abfinde dass eine Tabelle unter Umständen auf mehreren Wegen abgefragt/geändert werden kann
  +' Zugriffe können weniger als eine tabelle holen
  +' Updates nur bestimmte Werte updaten
  +' http://gorodinski.com/blog/2013/01/21/inverting-object-orientation-with-fsharp-discriminated-unions-and-pattern-matching/
  +
  +---
  +### DDD und F#
  +#### Model für eine Email/Telefonenummer/Kundennummer etc.
  +
  +' Single Case union bedeutet dass ich einen eignen Type für Emails reserviere.
  +' Funktionen/Datenstrukture die eine Email erfodern/zurückgeben, können dies jetzt mittels der Typdeklaration kundtun. 
  +' Emails sind halt keine strings.
  +
  +*)
  +    
  +// single case union
  +type Email = Email of string
  +type Telefon = PhoneNumber of string
  +type Kundennummer = CustomerNumber of string
  +
  +(**
  +
  +--- 
  +### DDD und F#
  +#### Zustände
  +
  +- Zusammenhängende Informationen in Types zusammenfassen
  +- Zustände mittels Typen darstellen
  +
   
   *)
   
   module DDD0 = 
  -
  -    type PersonenName = 
  -        { 
  -            FirstName:string; // Muss
  -            MiddleName:string; // Kann
  -            LastName:string; // Muss
  -        }
  -
  -(**
  -
  ----
  -### DDD und F#
  -#### Model für einen Namen
  -
  -*)
  -
  -module DDD1 = 
  -
  -    type PersonalName = 
  -        { 
  -            FirstName:string; // Muss
  -            MiddleName:string option; // Kann
  -            LastName:string; // Muss
  -        }
  -
  -(**
  -
  ----
  -### DDD und F#
  -#### Model für eine Email/Telefonenummer/Kundennummer etc.
  -
  -' Single Case union bedeutet dass ich einen eignen Type für Emails reserviere.  Funktionen/Datenstrukture die eine Email brauchen, können dies jetzt mittels der Typdeklaration kundtun. Ich trenne so "normale" von Emails.  
  -
  -*)
  -    // single case union
  -    type Email = Email of string
  -    type PhoneNumber = PhoneNumber of string
  -    type CustomerNumber = CustomerNumber of string
  -
  -(**
  +    open System
  +
  +    type PersonenName = { Titel: string option; Vorname:string; Nachname:string; }
  +
  +    type Kontakt = { Name:PersonenName; Email:Email; EmailVerifiziert:bool; }
  +
  +(**
  +
  +' Kontakt hat eine Email Adresse angegeben, diese muss verifiziert werden.  Erst danach kann der Kontakt bestimmte Tätigkeiten ausüben
  +' Beachte: EmailVerifiziert kann gesetzt werden, ODER ich muss in meinem Code dies kontrollieren
   
   --- 
   ### DDD und F#
  -#### Kontakt
  -
  -- Zusammenhängende Informationen als Primitives dargestellt
  -- Daten die fehlen darf als option dargestellt
  -
  -*)
  -
  -    type Contact = {
  -        FirstName:string
  -        MiddleInitial:string
  -        LastName:string
  -        EmailAdresse:string
  -        IsEmailVerified:bool
  -        EmailVerificationToken:string }
  -
  -    type Contact' = {
  -        Name: PersonalName
  -        Email:Email
  -        IsEmailVerified:bool
  -        EmailVerificationToken:string
  -    }
  -
  -(**
  +#### Zustände
  +
  +*)
  +
  +    type EmailVerificationToken = EmailVerificationToken of string
  +
  +    type VerifyEmail = Email -> EmailVerificationToken -> bool
  +
  +    let ``Funktion gilt nur für verifizierte`` kontakt = 
  +        if kontakt.EmailVerifiziert then
  +            "???"
  +        else
  +            "Ja das darf der Kotakt"
  +
  +(**
  +
  +' Zeigen. Type Inference funktioniert wirklich: Kontakt wird erkannt, kein Rückgabetyp da dieser auch vom Compiler erkannt wurde (kontakt:Kontakt -> string)
  +' VerifyEmail gibt mir einen bool zurück, ich muss jetzt darauf handeln und die Behandlung der Verifizierung (das Bool) übernehmen, neben der tatsächlichen email Adresse
  +' Solches code muss jetzt immer verwendet werden um zu prüfen ob die Email eines Kontakts verifiziert ist
   
   ---
   ### DDD und F#
   #### Model für eine verifizierte Email
   
  -- Wenn ein neuer Kunde eine Email eingibt, dann muss diese oft erst verifiziert werden
  -- Bis zu dieser Verifizierung, handelt es sich um eine nicht verifizierte Email
  -- Erst nach der Verifizierung, wird daraus eine verfizierte Email (der Beweis ist ein Token)
  -- Die beiden Zustände einer Email als DU modelieren
  -
  -*)
  -    type EmailVerificationToken = EmailVerificationToken of string
  -
  -    type EmailContactInfo = 
  -        | Unverified of Email
  -        | Verified of Email:Email * VerificationToken : EmailVerificationToken
  -
  -(**
  +' Wenn ein neuer Kunde eine Email eingibt, dann muss diese oft erst verifiziert werden
  +' Bis zu dieser Verifizierung, handelt es sich um eine nicht verifizierte Email
  +' Erst nach der Verifizierung, wird daraus eine verfizierte Email (der Beweis ist ein Token)
  +' Die beiden Zustände einer Email als DU modelieren
  +
  +*)
  +    type VerifizierteEmail = { Email:Email; Verifikation: EmailVerificationToken; }
  +
  +    type VerifyEmail' = Email -> EmailVerificationToken -> VerifizierteEmail option
  +
  +(**
  +
  +' Der neue Typ soll nur dann erstellt werden wenn die Verifikation erfolgt ist.  Die Funktion VerifyEmail' könnte ich z.B. mittels F# Scope Regeln so erstellen dass diese als einziges Gateway vorhanden ist um an das Typ VerifizierteEmail zu erzeugen
   
   --- 
   ### DDD und F#
  
positive.code: 
  *)
  
      type Contact'' = {
          Name: PersonalName
          EmailContactInfo:EmailContactInfo
      }
  
  
  
  
  
  
  
negative.code: ---
  ### Tuple: Construction
  
  - Kann beliebig viele Elemente beinhalten
  - Construction erolgt mittels Komma (mit und ohne Klammern)
  - Multiplikation von (mindestens) zwei Domains: Kartesiche Summe
  
  *)
  
  