added doi

This commit is contained in:
2025-07-31 12:59:04 +02:00
parent eb2d14ba98
commit deb3fc9b02
42 changed files with 3811 additions and 3449 deletions

View File

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
<meta charset="utf-8">
<meta name="generator" content="quarto-1.7.23">
<meta name="generator" content="quarto-1.8.17">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
@ -68,17 +68,19 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<meta name="quarto:offset" content="../../../">
<script src="../../../site_libs/quarto-html/quarto.js" type="module"></script>
<script src="../../../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
<script src="../../../site_libs/quarto-html/axe/axe-check.js" type="module"></script>
<script src="../../../site_libs/quarto-html/popper.min.js"></script>
<script src="../../../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../../../site_libs/quarto-html/anchor.min.js"></script>
<link href="../../../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-dark-2c84ecb840a13f4c7993f9e5648f0c14.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-6cf5824034cebd0380a5b9c74c43f006.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-ff1c8a91a872873ab9706226229f9e30.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-dark-04b38c9dba5d7c0f1fe2b621b39e7e62.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-ff1c8a91a872873ab9706226229f9e30.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
<script src="../../../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../../../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../../../site_libs/bootstrap/bootstrap-ec71cb1e120c0dd41819aca960e74e38.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-dark-716ed94a23403968eaa6fe981e0cbf91.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../../../site_libs/bootstrap/bootstrap-ec71cb1e120c0dd41819aca960e74e38.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-9b56b6674ace31b1957ea5f5ef42286f.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-dark-3c8015a3c2181875b3e8a350495bd83c.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../../../site_libs/bootstrap/bootstrap-9b56b6674ace31b1957ea5f5ef42286f.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<script id="quarto-search-options" type="application/json">{
"location": "navbar",
"copy-button": false,
@ -131,7 +133,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
toggleBodyColorMode(bsSheetEl);
}
}
window.setColorSchemeToggle = (alternate) => {
const setColorSchemeToggle = (alternate) => {
const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
for (let i=0; i < toggles.length; i++) {
const toggle = toggles[i];
@ -164,7 +166,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
}
manageTransitions('#quarto-margin-sidebar .nav-link', true);
// Switch the toggles
window.setColorSchemeToggle(alternate)
setColorSchemeToggle(alternate)
// Hack to workaround the fact that safari doesn't
// properly recolor the scrollbar when toggling (#1455)
if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
@ -204,7 +206,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
const isFileUrl = () => {
return window.location.protocol === 'file:';
}
window.hasAlternateSentinel = () => {
const hasAlternateSentinel = () => {
let styleSentinel = getColorSchemeSentinel();
if (styleSentinel !== null) {
return styleSentinel === "alternate";
@ -232,7 +234,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
let newTheme = '';
if(darkModeDefault) {
if(authorPrefersDark) {
newTheme = isAlternate ? baseTheme : alternateTheme;
} else {
newTheme = isAlternate ? alternateTheme : baseTheme;
@ -255,17 +257,20 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
changeGiscusTheme();
}
};
const authorPrefersDark = false;
const queryPrefersDark = window.matchMedia('(prefers-color-scheme: dark)');
const darkModeDefault = queryPrefersDark.matches;
document.querySelector('link.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
// Dark / light mode switch
window.quartoToggleColorScheme = () => {
// Read the current dark / light value
let toAlternate = !window.hasAlternateSentinel();
let toAlternate = !hasAlternateSentinel();
toggleColorMode(toAlternate);
setStyleSentinel(toAlternate);
toggleGiscusIfUsed(toAlternate, darkModeDefault);
window.dispatchEvent(new Event('resize'));
};
queryPrefersDark.addEventListener("change", e => {
if(window.localStorage.getItem("quarto-color-scheme") !== null)
@ -276,7 +281,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
toggleGiscusIfUsed(alternate, darkModeDefault);
});
// Switch to dark mode if need be
if (window.hasAlternateSentinel()) {
if (hasAlternateSentinel()) {
toggleColorMode(true);
} else {
toggleColorMode(false);
@ -288,6 +293,8 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<nav class="navbar navbar-expand-lg " data-bs-theme="dark">
<div class="navbar-container container-fluid">
<div class="navbar-brand-container mx-auto">
<a href="../../../index.html" class="navbar-brand navbar-brand-logo">
</a>
<a class="navbar-brand" href="../../../index.html">
<span class="navbar-title">Nicole Dresselhaus</span>
</a>
@ -299,12 +306,12 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav navbar-nav-scroll me-auto">
<li class="nav-item">
<a class="nav-link" href="../../../index.html"> <i class="bi bi-house" role="img">
<a class="nav-link active" href="../../../index.html" aria-current="page"> <i class="bi bi-house" role="img">
</i>
<span class="menu-text">Home</span></a>
</li>
<li class="nav-item">
<a class="nav-link active" href="../../../About/index.html" aria-current="page"> <i class="bi bi-file-person" role="img">
<a class="nav-link" href="../../../About/index.html"> <i class="bi bi-file-person" role="img">
</i>
<span class="menu-text">About</span></a>
</li>
@ -342,6 +349,10 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
<!-- sidebar -->
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation docked overflow-auto">
<div class="pt-lg-2 mt-2 text-left sidebar-header">
<a href="../../../index.html" class="sidebar-logo-link">
</a>
</div>
<div class="sidebar-menu-container">
<ul class="list-unstyled mt-1">
<li class="sidebar-item sidebar-item-section">
@ -385,12 +396,6 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<a href="../../../Writing/Obsidian-RAG.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">RAG für eine Obsidian-Wissensdatenbank: Technische Ansätze</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../../../Obsidian-Articles/Artikelbewertung durch LLM.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Artikelbewertung durch ein Large Language Model (LLM) - Ein Beispiel aus der Praxis</span></a>
</div>
</li>
</ul>
</li>
@ -651,7 +656,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<p>Wie man das verwendet, siehe <a href="../../../Coding/Haskell/Webapp-Example/index.html">Webapp-Example</a>.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-name-shadowing #-}</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-name-shadowing #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleContexts #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE LambdaCase #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE OverloadedStrings #-}</span></span>
@ -831,7 +836,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<span id="cb1-178"><a href="#cb1-178" aria-hidden="true" tabindex="-1"></a> out _ r status _ _ payload _</span>
<span id="cb1-179"><a href="#cb1-179" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> statusCode status <span class="op">&lt;</span> <span class="dv">300</span> <span class="ot">=</span> <span class="st">""</span></span>
<span id="cb1-180"><a href="#cb1-180" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> statusCode status <span class="op">&gt;</span> <span class="dv">399</span> <span class="op">&amp;&amp;</span> statusCode status <span class="op">&lt;</span> <span class="dv">500</span> <span class="ot">=</span> <span class="st">"Error code "</span><span class="op">&lt;&gt;</span>toLogStr (statusCode status) <span class="op">&lt;&gt;</span><span class="st">" sent. Request-Payload was: "</span><span class="op">&lt;&gt;</span> <span class="fu">mconcat</span> (toLogStr <span class="op">&lt;$&gt;</span> payload) <span class="op">&lt;&gt;</span> <span class="st">"\n"</span></span>
<span id="cb1-181"><a href="#cb1-181" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> toLogStr (<span class="fu">show</span> r) <span class="op">&lt;&gt;</span> <span class="st">"\n"</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb1-181"><a href="#cb1-181" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> toLogStr (<span class="fu">show</span> r) <span class="op">&lt;&gt;</span> <span class="st">"\n"</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
@ -850,7 +855,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
a.appendChild(i);
window.document.body.appendChild(a);
}
window.setColorSchemeToggle(window.hasAlternateSentinel())
setColorSchemeToggle(hasAlternateSentinel())
const icon = "";
const anchorJS = new window.AnchorJS();
anchorJS.options = {

View File

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
<meta charset="utf-8">
<meta name="generator" content="quarto-1.7.23">
<meta name="generator" content="quarto-1.8.17">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
@ -68,17 +68,19 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<meta name="quarto:offset" content="../../../">
<script src="../../../site_libs/quarto-html/quarto.js" type="module"></script>
<script src="../../../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
<script src="../../../site_libs/quarto-html/axe/axe-check.js" type="module"></script>
<script src="../../../site_libs/quarto-html/popper.min.js"></script>
<script src="../../../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../../../site_libs/quarto-html/anchor.min.js"></script>
<link href="../../../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-dark-2c84ecb840a13f4c7993f9e5648f0c14.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-6cf5824034cebd0380a5b9c74c43f006.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-ff1c8a91a872873ab9706226229f9e30.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-dark-04b38c9dba5d7c0f1fe2b621b39e7e62.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-ff1c8a91a872873ab9706226229f9e30.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
<script src="../../../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../../../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../../../site_libs/bootstrap/bootstrap-ec71cb1e120c0dd41819aca960e74e38.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-dark-716ed94a23403968eaa6fe981e0cbf91.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../../../site_libs/bootstrap/bootstrap-ec71cb1e120c0dd41819aca960e74e38.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-9b56b6674ace31b1957ea5f5ef42286f.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-dark-3c8015a3c2181875b3e8a350495bd83c.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../../../site_libs/bootstrap/bootstrap-9b56b6674ace31b1957ea5f5ef42286f.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<script id="quarto-search-options" type="application/json">{
"location": "navbar",
"copy-button": false,
@ -131,7 +133,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
toggleBodyColorMode(bsSheetEl);
}
}
window.setColorSchemeToggle = (alternate) => {
const setColorSchemeToggle = (alternate) => {
const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
for (let i=0; i < toggles.length; i++) {
const toggle = toggles[i];
@ -164,7 +166,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
}
manageTransitions('#quarto-margin-sidebar .nav-link', true);
// Switch the toggles
window.setColorSchemeToggle(alternate)
setColorSchemeToggle(alternate)
// Hack to workaround the fact that safari doesn't
// properly recolor the scrollbar when toggling (#1455)
if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
@ -204,7 +206,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
const isFileUrl = () => {
return window.location.protocol === 'file:';
}
window.hasAlternateSentinel = () => {
const hasAlternateSentinel = () => {
let styleSentinel = getColorSchemeSentinel();
if (styleSentinel !== null) {
return styleSentinel === "alternate";
@ -232,7 +234,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
let newTheme = '';
if(darkModeDefault) {
if(authorPrefersDark) {
newTheme = isAlternate ? baseTheme : alternateTheme;
} else {
newTheme = isAlternate ? alternateTheme : baseTheme;
@ -255,17 +257,20 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
changeGiscusTheme();
}
};
const authorPrefersDark = false;
const queryPrefersDark = window.matchMedia('(prefers-color-scheme: dark)');
const darkModeDefault = queryPrefersDark.matches;
document.querySelector('link.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
// Dark / light mode switch
window.quartoToggleColorScheme = () => {
// Read the current dark / light value
let toAlternate = !window.hasAlternateSentinel();
let toAlternate = !hasAlternateSentinel();
toggleColorMode(toAlternate);
setStyleSentinel(toAlternate);
toggleGiscusIfUsed(toAlternate, darkModeDefault);
window.dispatchEvent(new Event('resize'));
};
queryPrefersDark.addEventListener("change", e => {
if(window.localStorage.getItem("quarto-color-scheme") !== null)
@ -276,7 +281,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
toggleGiscusIfUsed(alternate, darkModeDefault);
});
// Switch to dark mode if need be
if (window.hasAlternateSentinel()) {
if (hasAlternateSentinel()) {
toggleColorMode(true);
} else {
toggleColorMode(false);
@ -288,6 +293,8 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<nav class="navbar navbar-expand-lg " data-bs-theme="dark">
<div class="navbar-container container-fluid">
<div class="navbar-brand-container mx-auto">
<a href="../../../index.html" class="navbar-brand navbar-brand-logo">
</a>
<a class="navbar-brand" href="../../../index.html">
<span class="navbar-title">Nicole Dresselhaus</span>
</a>
@ -299,12 +306,12 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav navbar-nav-scroll me-auto">
<li class="nav-item">
<a class="nav-link" href="../../../index.html"> <i class="bi bi-house" role="img">
<a class="nav-link active" href="../../../index.html" aria-current="page"> <i class="bi bi-house" role="img">
</i>
<span class="menu-text">Home</span></a>
</li>
<li class="nav-item">
<a class="nav-link active" href="../../../About/index.html" aria-current="page"> <i class="bi bi-file-person" role="img">
<a class="nav-link" href="../../../About/index.html"> <i class="bi bi-file-person" role="img">
</i>
<span class="menu-text">About</span></a>
</li>
@ -342,6 +349,10 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
<!-- sidebar -->
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation docked overflow-auto">
<div class="pt-lg-2 mt-2 text-left sidebar-header">
<a href="../../../index.html" class="sidebar-logo-link">
</a>
</div>
<div class="sidebar-menu-container">
<ul class="list-unstyled mt-1">
<li class="sidebar-item sidebar-item-section">
@ -385,12 +396,6 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<a href="../../../Writing/Obsidian-RAG.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">RAG für eine Obsidian-Wissensdatenbank: Technische Ansätze</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../../../Obsidian-Articles/Artikelbewertung durch LLM.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Artikelbewertung durch ein Large Language Model (LLM) - Ein Beispiel aus der Praxis</span></a>
</div>
</li>
</ul>
</li>
@ -651,7 +656,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<p>Anleitung siehe <a href="../../../Coding/Haskell/Webapp-Example/index.html">Webapp-Example</a>.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-orphans #-}</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-orphans #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-name-shadowing #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveAnyClass #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveFunctor #-}</span></span>
@ -727,7 +732,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<span id="cb1-74"><a href="#cb1-74" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-75"><a href="#cb1-75" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-76"><a href="#cb1-76" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Out</span> <span class="dt">Response</span></span>
<span id="cb1-77"><a href="#cb1-77" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FromBSON</span> <span class="dt">Repsonse</span> <span class="co">-- FromBSON-Instanz geht immer davon aus, dass alle keys da sind (ggf. mit null bei Nothing).</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb1-77"><a href="#cb1-77" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FromBSON</span> <span class="dt">Repsonse</span> <span class="co">-- FromBSON-Instanz geht immer davon aus, dass alle keys da sind (ggf. mit null bei Nothing).</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
@ -746,7 +751,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
a.appendChild(i);
window.document.body.appendChild(a);
}
window.setColorSchemeToggle(window.hasAlternateSentinel())
setColorSchemeToggle(hasAlternateSentinel())
const icon = "";
const anchorJS = new window.AnchorJS();
anchorJS.options = {

View File

@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
<meta charset="utf-8">
<meta name="generator" content="quarto-1.7.23">
<meta name="generator" content="quarto-1.8.17">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
@ -68,17 +68,19 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<meta name="quarto:offset" content="../../../">
<script src="../../../site_libs/quarto-html/quarto.js" type="module"></script>
<script src="../../../site_libs/quarto-html/tabsets/tabsets.js" type="module"></script>
<script src="../../../site_libs/quarto-html/axe/axe-check.js" type="module"></script>
<script src="../../../site_libs/quarto-html/popper.min.js"></script>
<script src="../../../site_libs/quarto-html/tippy.umd.min.js"></script>
<script src="../../../site_libs/quarto-html/anchor.min.js"></script>
<link href="../../../site_libs/quarto-html/tippy.css" rel="stylesheet">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-dark-2c84ecb840a13f4c7993f9e5648f0c14.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-6cf5824034cebd0380a5b9c74c43f006.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-ff1c8a91a872873ab9706226229f9e30.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-dark-04b38c9dba5d7c0f1fe2b621b39e7e62.css" rel="stylesheet" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
<link href="../../../site_libs/quarto-html/quarto-syntax-highlighting-ff1c8a91a872873ab9706226229f9e30.css" rel="stylesheet" class="quarto-color-scheme-extra" id="quarto-text-highlighting-styles">
<script src="../../../site_libs/bootstrap/bootstrap.min.js"></script>
<link href="../../../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
<link href="../../../site_libs/bootstrap/bootstrap-ec71cb1e120c0dd41819aca960e74e38.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-dark-716ed94a23403968eaa6fe981e0cbf91.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../../../site_libs/bootstrap/bootstrap-ec71cb1e120c0dd41819aca960e74e38.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-9b56b6674ace31b1957ea5f5ef42286f.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
<link href="../../../site_libs/bootstrap/bootstrap-dark-3c8015a3c2181875b3e8a350495bd83c.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
<link href="../../../site_libs/bootstrap/bootstrap-9b56b6674ace31b1957ea5f5ef42286f.min.css" rel="stylesheet" append-hash="true" class="quarto-color-scheme-extra" id="quarto-bootstrap" data-mode="light">
<script id="quarto-search-options" type="application/json">{
"location": "navbar",
"copy-button": false,
@ -131,7 +133,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
toggleBodyColorMode(bsSheetEl);
}
}
window.setColorSchemeToggle = (alternate) => {
const setColorSchemeToggle = (alternate) => {
const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
for (let i=0; i < toggles.length; i++) {
const toggle = toggles[i];
@ -164,7 +166,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
}
manageTransitions('#quarto-margin-sidebar .nav-link', true);
// Switch the toggles
window.setColorSchemeToggle(alternate)
setColorSchemeToggle(alternate)
// Hack to workaround the fact that safari doesn't
// properly recolor the scrollbar when toggling (#1455)
if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
@ -204,7 +206,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
const isFileUrl = () => {
return window.location.protocol === 'file:';
}
window.hasAlternateSentinel = () => {
const hasAlternateSentinel = () => {
let styleSentinel = getColorSchemeSentinel();
if (styleSentinel !== null) {
return styleSentinel === "alternate";
@ -232,7 +234,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
let newTheme = '';
if(darkModeDefault) {
if(authorPrefersDark) {
newTheme = isAlternate ? baseTheme : alternateTheme;
} else {
newTheme = isAlternate ? alternateTheme : baseTheme;
@ -255,17 +257,20 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
changeGiscusTheme();
}
};
const authorPrefersDark = false;
const queryPrefersDark = window.matchMedia('(prefers-color-scheme: dark)');
const darkModeDefault = queryPrefersDark.matches;
document.querySelector('link.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
document.querySelector('link#quarto-text-highlighting-styles.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
document.querySelector('link#quarto-bootstrap.quarto-color-scheme-extra').rel = 'disabled-stylesheet';
let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
// Dark / light mode switch
window.quartoToggleColorScheme = () => {
// Read the current dark / light value
let toAlternate = !window.hasAlternateSentinel();
let toAlternate = !hasAlternateSentinel();
toggleColorMode(toAlternate);
setStyleSentinel(toAlternate);
toggleGiscusIfUsed(toAlternate, darkModeDefault);
window.dispatchEvent(new Event('resize'));
};
queryPrefersDark.addEventListener("change", e => {
if(window.localStorage.getItem("quarto-color-scheme") !== null)
@ -276,7 +281,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
toggleGiscusIfUsed(alternate, darkModeDefault);
});
// Switch to dark mode if need be
if (window.hasAlternateSentinel()) {
if (hasAlternateSentinel()) {
toggleColorMode(true);
} else {
toggleColorMode(false);
@ -288,6 +293,8 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<nav class="navbar navbar-expand-lg " data-bs-theme="dark">
<div class="navbar-container container-fluid">
<div class="navbar-brand-container mx-auto">
<a href="../../../index.html" class="navbar-brand navbar-brand-logo">
</a>
<a class="navbar-brand" href="../../../index.html">
<span class="navbar-title">Nicole Dresselhaus</span>
</a>
@ -299,12 +306,12 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav navbar-nav-scroll me-auto">
<li class="nav-item">
<a class="nav-link" href="../../../index.html"> <i class="bi bi-house" role="img">
<a class="nav-link active" href="../../../index.html" aria-current="page"> <i class="bi bi-house" role="img">
</i>
<span class="menu-text">Home</span></a>
</li>
<li class="nav-item">
<a class="nav-link active" href="../../../About/index.html" aria-current="page"> <i class="bi bi-file-person" role="img">
<a class="nav-link" href="../../../About/index.html"> <i class="bi bi-file-person" role="img">
</i>
<span class="menu-text">About</span></a>
</li>
@ -342,6 +349,10 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
<!-- sidebar -->
<nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation docked overflow-auto">
<div class="pt-lg-2 mt-2 text-left sidebar-header">
<a href="../../../index.html" class="sidebar-logo-link">
</a>
</div>
<div class="sidebar-menu-container">
<ul class="list-unstyled mt-1">
<li class="sidebar-item sidebar-item-section">
@ -385,12 +396,6 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<a href="../../../Writing/Obsidian-RAG.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">RAG für eine Obsidian-Wissensdatenbank: Technische Ansätze</span></a>
</div>
</li>
<li class="sidebar-item">
<div class="sidebar-item-container">
<a href="../../../Obsidian-Articles/Artikelbewertung durch LLM.html" class="sidebar-item-text sidebar-link">
<span class="menu-text">Artikelbewertung durch ein Large Language Model (LLM) - Ein Beispiel aus der Praxis</span></a>
</div>
</li>
</ul>
</li>
@ -687,18 +692,18 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<section id="erstellen-eines-neuen-projektes" class="level3">
<h3 class="anchored" data-anchor-id="erstellen-eines-neuen-projektes">Erstellen eines neuen Projektes</h3>
<p>Zunächst erstellen wir in normales Haskell-Projekt ohne Funktionalität &amp; Firlefanz:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">stack</span> new myservice</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">stack</span> new myservice</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>Dies erstellt ein neues Verzeichnis und das generelle scaffolding. Nach einer kurzen Anpassung der <code>stack.yaml</code> (resolver auf unserer setzen; aktuell: <code>lts-17.4</code>) fügen wir am Ende der Datei</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">allow-newer</span><span class="kw">:</span><span class="at"> </span><span class="ch">true</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">allow-newer</span><span class="kw">:</span><span class="at"> </span><span class="ch">true</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="fu">ghc-options</span><span class="kw">:</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="fu">"$locals"</span><span class="kw">:</span><span class="at"> -fwrite-ide-info</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="fu">"$locals"</span><span class="kw">:</span><span class="at"> -fwrite-ide-info</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>ein. Anschließend organisieren™ wir uns noch eine gute <code>.gitignore</code> und initialisieren das git mittels <code>git init; git add .; git commit -m "initial scaffold"</code></p>
</section>
<section id="generierung-der-api" class="level3">
<h3 class="anchored" data-anchor-id="generierung-der-api">Generierung der API</h3>
<p>Da die API immer wieder neu generiert werden kann (und sollte!) liegt sich in einem unterverzeichnis des Hauptprojektes.</p>
<p>Initial ist es das einfachste ein leeres temporäres Verzeichnis woanders zu erstellen, die <code>api-doc.yml</code> hinein kopieren und folgendes ausführen:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">openapi-generator</span> generate <span class="at">-g</span> haskell <span class="at">-o</span> . <span class="at">-i</span> api-doc.yml</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">openapi-generator</span> generate <span class="at">-g</span> haskell <span class="at">-o</span> . <span class="at">-i</span> api-doc.yml</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>Dieses erstellt einem dann eine komplette library inkl. Datentypen. Wichtig: Der Name in der <code>api-doc</code> sollte vom Namen des Services (oben <code>myservice</code>) abweichen - entweder in Casing oder im Namen direkt. Suffixe wie API schneidet der Generator hier leider ab. (Wieso das ganze? Es entstehen nachher 2 libraries, <code>foo</code> &amp; <code>fooAPI</code>. Da der generator das API abschneidet endet man mit foo &amp; foo und der compiler meckert, dass er nicht weiß, welche lib gemeint ist).</p>
<p>danach: wie gewohnt <code>git init; git add .; git commit -m "initial"</code>. Auf dem Server der Wahl (github, gitea, gitlab, …) nun ein Repository erstellen (am Besten: <code>myserviceAPI</code> - nach Konvention ist alles auf API endend autogeneriert!) und den Anweisungen nach ein remote hinzufügen &amp; pushen.</p>
<section id="wieder-zurück-im-haskell-service" class="level4">
@ -706,32 +711,32 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<p>In unserem eigentlichen Service müssen wir nun die API einbinden. Dazu erstellen wir ein Verzeichnis <code>libs</code> (Konvention) und machen ein <code>git submodule add &lt;repository-url&gt; libs/myserviceAPI</code></p>
<p>Git hat nun die API in das submodul gepackt und wir können das oben erstellte temporäre Verzeichnis wieder löschen.</p>
<p>Anschließend müssen wir stack noch erklären, dass wir die API da nun liegen haben und passen wieder die <code>stack.yaml</code> an, indem wir das Verzeichnis unter packages hinzufügen.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">packages</span><span class="kw">:</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">packages</span><span class="kw">:</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> .</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> libs/myserviceAPI</span><span class="co"> # &lt;&lt;</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> libs/myserviceAPI</span><span class="co"> # &lt;&lt;</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>Nun können wir in der <code>package.yaml</code> (oder <code>myservice.cabal</code>, falls kein <code>hpack</code> verwendet wird) unter den dependencies unsere API hinzufügen (name wie die cabal-Datei in <code>libs/myserviceAPI</code>).</p>
</section>
</section>
<section id="einbinden-anderer-microservices" class="level3">
<h3 class="anchored" data-anchor-id="einbinden-anderer-microservices">Einbinden anderer Microservices</h3>
<p>Funktioniert komplett analog zu dem vorgehen oben (ohne das generieren natürlich :grin:). <code>stack.yaml</code> editieren und zu den packages hinzufügen:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">packages</span><span class="kw">:</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">packages</span><span class="kw">:</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> .</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> libs/myserviceAPI</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> libs/myCoolMLServiceAPI</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> libs/myCoolMLServiceAPI</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>in der <code>package.yaml</code> (oder der cabal) die dependencies hinzufügen und schon haben wir die Features zur Verfügung und können gegen diese Services reden.</p>
</section>
<section id="entfernen-von-anderen-technologienmicroservices" class="level3">
<h3 class="anchored" data-anchor-id="entfernen-von-anderen-technologienmicroservices">Entfernen von anderen Technologien/Microservices</h3>
<p>In git ist das entfernen von Submodules etwas frickelig, daher hier ein copy&amp;paste der <a href="https://gist.github.com/myusuf3/7f645819ded92bda6677">GitHub-Antwort</a>:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co">## Remove the submodule entry from .git/config</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co">## Remove the submodule entry from .git/config</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> submodule deinit <span class="at">-f</span> path/to/submodule</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="co">## Remove the submodule directory from the superproject's .git/modules directory</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="ex">rm-rf</span> .git/modules/path/to/submodule</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="co">## Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> rm-f path/to/submodule</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> rm-f path/to/submodule</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>Falls das nicht klappt, gibt es alternative Vorschläge unter dem Link oben.</p>
</section>
<section id="woher-weiss-ich-was-wo-liegt-dokumentation-halloo" class="level3">
@ -743,9 +748,9 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<li><code>...../index.html</code> - hier sind nur die direkten dependencies aufgeführt.</li>
</ul>
<p>Wenn man einen lokalen Webserver startet kann man mittels “s” auch die interaktive Suche öffnen (Suche nach Typen, Funktionen, Signaturen, etc.). In Bash mit <code>python3</code> geht das z.b. einfach über:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> <span class="va">$(</span><span class="ex">stack</span> path <span class="at">--local-doc-root</span><span class="va">)</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> <span class="va">$(</span><span class="ex">stack</span> path <span class="at">--local-doc-root</span><span class="va">)</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">-m</span> SimpleHTTPServer 8000</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ex">firefox</span> <span class="st">"http://localhost:8000"</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ex">firefox</span> <span class="st">"http://localhost:8000"</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
</section>
<section id="implementation-des-services-und-start" class="level3">
<h3 class="anchored" data-anchor-id="implementation-des-services-und-start">Implementation des Services und Start</h3>
@ -759,7 +764,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
</ul>
<p>Für die Main kann man prinzipiell eine Main andere Services copy/pasten. Im folgenden eine Annotierte main-Funktion - zu den einzelnen Voraussetzungen kommen wir im Anschluss.</p>
<p></p><p></p><details><summary>Main.hs anzeigen</summary><blockquote class="blockquote"><p></p>
<div class="sourceCode" id="cb8" data-code-fold="true" data-code-summary="Code anzeigen"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-name-shadowing #-}</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" data-code-fold="true" data-code-summary="Code anzeigen"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-name-shadowing #-}</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleContexts #-}</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE LambdaCase #-}</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE OverloadedStrings #-}</span></span>
@ -939,7 +944,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<span id="cb8-178"><a href="#cb8-178" aria-hidden="true" tabindex="-1"></a> out _ r status _ _ payload _</span>
<span id="cb8-179"><a href="#cb8-179" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> statusCode status <span class="op">&lt;</span> <span class="dv">300</span> <span class="ot">=</span> <span class="st">""</span></span>
<span id="cb8-180"><a href="#cb8-180" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> statusCode status <span class="op">&gt;</span> <span class="dv">399</span> <span class="op">&amp;&amp;</span> statusCode status <span class="op">&lt;</span> <span class="dv">500</span> <span class="ot">=</span> <span class="st">"Error code "</span><span class="op">&lt;&gt;</span>toLogStr (statusCode status) <span class="op">&lt;&gt;</span><span class="st">" sent. Request-Payload was: "</span><span class="op">&lt;&gt;</span> <span class="fu">mconcat</span> (toLogStr <span class="op">&lt;$&gt;</span> payload) <span class="op">&lt;&gt;</span> <span class="st">"\n"</span></span>
<span id="cb8-181"><a href="#cb8-181" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> toLogStr (<span class="fu">show</span> r) <span class="op">&lt;&gt;</span> <span class="st">"\n"</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb8-181"><a href="#cb8-181" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> toLogStr (<span class="fu">show</span> r) <span class="op">&lt;&gt;</span> <span class="st">"\n"</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
</blockquote></details></section>
<section id="weitere-instanzen-und-definitionen-die-der-generator-noch-nicht-macht" class="level4">
<h4 class="anchored" data-anchor-id="weitere-instanzen-und-definitionen-die-der-generator-noch-nicht-macht">Weitere Instanzen und Definitionen, die der Generator (noch) nicht macht</h4>
@ -969,7 +974,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
</ul></li>
</ul>
<p></p><p></p><details><summary>Types.hs anzeigen</summary><blockquote class="blockquote"><p></p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-orphans #-}</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-orphans #-}</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wno-name-shadowing #-}</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveAnyClass #-}</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveFunctor #-}</span></span>
@ -1045,12 +1050,12 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<span id="cb9-74"><a href="#cb9-74" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb9-75"><a href="#cb9-75" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb9-76"><a href="#cb9-76" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Out</span> <span class="dt">Response</span></span>
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FromBSON</span> <span class="dt">Repsonse</span> <span class="co">-- FromBSON-Instanz geht immer davon aus, dass alle keys da sind (ggf. mit null bei Nothing).</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb9-77"><a href="#cb9-77" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">FromBSON</span> <span class="dt">Repsonse</span> <span class="co">-- FromBSON-Instanz geht immer davon aus, dass alle keys da sind (ggf. mit null bei Nothing).</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
</blockquote></details></section>
<section id="was-noch-zu-tun-ist" class="level4">
<h4 class="anchored" data-anchor-id="was-noch-zu-tun-ist">Was noch zu tun ist</h4>
<p>Den Service implementieren. Einfach ein neues Modul aufmachen (z.B. <code>MyService.Handler</code> oder <code>MyService.DieserEndpunktbereich</code>/<code>MyService.JenerEndpunktbereich</code>) und dort die Funktion implementieren, die man in der <code>Main.hs</code> benutzt hat. In dem Handler habt ihr dann keinen Stress mehr mit Validierung, networking, logging, etc. pp. weil alles in der Main abgehandelt wurde und ihr nur noch den “Happy-Case” implementieren müsst. Beispiel für unseren Handler oben:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">myApiEndpointV1Post ::</span> <span class="dt">MonadIO</span> m <span class="ot">=&gt;</span> <span class="dt">ServerConfig</span> <span class="ot">-&gt;</span> (<span class="dt">ClientEnv</span>,<span class="dt">ClientEnv</span>) <span class="ot">-&gt;</span> <span class="dt">TQueue</span> <span class="dt">BS.ByteString</span> <span class="ot">-&gt;</span> ([<span class="dt">LogItem</span>] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()) <span class="ot">-&gt;</span> <span class="dt">Request</span> <span class="ot">-&gt;</span> m <span class="dt">Response</span></span>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10"><pre class="sourceCode haskell code-with-copy"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">myApiEndpointV1Post ::</span> <span class="dt">MonadIO</span> m <span class="ot">=&gt;</span> <span class="dt">ServerConfig</span> <span class="ot">-&gt;</span> (<span class="dt">ClientEnv</span>,<span class="dt">ClientEnv</span>) <span class="ot">-&gt;</span> <span class="dt">TQueue</span> <span class="dt">BS.ByteString</span> <span class="ot">-&gt;</span> ([<span class="dt">LogItem</span>] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()) <span class="ot">-&gt;</span> <span class="dt">Request</span> <span class="ot">-&gt;</span> m <span class="dt">Response</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>myApiEndpointV1Post sc calls amqPost <span class="fu">log</span> req <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a> liftIO <span class="op">.</span> <span class="fu">log</span> <span class="op">$</span> [<span class="dt">Info</span> <span class="op">$</span> <span class="st">"recieved "</span><span class="op">&lt;&gt;</span>pretty req] <span class="co">-- input-logging</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a> liftIO <span class="op">.</span> atomically <span class="op">.</span> writeTQueue <span class="op">.</span> LBS.toStrict <span class="op">$</span> <span class="st">"{\"hey Kibana, i recieved:\""</span> <span class="op">&lt;&gt;</span> A.encode (pretty req) <span class="op">&lt;&gt;</span> <span class="st">"}"</span> <span class="co">-- log in activeMQ/Kibana</span></span>
@ -1064,7 +1069,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a> liftIO <span class="op">.</span> access pipe master <span class="st">"DatabaseName"</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a> ifM (auth (myServiceMongoUsername sc) (myServiceMongoPassword sc)) (<span class="fu">return</span> ()) (liftIO <span class="op">.</span> printLog <span class="op">.</span> <span class="fu">pure</span> <span class="op">.</span> <span class="dt">Error</span> <span class="op">$</span> <span class="st">"MongoDB: Login failed."</span>)</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a> save <span class="st">"DatabaseCollection"</span> [<span class="st">"_id"</span> <span class="op">=:</span> <span class="dv">1337</span>, <span class="st">"entry"</span> <span class="op">=:</span> ret] <span class="co">-- selbe id wie oben ;)</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">return</span> ret</span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a> <span class="fu">return</span> ret</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>Diese dummy-Antwort führt auf, wie gut man die ganzen Sachen mischen kann.</p>
<ul>
<li>Logging in die Dateien/<code>stdout</code> - je nach Konfiguration</li>
@ -1085,7 +1090,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
</section>
<section id="wie-sorge-ich-für-bessere-warnungen-damit-der-compiler-meine-bugs-fängt" class="level5">
<h5 class="anchored" data-anchor-id="wie-sorge-ich-für-bessere-warnungen-damit-der-compiler-meine-bugs-fängt">Wie sorge ich für bessere Warnungen, damit der Compiler meine Bugs fängt?</h5>
<div class="sourceCode" id="cb11"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">stack</span> build <span class="at">--file-watch</span> <span class="at">--ghc-options</span> <span class="st">'-freverse-errors -W -Wall -Wcompat'</span> <span class="at">--interleaved-output</span></span></code><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></pre></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ex">stack</span> build <span class="at">--file-watch</span> <span class="at">--ghc-options</span> <span class="st">'-freverse-errors -W -Wall -Wcompat'</span> <span class="at">--interleaved-output</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
<p>Was tut das?</p>
<ul>
<li><code>--file-watch</code>: automatisches (minimales) kompilieren bei dateiänderungen</li>
@ -1153,7 +1158,7 @@ pre > code.sourceCode > span > a:first-child::before { text-decoration: underlin
a.appendChild(i);
window.document.body.appendChild(a);
}
window.setColorSchemeToggle(window.hasAlternateSentinel())
setColorSchemeToggle(hasAlternateSentinel())
const icon = "";
const anchorJS = new window.AnchorJS();
anchorJS.options = {