namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:expected

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
kennen:include:expected [2024-11-01 17:20] – [Methoden] rrichterkennen:include:expected [2024-11-01 20:33] (aktuell) – [Monadische Operationen] rrichter
Zeile 19: Zeile 19:
   {   {
     auto answer = question(6*n);     auto answer = question(6*n);
-    if (answer.has_value())+    if (answer.has_value())        // oder: if(answer)
       std::println("Die richtige Antwort ist {}", answer.value());       std::println("Die richtige Antwort ist {}", answer.value());
     else     else
Zeile 35: Zeile 35:
 | ''error_or(e)''  | Alternative, falls erwarteter Wert vorhanden | | ''error_or(e)''  | Alternative, falls erwarteter Wert vorhanden |
  
-Außerdem sind "monadische" Operationen als Methoden definiert+===== Monadische Operationen ===== 
 +> Monad: a monoid in the category of endofunctors 
 +> -- James Iry 
 + 
 +> Once you understand, you lose the ability to explain. 
 +> -- https://news.ycombinator.com/item?id=22417583 
 Diese rufen in Abhängigkeit vom Vorhandensein eines Wertes eine Funktion ''f'' auf. Diese rufen in Abhängigkeit vom Vorhandensein eines Wertes eine Funktion ''f'' auf.
-Im Ergebnis entsteht wiederum ein ''std::expected<.,.>''+Im Ergebnis entsteht wiederum ein ''std::expected<_,_>''
-Dabei werden die Typen von ''R'' und ''E'' entsprechend angepasst.+Dabei werden die Typen ''R'' und ''E'' entsprechend angepasst.
  
 ^ Wert vorhanden? ^ ja ^ nein ^Rückgabetyp von ''f'' ^ ^ Wert vorhanden? ^ ja ^ nein ^Rückgabetyp von ''f'' ^
Zeile 45: Zeile 51:
 | ''transform(f)'' | ''f(value())'' | | ''R2'' | | ''transform(f)'' | ''f(value())'' | | ''R2'' |
 | ''transform_error(f)'' | | ''f(error())'' | ''E2'' | | ''transform_error(f)'' | | ''f(error())'' | ''E2'' |
 +
 +Mit den monadischen Operationen lassen sich Verarbeitungsschritte und eventuell auftretende Fehler verketten: 
 +
 +<code cpp name_of_weekday.cpp>
 +#include <expected>
 +#include <iostream>
 +#include <print>
 +#include <string>
 +
 +struct Date { int y, m, d; };
 +
 +auto leapyear(int y) 
 +{
 +  return (y % 4 == 0 && !(y % 100 == 0)) || y % 400 == 0;
 +}  
 +
 +auto day_of_week(Date date) // Zellers Kongruenz, Gregorianisch: y > 1582  
 +{
 +  auto [y,m,d] = date;
 +  if (m < 3) { m += 12; --y; } 
 +  auto C = y / 100;
 +  auto D = y % 100;
 +  return (d + 13*(m+1)/5 + D + D/4 + C/4 + 5*C) % 7; 
 +}
 +
 +auto name_of_weekday(int w)
 +{
 +  std::string const name[] = { "Sa", "So", "Mo", "Di", "Mi", "Do", "Fr" };
 +  return name[w];
 +}
 +
 +std::expected<Date, std::string> input()
 +{
 +  Date date;
 +  char sep;
 +
 +  std::cout << "Datum (y-m-d): ";
 +  
 +  if (std::cin >> date.y >> sep >> date.m >> sep >> date.d && sep == '-'
 +    return date;
 +  else 
 +    return std::unexpected{"falsche Eingabe"};
 +}
 +
 +std::expected<Date, std::string> valid(Date date)
 +{
 +  if (date.m < 1 || date.m > 12) return std::unexpected{"ungültiger Monat"};
 +  if (date.d < 1 || date.d > 31) return std::unexpected{"ungültiger Tag"};
 +
 +  for (auto m : { 4, 6, 9, 11 })
 +  {
 +    if (m == date.m && date.d == 31)
 +      return std::unexpected{"April, Juni, September und Oktober haben keinen 31. Tag"};
 +  }
 +  if (date.m == 2 && date.d > 28 + leapyear(date.y)) 
 +  {
 +    return std::unexpected{"Diesen Tag gibt es im Februar nicht"};
 +  }
 +  return date;
 +}
 +
 +int main()
 +{
 +  auto result = input()
 +    .and_then(valid)
 +    .transform(day_of_week) 
 +    .transform(name_of_weekday)
 +    .transform_error([](std::string s) { return "Fehler: " + s; })
 +    .or_else([](const std::string& error) {
 +      std::println(std::cerr, "Eintrag {}", error);
 +      return std::expected<std::string, std::string>{std::unexpected{error}};
 +    });
 +
 +  if (result) std::println("{}", result.value());
 +  else std::println("{}", result.error());
 +}
 +</code>
  
 Siehe auch: [[optional]], [[variant]] Siehe auch: [[optional]], [[variant]]
  
  
kennen/include/expected.1730478029.txt.gz · Zuletzt geändert: 2024-11-01 17:20 von rrichter

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki