Kurz: printfn “%A” (sieb 50) printfn “%d” (List.length (sieb 10000))
Teil des Kurses F#
Kleine Projekte
// Primzahlsieb
let sieb n =
let prim = Array.create (n + 1) true
for i in 2 .. int (sqrt (float n)) do
if prim.[i] then
for j in i * i .. i .. n do prim.[j] <- false
[ for i in 2 .. n do if prim.[i] then yield i ]
printfn "%A" (sieb 50)
printfn "%d" (List.length (sieb 10000))
// Caesar
let verschiebe (text: string) schluessel =
text
|> String.map (fun c ->
if System.Char.IsLower c then char ((int c - int 'a' + schluessel + 26) % 26 + int 'a')
elif System.Char.IsUpper c then char ((int c - int 'A' + schluessel + 26) % 26 + int 'A')
else c)
let geheim = verschiebe "Hallo F#!" 3
printfn "%s" geheim
printfn "%s" (verschiebe geheim -3)Ausgabe:
[2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31; 37; 41; 43; 47]
1229
Kdoor I#!
Hallo F#!Datenanalyse mit Pipelines
type Verkauf = { Region: string; Produkt: string; Menge: int; Preis: decimal }
let daten =
[ { Region = "Nord"; Produkt = "Apfel"; Menge = 10; Preis = 1.20m }
{ Region = "Sued"; Produkt = "Birne"; Menge = 5; Preis = 0.80m }
{ Region = "Nord"; Produkt = "Birne"; Menge = 8; Preis = 0.80m }
{ Region = "West"; Produkt = "Apfel"; Menge = 20; Preis = 1.10m }
{ Region = "Sued"; Produkt = "Apfel"; Menge = 7; Preis = 1.20m } ]
let umsatz v = decimal v.Menge * v.Preis
daten
|> List.groupBy (fun v -> v.Region)
|> List.sortBy fst
|> List.iter (fun (region, vs) ->
printfn "%-5s %7.2f" region (vs |> List.sumBy umsatz))
printfn "Gesamt: %M" (daten |> List.sumBy umsatz)
let bester = daten |> List.maxBy umsatz
printfn "Bester Posten: %s in %s" bester.Produkt bester.Region
printfn "Äpfel: %d" (daten |> List.filter (fun v -> v.Produkt = "Apfel") |> List.sumBy (fun v -> v.Menge))Ausgabe:
Nord 18.40
Sued 12.40
West 22.00
Gesamt: 52.80
Bester Posten: Apfel in West
Äpfel: 37Tests und Ausnahmen
exception MeinFehler of string
let pruefe n =
if n < 0 then raise (MeinFehler(sprintf "negativ: %d" n))
n
try
printfn "%d" (pruefe 3)
printfn "%d" (pruefe -1)
with
| MeinFehler msg -> printfn "Eigener Fehler: %s" msg
| ex -> printfn "anderer Fehler: %s" ex.Message
let ergebnis =
try Ok(int "abc")
with :? System.FormatException as e -> Error e.Message
printfn "%A" ergebnis
try
try failwith "innen"
finally printfn "finally läuft immer"
with e -> printfn "außen gefangen: %s" e.Message
let mutable bestanden = 0
let mutable fehler = 0
let pruefeGleich name erwartet erhalten =
if erwartet = erhalten then
bestanden <- bestanden + 1
printfn "ok %s" name
else
fehler <- fehler + 1
printfn "FEHLER %s" name
pruefeGleich "Addition" 3 (1 + 2)
pruefeGleich "Liste" [ 2; 4 ] (List.map ((*) 2) [ 1; 2 ])
pruefeGleich "absichtlich" 5 (2 * 2)
printfn "%d bestanden, %d fehlgeschlagen" bestanden fehlerAusgabe:
3
Eigener Fehler: negativ: -1
Error "The input string 'abc' was not in a correct format."
finally läuft immer
außen gefangen: innen
ok Addition
ok Liste
FEHLER absichtlich
2 bestanden, 1 fehlgeschlagenÖkosystem
| Werkzeug | Zweck |
|---|---|
dotnet CLI, NuGet | Build und Pakete |
F# Interactive (dotnet fsi) | REPL und Skripte (.fsx) |
| Ionide (VS Code), Rider | Editoren |
| FSharp.Data | JSON/CSV/HTML-Typprovider |
| Giraffe, Saturn, Falco | Web-Frameworks |
| Fable | F# nach JavaScript |
| Expecto, xUnit, FsCheck | Tests (inkl. Property-based) |
| Paket, FAKE | Paketmanager und Build-DSL |
| Polyglot Notebooks | Datenanalyse in Notebooks |
Merke
- F# eignet sich hervorragend für Datenverarbeitung, Domänenmodelle und Parser
- Pipelines (
|>) und Records/Unions machen Code kurz und lesbar - Ausnahmen mit
try ... with,exceptionundfailwith - Das .NET-Ökosystem steht vollständig zur Verfügung
Übungsaufgabe
Baue einen kleinen Taschenrechner-Parser mit Discriminated Unions.
Quiz zur Selbstkontrolle
Wie definiert man eigene Ausnahmen in F#?
- exception Name of string (richtig)
- class MyEx : Exception
- throw new Name
- error Name
Wofür ist Fable?
- F# nach JavaScript übersetzen (richtig)
- Datenbankzugriff
- Ein Texteditor
- Ein Test-Framework
Welche Datei-Endung hat ein F#-Skript?
- .fsx (richtig)
- .fs.js
- .fsc
- .fsh
Weiter im Kurs
Zurück: Strings, Dateien, Async und Computation Expressions
Weiter: Referenz und Spickzettel
Alle Kapitel: F# im Überblick