spout: s17
This commit is contained in:
parent
2748bc5640
commit
f932215a0d
3 changed files with 66 additions and 68 deletions
|
|
@ -1,58 +0,0 @@
|
|||
---
|
||||
title: "Monads: Why and how"
|
||||
description: I could not repress the urge to make a monad explainer any longer. Did you know that a monad is a monoid in the category of endofunctors?
|
||||
tags: post,short,haskell
|
||||
date: 2026-05-06 01:20:10 -5
|
||||
---
|
||||
|
||||
I acknowledge that [the world wide web has one hundred trillion monad explainers.](https://wiki.haskell.org/Monad_tutorials_timeline)
|
||||
|
||||

|
||||
|
||||
## Why monads
|
||||
In the land of Haskell and friends, we love referential transparency.
|
||||
We greatly appreciate that
|
||||
```haskell
|
||||
let x = 1 in x + x
|
||||
```
|
||||
will always have the same result as
|
||||
```haskell
|
||||
1 + 1
|
||||
```
|
||||
|
||||
In languages where (almost) no functions have unmarked side-effects, like Haskell, you can even be confident that
|
||||
```haskell
|
||||
let x = f y in x + x
|
||||
```
|
||||
is the same as
|
||||
```haskell
|
||||
(f y) + (f y)
|
||||
```
|
||||
|
||||
This is a truly excellent property to have, but it causes some problems when your program starts interacting with the world.
|
||||
|
||||
Aside from referential transparency, we don't want to fix evaluation order if we don't have to;
|
||||
giving the compiler more freedom to reorder evaluation lets it perform more optimizations.
|
||||
And we always want more optimizations.
|
||||
|
||||
But, quite often, we *need* things to happen in a specific order.
|
||||
|
||||
Monads let us do two things:
|
||||
1. Order operations
|
||||
2. Use past results to decide what to do next
|
||||
|
||||
## How monads
|
||||
Easy:
|
||||
```haskell
|
||||
class Monad m where
|
||||
(>>=) :: m a -> (a -> m b) -> m b
|
||||
pure :: a -> m a
|
||||
```
|
||||
|
||||
`>>=`, pronounced `bind`, gives us ordering and lets us use past results to decide what to do next.
|
||||
|
||||
The fact that it gives us ordering is made more clear if we define `>>`, which ignores its result:
|
||||
```haskell
|
||||
(>>) :: m a -> m b -> m b
|
||||
a >> b = a >>= \_ -> b
|
||||
```
|
||||
|
|
@ -144,6 +144,12 @@ h2 {
|
|||
<body>
|
||||
<h1 style="margin: 1rem">spout: reverse-chron html pieces by <a href="https://terezi.pyrope.net">mehbark</a></h1>
|
||||
|
||||
<article id="s18">
|
||||
<h1><a href="#s18">#</a> variable weight noodling</h1>
|
||||
<p>warning: smoothly changing fonts that may be a bit nauseating. also uses google fonts (shame).</p>
|
||||
<p><a href="./variable-font-noodling.html">enter if you dare</a></p>
|
||||
</article>
|
||||
|
||||
<article id="s17">
|
||||
<h1><a href="#s17">#</a> graphing with sign-changes</h1>
|
||||
<p>I had somehow never heard of this canonical graphing technique until watching <a href="https://www.youtube.com/watch?v=YJJk0iLJ4Ks">this video about a 3d graphing calculator in minecraft</a></p>
|
||||
|
|
|
|||
50
site-src/spout/variable-font-noodling.html
Normal file
50
site-src/spout/variable-font-noodling.html
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>variable font weights</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Next:wght@200..800&family=Google+Sans+Flex:opsz,wght@6..144,1..1000&family=Inter:opsz,wght@14..32,100..900&family=JetBrains+Mono:wght@100..800&family=Montserrat:wght@100..900&family=Open+Sans:wght@300..800&family=Playfair+Display:wght@400..900&family=Source+Code+Pro:wght@200..900&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
ul {
|
||||
list-decoration: none;
|
||||
}
|
||||
li {
|
||||
font-optical-sizing: auto;
|
||||
font-size: 10rem;
|
||||
text-align: center;
|
||||
animation: vary 6.7s linear infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes vary {
|
||||
from {
|
||||
font-weight: var(--min);
|
||||
}
|
||||
|
||||
to {
|
||||
font-weight: var(--max);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => document.querySelectorAll("li").forEach(li => {
|
||||
const family = li.style.fontFamily.replaceAll('"', "");
|
||||
const min = li.style.getPropertyValue("--min");
|
||||
const max = li.style.getPropertyValue("--max");
|
||||
li.title = `${family} (${min}-${max})`
|
||||
}));
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
<li style="--min: 200; --max: 800; font-family: 'Atkinson Hyperlegible Next'">Variable</li>
|
||||
<li style="--min: 1; --max: 1000; font-family: 'Google Sans Flex'">Variable</li>
|
||||
<li style="--min: 300; --max: 800; font-family: 'Open Sans'">Variable</li>
|
||||
<li style="--min: 100; --max: 900; font-family: 'Inter'">Variable</li>
|
||||
<li style="--min: 100; --max: 900; font-family: 'Montserrat'">Variable</li>
|
||||
<li style="--min: 400; --max: 900; font-family: 'Playfair Display'">Variable</li>
|
||||
<li style="--min: 200; --max: 900; font-family: 'Source Code Pro'">Variable</li>
|
||||
<li style="--min: 100; --max: 800; font-family: 'JetBrains Mono'">Variable</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue