no longer leaving behind garbage in the form of serve_xyz
This commit is contained in:
parent
015dfd1769
commit
38d366c895
3 changed files with 27 additions and 13 deletions
|
@ -1,4 +1,4 @@
|
|||
# Functors and Applicatives for Free[^falsehood]
|
||||
# Functors and Applicatives, Gratis[^falsehood]
|
||||
|
||||
It's usually possible to derive implementations of general structures from those of more specific ones, e.g. `Applicative` from `Monad` and `Functor` from `Applicative`. Here's how to do it and and why it's probably best avoided.
|
||||
|
||||
|
@ -19,7 +19,11 @@ module type Monad = sig
|
|||
val return : 'a -> 'a t
|
||||
val bind : ('a -> 'b t) -> 'a t -> 'b t
|
||||
end
|
||||
```
|
||||
|
||||
Here we have the usual module signatures for functors, applicative functors, and monads respectively. The only thing of note is that I've written everything pipe-last[^pipe-last]. It's more common to see these in pipe-first style to agree with the respective infix operators, but I don't see any of those around to get offended; do you?
|
||||
|
||||
```ocaml
|
||||
module ApplicativeOfMonad (M : Monad) :
|
||||
Applicative with type 'a t = 'a M.t = struct
|
||||
type 'a t = 'a M.t
|
||||
|
@ -39,6 +43,8 @@ module FunctorOfMonad (M : Monad) :
|
|||
end
|
||||
```
|
||||
|
||||
Each of these accepts an instance of a less general structure and uses only the elements the module provides to implement an instance of the more general structure.
|
||||
|
||||
It turns out that there are multiple ways to implement the derivation functors--- also multiple ways to implement a particular monad--- and they don't all behave the same, which means it's hard to predict whether the more-general, derived implementations are the "natural" ones that you expected to get without _ad hoc_ testing, which obviously rather defeats the point of "free". On the other hand, the derivations here can be performed pretty mechanically, with little insight, by following the types in much the same way one might mechanically prove an easy proposition.
|
||||
|
||||
***
|
||||
|
@ -47,6 +53,8 @@ The modules above that seem to have parameters, do; these modules are called "fu
|
|||
|
||||
A subtlety of the OCaml module system is that if a module is defined with a particular `module type` a.k.a. signature attached, e.g. `module M : S = struct...`, all the types that are abstract in the signature `S` will _also_ be abstract in the module itself. This means that the compiler can't see or be convinced that for some `F (M)` with `type t = M.t` in `F`, `M.t` and `(F (M)).t` are equal. This is because both types are abstract, meaning the underlying type is not available. To fix this, we can explicitly expose the equality by using the `with type` construct. In the above, `Functor with type 'a t = 'a M.t`--- for example--- exposes the equality of the two types, so that functions defined as expecting arguments of `'a t` can accept `'a M.t`, and _vice versa_.
|
||||
|
||||
[^falsehood]: Unsurprisingly, that's a lie. You have to buy a `Monad` first.
|
||||
[^falsehood]: Unsurprisingly, that's a lie. Isn't it always? You have to buy a `Monad` first.
|
||||
|
||||
[^1ml]: See [1ML](https://people.mpi-sws.org/~rossberg/1ml/1ml-jfp-draft.pdf) for an OCaml-like language without this stratification.
|
||||
[^1ml]: See [1ML](https://people.mpi-sws.org/~rossberg/1ml/1ml-jfp-draft.pdf) for an OCaml-like language without this stratification.
|
||||
|
||||
[^pipe-last]: This idea is that to synergize with the automatic currying of OCaml, parameters to which a function is more likely to be "partially applied" should be earlier in the argument list. This cuts down on syntactic noise; particularly, pipes which apply to the _last_ argument (see?) don't require shuffling-about of the parameter order, e.g. `xs |> List.map f` rather than `xs |> (fun xs -> List.map xs f)`. JaneStreet will tell you that labels address the issue best, but to my eyes, `:` and `~` were never meant to stand that close to one another.
|
24
build.sh
24
build.sh
|
@ -3,11 +3,11 @@
|
|||
#! nix-shell -p bash harfbuzz soupault woff2 jotdown python3 --pure
|
||||
|
||||
if ! [[ -d pgvv/ ]]; then
|
||||
python3 -m venv pgvv
|
||||
source ./pgvv/bin/activate
|
||||
python3 -m pip install --upgrade pip
|
||||
pip install --upgrade pygments
|
||||
deactivate
|
||||
python3 -m venv pgvv
|
||||
source ./pgvv/bin/activate
|
||||
python3 -m pip install --upgrade pip
|
||||
pip install --upgrade pygments
|
||||
deactivate
|
||||
fi
|
||||
|
||||
function soup_config {
|
||||
|
@ -58,20 +58,26 @@ pygmentize -f html -S algol_nu | grep -v 'line-height' >css/code.css
|
|||
builtin pushd acl.cool
|
||||
soup_config
|
||||
soupault
|
||||
|
||||
NEXT_DIR="serve_$(date +%s)"
|
||||
CUR_DIR=$(find . -maxdepth 1 -type d -regex './serve_[0-9]+')
|
||||
echo "$PREV_DIR"
|
||||
cp -a serve "$NEXT_DIR"
|
||||
ln -sfn "$NEXT_DIR" serve_
|
||||
|
||||
for d in $CUR_DIR; do
|
||||
rm -r $d
|
||||
done
|
||||
popd
|
||||
|
||||
builtin pushd ytheleus.org
|
||||
soup_config
|
||||
soupault
|
||||
|
||||
NEXT_DIR="serve_$(date +%s)"
|
||||
CUR_DIR=$(find . -maxdepth 1 -type d -regex './serve_[0-9]+')
|
||||
cp -a serve "$NEXT_DIR"
|
||||
ln -sfn "$NEXT_DIR" serve_
|
||||
|
||||
for d in $CUR_DIR; do
|
||||
rm -r $d
|
||||
done
|
||||
popd
|
||||
|
||||
deactivate
|
||||
|
|
|
@ -139,4 +139,4 @@ delete_all = true
|
|||
[widgets.syntax]
|
||||
widget = "preprocess_element"
|
||||
selector = 'pre code'
|
||||
command = "pygmentize -l \"$(awk -F \\- '{print $NF}' <<< $ATTR_CLASS)\" -f html | head -c -13 | awk -F '<pre>' '{print $NF}'"
|
||||
command = "pygmentize -l ${ATTR_CLASS##*-} -f html | head -c -13 | awk -F '<pre>' '{print $NF}'"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue