anchor.diff:  ---
   ### Tuple: Construction
   
  -- Kann beliebig viele Elemente beinhalten                    
  -- Construction erolgt mittels Komma (mit und ohne Klammern)  
  -- Multiplikation von (mindestens) zwei Domains: Kartesiche Summe 
  +- Kann beliebig viele Elemente beinhalten
  +- Construction erolgt mittels Komma (mit und ohne Klammern)
  +- Multiplikation von (mindestens) zwei Domains: Kartesiche Summe
   
   *)
   
  
positive.code: 
  *)
  
      type Contact'' = {
          Name: PersonalName
          EmailContactInfo:EmailContactInfo
      }
  
  
  
  
  
  
  
negative.code: 
  *)
  
  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 = 
      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#
  #### 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 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#
  