diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..423d5dd
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,21 @@
+root = true
+
+[*]
+indent_size = 4
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[Makefile]
+indent_style = tab
+
+[*.{tex,cls,lua,nix}]
+indent_style = space
+indent_size = 2
+max_line_length = 80
+
+[*.md]
+trim_trailing_whitespace = false
+indent_size = 2
+max_line_length = 80
diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..558f7ab
--- /dev/null
+++ b/.envrc
@@ -0,0 +1,2 @@
+use flake .
+use flake github:loophp/nix-prettier
diff --git a/.github/settings.yml b/.github/settings.yml
new file mode 100644
index 0000000..9b07571
--- /dev/null
+++ b/.github/settings.yml
@@ -0,0 +1,51 @@
+# https://github.com/probot/settings
+
+branches:
+ - name: master
+ protection:
+ enforce_admins: false
+ required_pull_request_reviews:
+ dismiss_stale_reviews: true
+ require_code_owner_reviews: true
+ required_approving_review_count: 1
+ restrictions: null
+ required_linear_history: true
+ required_status_checks:
+ strict: true
+
+labels:
+ - name: typo
+ color: ee0701
+
+ - name: dependencies
+ color: 0366d6
+
+ - name: enhancement
+ color: 0e8a16
+
+ - name: question
+ color: cc317c
+
+ - name: security
+ color: ee0701
+
+ - name: stale
+ color: eeeeee
+
+repository:
+ allow_merge_commit: true
+ allow_rebase_merge: true
+ allow_squash_merge: true
+ default_branch: master
+ description:
+ "Bartosz Milewski's 'Category Theory for Programmers' unofficial PDF and
+ LaTeX sources"
+ homepage: https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/
+ topics: pdf,haskell,scala,latex,cpp,functional-programming,ocaml,category-theory
+ has_downloads: true
+ has_issues: true
+ has_pages: false
+ has_projects: false
+ has_wiki: false
+ name: milewski-ctfp-pdf
+ private: false
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
deleted file mode 100644
index 06da2b3..0000000
--- a/.github/workflows/build.yaml
+++ /dev/null
@@ -1,117 +0,0 @@
-name: Build PDFs
-
-on:
- - push
-
-jobs:
- dependencies:
- name: Build dependencies
- runs-on: ubuntu-latest
- outputs:
- version: ${{ steps.version.outputs.version }}
-
- steps:
- - name: Set up Git repository
- uses: actions/checkout@v2
- with:
- fetch-depth: 1
-
- - name: Create global variables
- id: version
- run: echo "::set-output name=version::$(git rev-parse --short HEAD)"
-
- determine-matrix:
- name: Figure out the packages we need to build
- runs-on: ubuntu-latest
- needs: [dependencies]
-
- outputs:
- matrix: ${{ steps.set-matrix.outputs.matrix }}
-
- steps:
- - name: Set up Git repository
- uses: actions/checkout@v2
- with:
- fetch-depth: 1
-
- - name: Install the Nix package manager
- uses: cachix/install-nix-action@v16
-
- - id: set-matrix
- run: |
- echo "::set-output name=matrix::$(
- nix eval --json --impure \
- --expr 'builtins.attrNames (import ./.).packages.x86_64-linux'
- )"
-
- build:
- name: Build documents
- needs: determine-matrix
- runs-on: ubuntu-latest
- strategy:
- matrix:
- packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}
-
- steps:
- - name: Set up Git repository
- uses: actions/checkout@v2
- with:
- fetch-depth: 1
-
- - name: Install Nix
- uses: cachix/install-nix-action@v16
-
- - name: Build ${{ matrix.packages }}.pdf
- run: |
- nix build .#${{ matrix.packages }}
- mkdir -p out
- cp -ar ./result/* out/
-
- - name: Upload build assets (${{ matrix.packages }}.pdf)
- uses: actions/upload-artifact@v2
- with:
- name: ctfp
- path: out/*
-
- release:
- name: "Create Github tag/pre-release"
- runs-on: ubuntu-latest
- needs: [dependencies, build]
- outputs:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
- steps:
- - name: Create Github pre-release (${{ needs.dependencies.outputs.version }})
- id: create_release
- uses: actions/create-release@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: v${{ github.run_number }}-${{ needs.dependencies.outputs.version }}
- release_name: Version ${{ github.run_number }} (${{ needs.dependencies.outputs.version }})
- draft: false
- prerelease: true
-
- assets:
- name: Upload release assets
- runs-on: ubuntu-latest
- needs: [determine-matrix, dependencies, release]
- strategy:
- matrix:
- packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}
-
- steps:
- - name: Download build assets (${{ matrix.packages }}.pdf)
- uses: actions/download-artifact@v2
- with:
- name: ctfp
- path: ctfp
-
- - name: Upload release assets (${{ matrix.packages }}--${{ needs.dependencies.outputs.version }}.pdf)
- uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ needs.release.outputs.upload_url }}
- asset_path: ctfp/${{ matrix.packages }}.pdf
- asset_name: ${{ matrix.packages }}--${{ needs.dependencies.outputs.version }}.pdf
- asset_content_type: application/pdf
diff --git a/.github/workflows/nix-flake-check.yaml b/.github/workflows/nix-flake-check.yaml
new file mode 100644
index 0000000..37465b1
--- /dev/null
+++ b/.github/workflows/nix-flake-check.yaml
@@ -0,0 +1,64 @@
+name: Check and build
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+jobs:
+ dependencies:
+ name: Build dependencies
+ runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.version.outputs.version }}
+
+ steps:
+ - name: Set up Git repository
+ uses: actions/checkout@v3
+
+ - name: Create global variables
+ id: version
+ run:
+ echo "version=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
+
+ determine-matrix:
+ name: Figure out the packages we need to build
+ runs-on: ubuntu-latest
+ needs: [dependencies]
+
+ outputs:
+ matrix: ${{ steps.set-matrix.outputs.matrix }}
+
+ steps:
+ - name: Set up Git repository
+ uses: actions/checkout@v3
+
+ - name: Install the Nix package manager
+ uses: cachix/install-nix-action@v18
+
+ - id: set-matrix
+ run: |
+ echo "matrix=$(
+ nix eval --json .#packages.x86_64-linux --apply builtins.attrNames
+ )" >> $GITHUB_OUTPUT
+
+ build:
+ name: Build
+ needs: determine-matrix
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}
+
+ steps:
+ - name: Set up Git repository
+ uses: actions/checkout@v3
+
+ - name: Install Nix
+ uses: cachix/install-nix-action@v18
+
+ - name: Nix flake check
+ run: nix flake check
+
+ - name: Build ${{ matrix.packages }}.pdf
+ run: nix build .#${{ matrix.packages }}
diff --git a/.github/workflows/nix-fmt-checks.yaml b/.github/workflows/nix-fmt-checks.yaml
new file mode 100644
index 0000000..4439b89
--- /dev/null
+++ b/.github/workflows/nix-fmt-checks.yaml
@@ -0,0 +1,17 @@
+name: Nix formatter checks
+
+on:
+ pull_request:
+
+jobs:
+ format-check:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Install Nix
+ uses: cachix/install-nix-action@v18
+
+ - name: Run nix formatter tool
+ run: nix fmt . -- --check
diff --git a/.github/workflows/prettier-checks.yaml b/.github/workflows/prettier-checks.yaml
new file mode 100644
index 0000000..9090c5c
--- /dev/null
+++ b/.github/workflows/prettier-checks.yaml
@@ -0,0 +1,18 @@
+name: Prettier checks
+
+on:
+ pull_request:
+
+jobs:
+ prettier:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Install the Nix package manager
+ uses: cachix/install-nix-action@v18
+
+ - name: Checks
+ run: nix run nixpkgs#nodePackages.prettier -- --check .
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
new file mode 100644
index 0000000..37b6b1f
--- /dev/null
+++ b/.github/workflows/release.yaml
@@ -0,0 +1,99 @@
+name: Release PDFs
+
+on:
+ push:
+ tags:
+ - "**"
+
+jobs:
+ determine-matrix:
+ name: Figure out the assets we need to build
+ runs-on: ubuntu-latest
+
+ outputs:
+ matrix: ${{ steps.set-matrix.outputs.matrix }}
+
+ steps:
+ - name: Set up Git repository
+ uses: actions/checkout@v3
+
+ - name: Install the Nix package manager
+ uses: cachix/install-nix-action@v18
+
+ - id: set-matrix
+ run: |
+ echo "matrix=$(
+ nix eval --json --impure \
+ --expr 'builtins.filter (x: (null == builtins.match "(.*)-nts" x)) (builtins.attrNames (import ./.).packages.x86_64-linux)'
+ )" >> $GITHUB_OUTPUT
+
+ build:
+ name: Build documents
+ needs: determine-matrix
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}
+
+ steps:
+ - name: Set up Git repository
+ uses: actions/checkout@v3
+
+ - name: Install Nix
+ uses: cachix/install-nix-action@v18
+
+ - name: Build ${{ matrix.packages }}.pdf
+ run: |
+ nix build .#${{ matrix.packages }}
+ mkdir -p out
+ cp -ar ./result/* out/
+
+ - name: Upload build assets (${{ matrix.packages }}.pdf)
+ uses: actions/upload-artifact@v2
+ with:
+ name: ctfp
+ path: out/*
+
+ release:
+ name: "Create Github pre-release"
+ runs-on: ubuntu-latest
+ needs: [build]
+ outputs:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ steps:
+ - name: Create Github pre-release (${{ github.ref }})
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref }}
+ release_name: ${{ github.ref }}
+ draft: true
+
+ assets:
+ name: Upload release assets
+ runs-on: ubuntu-latest
+ needs: [determine-matrix, release]
+ strategy:
+ matrix:
+ packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}
+
+ steps:
+ - name: Download build assets (${{ matrix.packages }}.pdf)
+ uses: actions/download-artifact@v2
+ with:
+ name: ctfp
+ path: ctfp
+
+ - name:
+ Upload release assets (${{ matrix.packages }}--${{ github.ref
+ }}.pdf)
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ needs.release.outputs.upload_url }}
+ asset_path: ctfp/${{ matrix.packages }}.pdf
+ asset_name: ${{ matrix.packages }}--${{ github.ref }}.pdf
+ asset_content_type: application/pdf
diff --git a/.gitignore b/.gitignore
index c1cc3ff..cd478b1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,16 +1,26 @@
-.vscode/
-*.fls
+/.vscode/
+/.direnv/
+/build/
+/result
+.DS_Store
+src/.dotty-ide-disabled
+src/.metals
+out/
_minted*
-*.fdb_latexmk
+*.fls
out/*
+*.fdb_latexmk
+*.bak*
+*.log
*.pdf
*.xdv
*.gz
-src/version.tex
*.pyg
*.synctex(busy)
-src/.dotty-ide-disabled
-venv/*
-.DS_Store
-src/.metals
-out/
\ No newline at end of file
+*.aux
+*.idx
+*.ilg
+*.lig
+*.ind
+*.out
+*.toc
diff --git a/.latexindent.yaml b/.latexindent.yaml
new file mode 100644
index 0000000..7e60ec5
--- /dev/null
+++ b/.latexindent.yaml
@@ -0,0 +1,7 @@
+defaultIndent: " "
+verbatimEnvironments:
+ verbatim: 1
+ lstlisting: 1
+ minted: 1
+ snip: 1
+ snipv: 1
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..c47d4a1
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,6 @@
+/.direnv/
+/.idea/
+/vendor/
+/docs/
+/build/
+CHANGELOG.md
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..4b1ce6b
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,3 @@
+{
+ "proseWrap": "always"
+}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 490671f..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-language:
-- nix
-
-script:
-- nix-shell --pure --command 'cd src; make all'
-
-cache:
- directories:
- src/_minted-ctfp
-
-deploy:
- - provider: releases
- api_key:
- secure: usNWQZc/HcrZxR72+Qz2YXeyf56h0EwLVl6oOXIivxTWQCTTQ0cE6tXG6lP8JxQ1qlfAhbdh4QOmz6jxQD60HxsUwDWmt9t51o+8n3EMeID0hc45ES40/mbieUfR1jbkLbwmL16Z/bWsvUErmGuUgOxYrUCplK9fWs7Vvt8xmReFdunw8XpVrywG4rl1jXDo9YWihMps5KLOqd3mY3yvlxAmB+UKkhHPNdcEuEghEBhC8HZoZkFiwfRw/8PeOh9VpnQ2ht9eDXOlB7zNYY9Xr/S98FbzfZXxFjApXVRgNP8k2UYyHn8HCmIoCSs+Jv06tEvNCuwTvj0JNsuoW7vu/Q7wrrpScfDL+WnSw2CScml+xAe7Q4caoZKkzaMCnj5fHbPEZ731+SLZNbG6TMTYhMqhFm0Fr87bwdNlayqAssIhOwU4ca3pnZOQFO4vNOWblNfbHsX5F9sJDOR0uD4Y+PgfNWgTsssXqei7owBJNTe+qz5Q7IaFA3A8EMp57CV1dUCgmjxVuugtz6DLpl16WGiWpqakIA900GXMG+2c4ENCCDWmYtGlpWs2lSBqRYHV1gncE8UGtIih8G6g5jQd2aJUQKHKuaEiv/28WLI7f2exUuOBmc0ce4xP+qZAs5XWiPo4jJLNyb81uNIZ0jCb/c5+lEH8EsYF+jFOrmw17GQ=
- file: out/**/*.pdf
- file_glob: true
- skip_cleanup: true
- on:
- repo: hmemcpy/milewski-ctfp-pdf
- branch: master
- tags: true
- - provider: s3
- bucket: milewski-ctfp-pdf
- access_key_id: '$ARTIFACTS_KEY'
- secret_access_key: '$ARTIFACTS_SECRET'
- region: us-east-1
- acl: public_read
- local_dir: out
- skip_cleanup: true
- on:
- all_branches: true
- repo: hmemcpy/milewski-ctfp-pdf
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..fe7a719
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,31 @@
+OUTPUT ?= $(shell basename "$(shell dirname "$(INPUT)")")
+OUTPUT_DIRECTORY = $(shell pwd)/build
+LATEXMK_ARGS ?= -f -file-line-error -shell-escape -logfilewarninglist -interaction=nonstopmode -halt-on-error -norc -pdflatex="xelatex %O %S" -pdfxe
+TEXINPUTS = ""
+TEXLIVE_RUN = TEXINPUTS=$(TEXINPUTS)
+LATEXMK_COMMAND = $(TEXLIVE_RUN) latexmk $(LATEXMK_ARGS)
+
+# Make does not offer a recursive wildcard function, so here's one:
+rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
+
+ctfp:
+ cd src; $(LATEXMK_COMMAND) -jobname=ctfp ctfp-reader.tex
+
+ctfp-ocaml:
+ cd src; $(LATEXMK_COMMAND) -jobname=ctfp-ocaml ctfp-reader-ocaml.tex
+
+ctfp-scala:
+ cd src; $(LATEXMK_COMMAND) -jobname=ctfp-scala ctfp-reader-scala.tex
+
+ctfp-print:
+ cd src; $(LATEXMK_COMMAND) -jobname=ctfp-print ctfp-print.tex
+
+ctfp-print-ocaml:
+ cd src; $(LATEXMK_COMMAND) -jobname=ctfp-print-ocaml ctfp-print-ocaml.tex
+
+ctfp-print-scala:
+ cd src; $(LATEXMK_COMMAND) -jobname=ctfp-print-scala ctfp-print-scala.tex
+
+lint:
+ $(foreach file, $(call rwildcard,$(shell dirname "$(INPUT)"),*.tex), latexindent -l -w $(file);)
+
diff --git a/README.md b/README.md
index a2d2425..0fcfb5a 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,106 @@
-Category Theory for Programmers
-====
-![image](https://user-images.githubusercontent.com/601206/43392303-f770d7be-93fb-11e8-8db8-b7e915b435ba.png)
-Direct link: [category-theory-for-programmers.pdf](https://github.com/hmemcpy/milewski-ctfp-pdf/releases/download/v1.3.0/category-theory-for-programmers.pdf)
-(Latest release: v1.3.0, August 2019. See [releases](https://github.com/hmemcpy/milewski-ctfp-pdf/releases) for additional formats and languages.)
+![GitHub stars][github stars]
+[![GitHub Workflow Status][github workflow status]][github actions link]
+[![Download][download badge]][github latest release]
+[![License][license badge]][github latest release]
-[![Build Status](https://travis-ci.org/hmemcpy/milewski-ctfp-pdf.svg?branch=master)](https://travis-ci.org/hmemcpy/milewski-ctfp-pdf)
-[(latest CI build)](https://s3.amazonaws.com/milewski-ctfp-pdf/category-theory-for-programmers.pdf)
+# Category Theory For Programmers
-
-**[Available in full-color hardcover print](https://www.blurb.com/b/9621951-category-theory-for-programmers-new-edition-hardco)**
-Publish date: 12 August, 2019. Based off release tag [v1.3.0](https://github.com/hmemcpy/milewski-ctfp-pdf/releases/tag/v1.3.0). See [errata-1.3.0](errata-1.3.0.md) for changes and fixes since print.
+An _unofficial_ PDF version of "**C**ategory **T**heory **F**or **P**rogrammers"
+by [Bartosz Milewski][bartosz github], converted from his [blogpost
+series][blogpost series] (_with permission!_).
-**[Scala Edition is now available in paperback](https://www.blurb.com/b/9603882-category-theory-for-programmers-scala-edition-pape)**
-Publish date: 12 August, 2019. Based off release tag [v1.3.0](https://github.com/hmemcpy/milewski-ctfp-pdf/releases/tag/v1.3.0). See [errata-scala](errata-scala.md) for changes and fixes since print.
+![Category Theory for Programmers][ctfp image]
-This is an *unofficial* PDF version of "Category Theory for Programmers" by Bartosz Milewski, converted from his [blogpost series](https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/) (with permission!)
+## Buy the book
----
+- **[Standard edition in full-color hardcover
+ print][buy regular edition on blurb]**
+ - Publish date: 12 August, 2019.
+ - Based off release tag [v1.3.0][v1.3.0 github release link]. See
+ [errata-1.3.0](errata-1.3.0.md) for changes and fixes since print.
+- **[Scala Edition in paperback][buy scala edition on blurb]**
+ - Publish date: 12 August, 2019.
+ - Based off release tag [v1.3.0][v1.3.0 github release link]. See
+ [errata-scala](errata-scala.md) for changes and fixes since print.
-Building
---------
+## Build the book
-The best way to build the book is using the [Nix](https://nixos.org/nix/) package manager. After [installing Nix](https://nixos.org/download.html), if you're using a non-NixOS operating system, you need to install `nixFlakes` in your environment following the steps below ([source](https://nixos.wiki/wiki/Flakes#Non-NixOS)):
+The building workflow requires [Nix][nix website]. After [installing
+Nix][nix download website], you need to enable the upcoming "flake" feature
+which must be [enabled manually][nixos wiki flake] the time being. This is
+needed to expose the new Nix commands and flakes support that are hidden behind
+feature-flags.
-```bash
-$ nix-env -iA nixpkgs.nixFlakes
-```
+Afterwards, type `nix flake show` in the root directory of the project to see
+all the available versions of this book. Then type `nix build .#` to
+build the edition you want (Haskell, Scala, OCaml, Reason and their printed
+versions). For example, to build the Scala edition you'll have to type
+`nix build .#ctfp-scala`.
-Edit either `~/.config/nix/nix.conf` or `/etc/nix/nix.conf` and add:
+Upon successful compilation, the PDF file will be placed in the `result`
+directory.
-```
-experimental-features = nix-command flakes
-```
+The command `nix develop` will provide a shell containing all the required
+dependencies to build the book manually using the provided `Makefile`. To build
+the `ctfp-scala` edition, just run `make ctfp-scala`.
-This is needed to expose the Nix 2.0 CLI and flakes support that are hidden behind feature-flags.
+## Contribute
-Also, if the Nix installation is in multi-user mode, don’t forget to restart the nix-daemon.
+Contributors are welcome to contribute to this book by sending pull-requests.
+Once reviewed, the changes are merged in the main branch and will be
+incorporated in the next release.
-Afterwards, type `nix flake show` in the root directory of the project to see all the available versions of this book. Then type `nix build .#` to build the edition you want (Haskell, Scala, OCaml, Reason and their printed versions). For example, to build the Scala edition you'll have to type `nix build .#ctfp-scala`.
+**Note from [Bartosz][bartosz github]**: I really appreciate all your
+contributions. You made this book much better than I could have imagined. Thank
+you!
-Upon successful compilation, the PDF file will be placed in the `result` directory inside the root directory `milewski-ctfp-pdf` of the repository.
+Find the [list of contributors on Github][contributors].
-The file `preamble.tex` contains all the configuration and style declarations.
+## Acknowledgements
-Acknowledgements
-----------------
+PDF LaTeX source and the tools to create it are based on the work by [Andres
+Raba][andres raba github]. The book content is taken, with permission, from
+[Bartosz Milewski][bartosz github]'s blogpost series, and adapted to the LaTeX
+format.
-PDF LaTeX source and the tools to create it are based on the work by Andres Raba et al., available here: https://github.com/sarabander/sicp-pdf.
-The book content is taken, with permission, from Bartosz Milewski's blogpost series, and adapted to the LaTeX format.
+The original blog post acknowledgments by Bartosz are consolidated in the
+_Acknowledgments_ page at the end of the book.
-Thanks to the following people for contributing corrections/conversions and misc:
+## License
-* Oleg Rakitskiy
-* Jared Weakly
-* Paolo G. Giarrusso
-* Adi Shavit
-* Mico Loretan
-* Marcello Seri
-* Erwin Maruli Tua Pakpahan
-* Markus Hauck
-* Yevheniy Zelenskyy
-* Ross Kirsling
-* ...and many others!
+The PDF book, `.tex` files, and associated images and figures in directories
+`src/fig` and `src/content` are licensed under [Creative Commons
+Attribution-ShareAlike 4.0 International License][license cc by sa].
-The original blog post acknowledgments by Bartosz are consolidated in the *Acknowledgments* page at the end of the book.
+The script files `scraper.py` and others are licensed under [GNU General Public
+License version 3][license gnu gpl].
-**Note from Bartosz**: I really appreciate all your contributions. You made this book much better than I could have imagined. Thank you!
-
-License
--------
-
-The PDF book, `.tex` files, and associated images and figures in directories `src/fig` and `src/content` are licensed under Creative Commons Attribution-ShareAlike 4.0 International License ([cc by-sa](http://creativecommons.org/licenses/by-sa/4.0/)).
-
-The script files `scraper.py` and others are licensed under GNU General Public License version 3 (for details, see [LICENSE](https://github.com/hmemcpy/milewski-ctfp-pdf/blob/master/LICENSE)).
+[download badge]:
+ https://img.shields.io/badge/Download-latest-green.svg?style=flat-square
+[github actions link]: https://github.com/hmemcpy/milewski-ctfp-pdf/actions
+[github stars]:
+ https://img.shields.io/github/stars/hmemcpy/milewski-ctfp-pdf.svg?style=flat-square
+[github workflow status]:
+ https://img.shields.io/github/actions/workflow/status/hmemcpy/milewski-ctfp-pdf/build.yml?branch=master&style=flat-square
+[github latest release]:
+ https://github.com/hmemcpy/milewski-ctfp-pdf/releases/latest
+[license badge]:
+ https://img.shields.io/badge/License-CC_By_SA-green.svg?style=flat-square
+[ctfp image]:
+ https://user-images.githubusercontent.com/601206/47271389-8eea0900-d581-11e8-8e81-5b932e336336.png
+[bartosz github]: https://github.com/BartoszMilewski
+[nixos wiki flake]: https://nixos.wiki/wiki/Flakes
+[andres raba github]: https://github.com/sarabander
+[contributors]: https://github.com/hmemcpy/milewski-ctfp-pdf/graphs/contributors
+[license cc by sa]: https://spdx.org/licenses/CC-BY-SA-4.0.html
+[license gnu gpl]: https://spdx.org/licenses/GPL-3.0.html
+[blogpost series]:
+ https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/
+[buy regular edition on blurb]:
+ https://www.blurb.com/b/9621951-category-theory-for-programmers-new-edition-hardco
+[buy scala edition on blurb]:
+ https://www.blurb.com/b/9603882-category-theory-for-programmers-scala-edition-pape
+[v1.3.0 github release link]:
+ https://github.com/hmemcpy/milewski-ctfp-pdf/releases/tag/v1.3.0
+[nix website]: https://nixos.org/nix/
+[nix download website]: https://nixos.org/download.html
diff --git a/default.nix b/default.nix
deleted file mode 100644
index eae45ac..0000000
--- a/default.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-let
- rev = "cecfd08d13ddef8a79f277e67b8084bd9afa1586";
- url = "https://github.com/edolstra/flake-compat/archive/${rev}.tar.gz";
- flake = import (fetchTarball url) { src = ./.; };
- inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
-in if inNixShell then flake.shellNix else flake.defaultNix
diff --git a/errata-1.0.0.md b/errata-1.0.0.md
index 81490bb..94438e0 100644
--- a/errata-1.0.0.md
+++ b/errata-1.0.0.md
@@ -2,82 +2,111 @@
### Preface
-* [#155](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/155) - Typo (physicist -> physicists)
+- [#155](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/155) - Typo
+ (physicist -> physicists)
### 6. Simple Algebraic Data Types
-* [#176](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/176) - Typo (statements -> statement)
+- [#176](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/176) - Typo
+ (statements -> statement)
### 8. Functoriality
-* [9a3a5a3](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/9a3a5a386e98ef8f926bccd08f572cc19b1a6367) - added clarifications on bifunctoriality vs. separate functoriality (fix by Bartosz)
+- [9a3a5a3](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/9a3a5a386e98ef8f926bccd08f572cc19b1a6367) -
+ added clarifications on bifunctoriality vs. separate functoriality (fix by
+ Bartosz)
### 9. Function Types
-* [#182](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/182) - Fix typo (chose -> choose)
+- [#182](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/182) - Fix typo
+ (chose -> choose)
### 10. Natural Transformations
-* [#157](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/157) - Adding paragraph indent
+- [#157](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/157) - Adding
+ paragraph indent
### 12. Limits and Colimits
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical error
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical error
### 14. Representable Functors
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical error
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical error
### 18. Adjunctions
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling of "counit"
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling
+ of "counit"
### 19. Free/Forgetful Adjunctions
-* [#156](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/156) - an instance of the category name **Mon** is appearing as **arg**
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling of "isomorphism"
+- [#156](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/156) - an instance of
+ the category name **Mon** is appearing as **arg**
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling
+ of "isomorphism"
### 20. Monads - Programmer's Definition
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix grammatical error
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical error
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix
+ grammatical error
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical error
### 22. Monads Categorically
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical error
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical error
### 23. Comonads
-* [#158](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/158) - fixed incorrect typesetting of `set`
-* [23f522e](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/23f522ec083c2c98f28f15935ff2893ccd1fa76c) - adjusted `Prod`/`Product` names (fix by Bartosz)
+- [#158](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/158) - fixed
+ incorrect typesetting of `set`
+- [23f522e](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/23f522ec083c2c98f28f15935ff2893ccd1fa76c) -
+ adjusted `Prod`/`Product` names (fix by Bartosz)
### 25. Algebras for Monads
-* [#158](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/158) - fixed incorrect typesetting of `set`
-* [#159](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/159) - fixed incorrect typesetting of category terms
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling of "counit" and "morphisms", fix subscript spacing
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical errors
+- [#158](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/158) - fixed
+ incorrect typesetting of `set`
+- [#159](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/159) - fixed
+ incorrect typesetting of category terms
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling
+ of "counit" and "morphisms", fix subscript spacing
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical errors
### 26. Ends and Coends
-* [#159](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/159) - fixed incorrect typesetting of category terms
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling of "coequalizer", fix subscript spacing
+- [#159](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/159) - fixed
+ incorrect typesetting of category terms
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling
+ of "coequalizer", fix subscript spacing
### 27. Kan Extensions
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix subscript spacing
-* [31821e5](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/31821e5ded0dacf059e1fcb985be406e8a495107) - postcomposition -> precomposition (fix by Bartosz)
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix subscript
+ spacing
+- [31821e5](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/31821e5ded0dacf059e1fcb985be406e8a495107) -
+ postcomposition -> precomposition (fix by Bartosz)
### 28. Enriched Categories
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix subscript spacing
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical error
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix subscript
+ spacing
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical error
### 29. Topoi
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical error
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical error
### 30. Lawvere Theories
-* [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling of "coequalizer"
-* [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix grammatical errors and a typesetting error
+- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling
+ of "coequalizer"
+- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix
+ grammatical errors and a typesetting error
diff --git a/errata-1.3.0.md b/errata-1.3.0.md
index 79870e2..7a50b26 100644
--- a/errata-1.3.0.md
+++ b/errata-1.3.0.md
@@ -1,17 +1,27 @@
## A list of typos/mistakes that were fixed after the release of the new edition (1.3.0) (12 August, 2019).
-(see errata for the original edition until 1.3.0 [here](https://github.com/hmemcpy/milewski-ctfp-pdf/blob/master/errata-1.0.0.md))
+
+(see errata for the original edition until 1.3.0
+[here](https://github.com/hmemcpy/milewski-ctfp-pdf/blob/master/errata-1.0.0.md))
### Preface
-* [#278](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/278) - Fixed reference to Saunders Mac Lane's *Categories for the Working Mathematician*. Was previously misreferenced as "*Category Theory* for the Working Mathematician."
+- [#278](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/278) - Fixed
+ reference to Saunders Mac Lane's _Categories for the Working Mathematician_.
+ Was previously misreferenced as "_Category Theory_ for the Working
+ Mathematician."
### 12. Limits and Colimits
-* [#278](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/278) - Fixed formatting of quotation marks around "selecting." Were previously pointing the wrong direction.
+- [#278](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/278) - Fixed
+ formatting of quotation marks around "selecting." Were previously pointing the
+ wrong direction.
+
### 18. Adjunctions
-* [#228](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/228) - Typo (adjuncion -> adjunction)
+- [#228](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/228) - Typo
+ (adjuncion -> adjunction)
### 30. Lawvere Theories
-* [#226](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/226) - fix type in diagram of monads as coends
+- [#226](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/226) - fix type in
+ diagram of monads as coends
diff --git a/errata-scala.md b/errata-scala.md
index 6f34f76..3220ad8 100644
--- a/errata-scala.md
+++ b/errata-scala.md
@@ -2,8 +2,12 @@
### 7. Functors
-* [3d29cd9](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/3d29cd99f34ce1205ed9a68aeae038d9d47c7145) - Added `LazyList` example, supported since Scala 2.13
+- [3d29cd9](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/3d29cd99f34ce1205ed9a68aeae038d9d47c7145) -
+ Added `LazyList` example, supported since Scala 2.13
-* [#210](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/210) - Section 6.4 - `prodToSum` snippet. Explicitly Tupling return type to avoid adapted args warning, which is deprecated behavior
+- [#210](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/210) - Section 6.4 -
+ `prodToSum` snippet. Explicitly Tupling return type to avoid adapted args
+ warning, which is deprecated behavior
-* [#243](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/243) - Section 8.7 - Change bimap to dimap in Profunctor definition
\ No newline at end of file
+- [#243](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/243) - Section 8.7 -
+ Change bimap to dimap in Profunctor definition
diff --git a/flake.lock b/flake.lock
index 3cc7c37..56623c6 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,40 +1,60 @@
{
"nodes": {
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1674771137,
+ "narHash": "sha256-Zpk1GbEsYrqKmuIZkx+f+8pU0qcCYJoSUwNz1Zk+R00=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "7c7a8bce3dffe71203dcd4276504d1cb49dfe05f",
+ "type": "github"
+ },
+ "original": {
+ "id": "flake-parts",
+ "type": "indirect"
+ }
+ },
"nixpkgs": {
"locked": {
- "lastModified": 1645379616,
- "narHash": "sha256-eLzR3MRS9hcNqSWZxP6BP7xiBjgC3/pB5n2Q0lLFe/g=",
+ "lastModified": 1675153841,
+ "narHash": "sha256-EWvU3DLq+4dbJiukfhS7r6sWZyJikgXn6kNl7eHljW8=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "40ef692a55b188b1f5ae3967f3fc7808838c3f1d",
+ "rev": "ea692c2ad1afd6384e171eabef4f0887d2b882d3",
"type": "github"
},
"original": {
"owner": "NixOS",
- "ref": "nixos-21.11",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "dir": "lib",
+ "lastModified": 1672350804,
+ "narHash": "sha256-jo6zkiCabUBn3ObuKXHGqqORUMH27gYDIFFfLq5P4wg=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "677ed08a50931e38382dbef01cba08a8f7eac8f6",
+ "type": "github"
+ },
+ "original": {
+ "dir": "lib",
+ "owner": "NixOS",
+ "ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
- "nixpkgs": "nixpkgs",
- "utils": "utils"
- }
- },
- "utils": {
- "locked": {
- "lastModified": 1644229661,
- "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs"
}
}
},
diff --git a/flake.nix b/flake.nix
index d983e7c..15b555f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,149 +1,203 @@
{
description = "Category Theory for Programmers";
- inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.11";
- inputs.utils.url = "github:numtide/flake-utils";
+ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
- outputs = { self, nixpkgs, utils }: utils.lib.eachDefaultSystem (system: let
- inherit (nixpkgs) lib;
-
- pkgs = nixpkgs.legacyPackages.${system};
-
- ###########################################################################
- # LaTeX Environment
- texliveEnv = pkgs.texlive.combine {
- inherit (pkgs.texlive)
- bookcover
- textpos
- fgruler
- tcolorbox
- fvextra
- framed
- newtx
- nowidow
- emptypage
- wrapfig
- subfigure
- adjustbox
- collectbox
- tikz-cd
- imakeidx
- idxlayout
- titlesec
- subfiles
- lettrine
- upquote
- libertine
- mweights
- fontaxes
- mdframed
- needspace
- xifthen
- ifnextok
- currfile
- noindentafter
- ifmtarg
- scheme-medium
- listings
- minted
- microtype
- babel
- todonotes
- chngcntr
- ifplatform
- xstring
- minifp
- titlecaps
- enumitem
- environ
- trimspaces
- l3packages
- zref
- catchfile
- import
- ;
- };
-
- ###########################################################################
- # Python Environment
-
- # Pin the Python version and its associated package set in a single place.
- python = pkgs.python38;
- pythonPkgs = pkgs.python38Packages;
-
- pygments-style-github = pythonPkgs.buildPythonPackage rec {
- pname = "pygments-style-github";
- version = "0.4";
-
- doCheck = false; # Hopefully someone else has run the tests.
-
- src = pythonPkgs.fetchPypi {
- inherit pname version;
- sha256 = "19zl8l5fyb8z3j8pdlm0zbgag669af66f8gn81ichm3x2hivvjhg";
- };
-
- # Anything depending on this derivation is probably also gonna want
- # pygments to be available.
- propagatedBuildInputs = with pythonPkgs; [ pygments ];
- };
-
- pythonEnv = python.withPackages (p: [ p.pygments pygments-style-github ]);
-
- commonAttrs = {
- nativeBuildInputs = [ texliveEnv pythonEnv pkgs.which ];
- FONTCONFIG_FILE = pkgs.makeFontsConf {
- fontDirectories = with pkgs; [ inconsolata-lgc libertine libertinus ];
- };
- };
-
- mkLatex = variant: edition: let
- maybeVariant = lib.optionalString (variant != null) "-${variant}";
- maybeEdition = lib.optionalString (edition != null) "-${edition}";
- variantStr = if variant == null then "reader" else variant;
- suffix = maybeVariant + maybeEdition;
- basename = "ctfp-${variantStr}${maybeEdition}";
- version = self.shortRev or self.lastModifiedDate;
- in pkgs.stdenv.mkDerivation (commonAttrs // {
- inherit basename version;
-
- name = "ctfp${suffix}-${version}";
- fullname = "ctfp${suffix}";
- src = "${self}/src";
-
- configurePhase = ''
- echo -n "\\newcommand{\\OPTversion}{$version}" > version.tex
- '';
-
- buildPhase = ''
- latexmk -shell-escape -interaction=nonstopmode -halt-on-error \
- -norc -jobname=ctfp -pdflatex="xelatex %O %S" -pdf "$basename.tex"
- '';
-
- installPhase = "install -m 0644 -vD ctfp.pdf \"$out/$fullname.pdf\"";
-
- passthru.packageName = "ctfp${suffix}";
- });
-
- editions = [ null "scala" "ocaml" "reason" ];
- variants = [ null "print" ];
- in {
- # nix build .#ctfp
- # nix build .#ctfp-print
- # nix build .#ctfp-print-ocaml
- # etc etc
- packages = lib.listToAttrs (lib.concatMap (variant: map (edition: rec {
- name = value.packageName;
- value = mkLatex variant edition;
- }) editions) variants);
-
- # nix build .
- defaultPackage = self.packages.${system}.ctfp;
-
- # nix develop .
- devShell = pkgs.mkShell (commonAttrs // {
- nativeBuildInputs = commonAttrs.nativeBuildInputs ++ [
- pkgs.git pkgs.gnumake
+ outputs = inputs @ {
+ self,
+ flake-parts,
+ nixpkgs,
+ }:
+ flake-parts.lib.mkFlake {inherit inputs;} {
+ systems = [
+ "x86_64-linux"
+ "x86_64-darwin"
+ "aarch64-linux"
+ "aarch64-darwin"
];
- });
- });
+
+ perSystem = {
+ config,
+ pkgs,
+ system,
+ ...
+ }: let
+ inherit (nixpkgs) lib;
+
+ pkgs = nixpkgs.legacyPackages.${system};
+
+ ###########################################################################
+ # LaTeX font
+ inconsolata-lgc-latex = pkgs.stdenvNoCC.mkDerivation {
+ name = "inconsolata-lgc-latex";
+ pname = "inconsolata-lgc-latex";
+
+ src = pkgs.inconsolata-lgc;
+
+ dontConfigure = true;
+ sourceRoot = ".";
+
+ installPhase = ''
+ runHook preInstall
+
+ find $src -name '*.ttf' -exec install -m644 -Dt $out/fonts/truetype/public/inconsolata-lgc/ {} \;
+ find $src -name '*.otf' -exec install -m644 -Dt $out/fonts/opentype/public/inconsolata-lgc/ {} \;
+
+ runHook postInstall
+ '';
+
+ tlType = "run";
+ };
+
+ ###########################################################################
+ # LaTeX Environment
+ texliveEnv = pkgs.texlive.combine {
+ inherit
+ (pkgs.texlive)
+ adjustbox
+ alegreya
+ babel
+ bookcover
+ catchfile
+ chngcntr
+ collectbox
+ currfile
+ emptypage
+ enumitem
+ environ
+ fgruler
+ fontaxes
+ framed
+ fvextra
+ idxlayout
+ ifmtarg
+ ifnextok
+ ifplatform
+ imakeidx
+ import
+ inconsolata
+ l3packages
+ lettrine
+ libertine
+ libertinus-fonts
+ listings
+ mdframed
+ microtype
+ minifp
+ minted
+ mweights
+ needspace
+ newtx
+ noindentafter
+ nowidow
+ scheme-medium
+ subfigure
+ subfiles
+ textpos
+ tcolorbox
+ tikz-cd
+ titlecaps
+ titlesec
+ todonotes
+ trimspaces
+ upquote
+ wrapfig
+ xifthen
+ xpatch
+ xstring
+ zref
+ ;
+
+ inconsolata-lgc-latex = {
+ pkgs = [inconsolata-lgc-latex];
+ };
+ };
+
+ ###########################################################################
+ # Python Environment
+
+ # Pin the Python version and its associated package set in a single place.
+ python = pkgs.python311;
+ pythonPkgs = pkgs.python311Packages;
+
+ pygments-style-github = pythonPkgs.buildPythonPackage rec {
+ pname = "pygments-style-github";
+ version = "0.4";
+
+ doCheck = false; # Hopefully someone else has run the tests.
+
+ src = pythonPkgs.fetchPypi {
+ inherit pname version;
+ sha256 = "19zl8l5fyb8z3j8pdlm0zbgag669af66f8gn81ichm3x2hivvjhg";
+ };
+
+ # Anything depending on this derivation is probably also gonna want
+ # pygments to be available.
+ propagatedBuildInputs = with pythonPkgs; [pygments];
+ };
+
+ pythonEnv = python.withPackages (p: [p.pygments pygments-style-github]);
+
+ commonAttrs = {
+ nativeBuildInputs = [texliveEnv pythonEnv pkgs.which];
+ };
+
+ mkLatex = variant: edition: let
+ maybeVariant = lib.optionalString (variant != null) "-${variant}";
+ maybeEdition = lib.optionalString (edition != null) "-${edition}";
+ variantStr =
+ if variant == null
+ then "reader"
+ else variant;
+ suffix = maybeVariant + maybeEdition;
+ basename = "ctfp-${variantStr}${maybeEdition}";
+ version = self.shortRev or self.lastModifiedDate;
+ in
+ pkgs.stdenv.mkDerivation (commonAttrs
+ // {
+ inherit basename version;
+
+ name = "ctfp${suffix}";
+ fullname = "ctfp${suffix}";
+ src = "${self}/src";
+
+ configurePhase = ''
+ substituteInPlace "version.tex" --replace "dev" "${version}"
+ '';
+
+ buildPhase = ''
+ latexmk -file-line-error -shell-escape -logfilewarninglist -interaction=nonstopmode -halt-on-error \
+ -norc -jobname=ctfp -pdflatex="xelatex %O %S" -pdfxe "$basename.tex"
+ '';
+
+ installPhase = "install -m 0644 -vD ctfp.pdf \"$out/$fullname.pdf\"";
+
+ passthru.packageName = "ctfp${suffix}";
+ });
+
+ editions = [null "scala" "ocaml" "reason"];
+ variants = [null "print"];
+ in rec {
+ formatter = pkgs.alejandra;
+
+ packages = lib.listToAttrs (lib.concatMap (variant:
+ map (edition: rec {
+ name = value.packageName;
+ value = mkLatex variant edition;
+ })
+ editions)
+ variants);
+
+ # nix develop .
+ devShells.default = pkgs.mkShellNoCC (commonAttrs
+ // {
+ nativeBuildInputs =
+ commonAttrs.nativeBuildInputs
+ ++ [
+ pkgs.git
+ pkgs.gnumake
+ ];
+ });
+ };
+ };
}
diff --git a/shell.nix b/shell.nix
deleted file mode 100644
index 84fd912..0000000
--- a/shell.nix
+++ /dev/null
@@ -1,12 +0,0 @@
-(import
- (
- let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
- fetchTarball {
- url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
- sha256 = lock.nodes.flake-compat.locked.narHash;
- }
- )
- {
- src = ./.;
- }
-).shellNix
\ No newline at end of file
diff --git a/src/.gitignore b/src/.gitignore
deleted file mode 100644
index 7a85be6..0000000
--- a/src/.gitignore
+++ /dev/null
@@ -1,17 +0,0 @@
-*.aux
-*.cp*
-*.fn
-*.ky
-*.log
-*.pg
-*.toc
-*.tp
-*.vr
-*.vim
-*.idx
-*.ilg
-*.ind
-*.out
-*.swp
-*~
-ctfp.fdb_latexmk
\ No newline at end of file
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 6bed4d1..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,85 +0,0 @@
-# Igal Tabachnik, 2007.
-# Based on work by Andres Raba et al., 2013-2015.
-
-.PHONY: default all clean out-dir version.tex scala ocaml reason
-
-DIR := $(shell pwd)
-GIT_VER := $(shell git describe --tags --always --long | tr -d '\n')
-OUTPUT_DIR := ../out
-
-OUTPUT = category-theory-for-programmers
-
-# Default top-level LaTeX to generate
-DEFAULTTOPTEX = ctfp-reader.tex ctfp-print.tex
-
-SCALATEXFILES = ctfp-reader-scala.tex ctfp-print-scala.tex # todo make this a macro
-
-OCAMLTEXFILES = ctfp-reader-ocaml.tex ctfp-print-ocaml.tex # todo make this a macro
-
-REASONTEXFILES = ctfp-reader-reason.tex ctfp-print-reason.tex # todo make this a macro
-
-# Top-level LaTeX files from which CTFP book can be generated
-TOPTEXFILES = version.tex $(DEFAULTTOPTEX) $(SCALATEXFILES) $(OCAMLTEXFILES) $(REASONTEXFILES)
-
-# Default PDF file to make
-DEFAULTPDF:=$(DEFAULTTOPTEX:.tex=.pdf)
-
-# Scala PDF file to make
-SCALAPDF:=$(SCALATEXFILES:.tex=.pdf)
-
-# OCaml PDF file to make
-OCAMLPDF:=$(OCAMLTEXFILES:.tex=.pdf)
-
-# ReasonML PDF file to make
-REASONPDF:=$(REASONTEXFILES:.tex=.pdf)
-
-# Other PDF files for the CTFP book
-TOPPDFFILES:=$(TOPTEXFILES:.tex=.pdf)
-
-# Configuration files
-OPTFILES = opt-print-ustrade.tex \
- opt-reader-10in.tex \
- opt-scala.tex
-
-# All the LaTeX files for the CTFP book in order of dependency
-TEXFILES = $(TOPTEXFILES) $(SCALATEXFILES) $(OCAMLTEXFILES) $(REASONTEXFILES) $(OPTFILES)
-
-default: suffix=''
-default: out-dir $(DEFAULTPDF) # todo cover
-
-all: clean default scala ocaml reason
-
-scala: suffix='-scala'
-scala: clean out-dir version.tex $(SCALAPDF)
-
-ocaml: suffix='-ocaml'
-ocaml: clean out-dir version.tex $(OCAMLPDF)
-
-reason: suffix='-reason'
-reason: clean out-dir version.tex $(REASONPDF)
-
-# Main targets
-$(TOPPDFFILES) : %.pdf : %.tex $(TEXFILES)
- if which latexmk > /dev/null 2>&1 ;\
- then \
- latexmk -shell-escape -interaction=nonstopmode -halt-on-error -norc -jobname=ctfp -pdflatex="xelatex %O %S" -pdf $< ;\
- mv ctfp.pdf $(OUTPUT_DIR)/$(subst ctfp,$(OUTPUT),$(subst ctfp-reader,$(OUTPUT),$*)).pdf ;\
- else @printf "Error: unable to find latexmk. Is it installed?\n" ;\
- fi
-
-version.tex:
- @printf '\\newcommand{\\OPTversion}{' > version.tex
- @printf $(GIT_VER) >> version.tex
- @printf '}' >> version.tex
-
-out-dir:
- @printf 'Creating output directory: $(OUTPUT_DIR)\n'
- mkdir -p $(OUTPUT_DIR)
-
-clean:
- rm -f *~ *.aux {ctfp-*}.{out,log,pdf,dvi,fls,fdb_latexmk,aux,brf,bbl,idx,ilg,ind,toc,sed}
- if which latexmk > /dev/null 2>&1 ; then latexmk -CA; fi
- rm -rf ../out
-
-clean-minted:
- rm -rf _minted-*
diff --git a/src/category.tex b/src/category.tex
index 25051b2..791c489 100644
--- a/src/category.tex
+++ b/src/category.tex
@@ -1,11 +1,11 @@
\newcommand{\cat}{%
-\symbf%
+ \symbf%
}
\newcommand{\idarrow}[1][]{%
-\mathbf{id}_{#1}%
+ \mathbf{id}_{#1}%
}
\newcommand{\Lim}[1][]{%
-\mathbf{Lim}{#1}%
+ \mathbf{Lim}{#1}%
}
\newcommand{\Set}{\cat{Set}}
\newcommand{\Rel}{\cat{Rel}}
diff --git a/src/colophon.tex b/src/colophon.tex
index f0d7fdf..89b4981 100644
--- a/src/colophon.tex
+++ b/src/colophon.tex
@@ -10,6 +10,6 @@ typeface is Alegreya, designed by Juan Pablo del Peral.
Original book layout design and typography are done by Andres Raba. Syntax highlighting is using ``GitHub'' style for Pygments by
\urlref{https://github.com/hugomaiavieira/pygments-style-github}{Hugo Maia Vieira}.
\ifdefined\OPTCustomLanguage{%
- \input{content/\OPTCustomLanguage/colophon}
-}
+ \input{content/\OPTCustomLanguage/colophon}
+ }
\fi
\ No newline at end of file
diff --git a/src/content/0.0/preface.tex b/src/content/0.0/preface.tex
index 5755e9d..8a32a64 100644
--- a/src/content/0.0/preface.tex
+++ b/src/content/0.0/preface.tex
@@ -1,20 +1,20 @@
% !TEX root = ../../ctfp-print.tex
\begin{quote}
-For some time now I've been floating the idea of writing a book about
-category theory that would be targeted at programmers. Mind you, not
-computer scientists but programmers --- engineers rather than
-scientists. I know this sounds crazy and I am properly scared. I can't
-deny that there is a huge gap between science and engineering because I
-have worked on both sides of the divide. But I've always felt a very
-strong compulsion to explain things. I have tremendous admiration for
-Richard Feynman who was the master of simple explanations. I know I'm no
-Feynman, but I will try my best. I'm starting by publishing this preface
---- which is supposed to motivate the reader to learn category theory
---- in hopes of starting a discussion and soliciting feedback.\footnote{
-You may also watch me teach this material to a live audience, at
-\href{https://goo.gl/GT2UWU}{https://goo.gl/GT2UWU} (or search
-``bartosz milewski category theory'' on YouTube.)}
+ For some time now I've been floating the idea of writing a book about
+ category theory that would be targeted at programmers. Mind you, not
+ computer scientists but programmers --- engineers rather than
+ scientists. I know this sounds crazy and I am properly scared. I can't
+ deny that there is a huge gap between science and engineering because I
+ have worked on both sides of the divide. But I've always felt a very
+ strong compulsion to explain things. I have tremendous admiration for
+ Richard Feynman who was the master of simple explanations. I know I'm no
+ Feynman, but I will try my best. I'm starting by publishing this preface
+ --- which is supposed to motivate the reader to learn category theory
+ --- in hopes of starting a discussion and soliciting feedback.\footnote{
+ You may also watch me teach this material to a live audience, at
+ \href{https://goo.gl/GT2UWU}{https://goo.gl/GT2UWU} (or search
+ ``bartosz milewski category theory'' on YouTube.)}
\end{quote}
\lettrine[lhang=0.17]{I}{will attempt}, in the space of a few paragraphs,
@@ -64,7 +64,7 @@ Of course when using hand-waving arguments you run the risk of saying
something blatantly wrong, so I will try to make sure that there is
solid mathematical theory behind informal arguments in this book. I do
have a worn-out copy of Saunders Mac Lane's \emph{Categories for
-the Working Mathematician} on my nightstand.
+ the Working Mathematician} on my nightstand.
Since this is category theory \emph{for programmers} I will illustrate
all major concepts using computer code. You are probably aware that
@@ -102,8 +102,8 @@ the position of a frog that must decide if it should continue swimming
in increasingly hot water, or start looking for some alternatives.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/img_1299.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/img_1299.jpg}
\end{figure}
\noindent
@@ -136,7 +136,7 @@ us to rethink the foundations of programming. Just like the builders of
Europe's great gothic cathedrals we've been honing our craft to the
limits of material and structure. There is an unfinished gothic
\urlref{http://en.wikipedia.org/wiki/Beauvais_Cathedral}{cathedral in
-Beauvais}, France, that stands witness to this deeply human struggle
+ Beauvais}, France, that stands witness to this deeply human struggle
with limitations. It was intended to beat all previous records of height
and lightness, but it suffered a series of collapses. Ad hoc measures
like iron rods and wooden supports keep it from disintegrating, but
@@ -151,7 +151,7 @@ all this based on very flimsy theoretical foundations. We have to fix
those foundations if we want to move forward.
\begin{figure}
-\centering
-\includegraphics[totalheight=0.5\textheight]{images/beauvais_interior_supports.jpg}
-\caption{Ad hoc measures preventing the Beauvais cathedral from collapsing.}
+ \centering
+ \includegraphics[totalheight=0.5\textheight]{images/beauvais_interior_supports.jpg}
+ \caption{Ad hoc measures preventing the Beauvais cathedral from collapsing.}
\end{figure}
diff --git a/src/content/1.1/category-the-essence-of-composition.tex b/src/content/1.1/category-the-essence-of-composition.tex
index c90c709..ef0e521 100644
--- a/src/content/1.1/category-the-essence-of-composition.tex
+++ b/src/content/1.1/category-the-essence-of-composition.tex
@@ -12,11 +12,11 @@ object $B$ to object $C$, then there must be an arrow --- their composition
--- that goes from $A$ to $C$.
\begin{figure}
-\centering
-\includegraphics[width=0.8\textwidth]{images/img_1330.jpg}
-\caption{In a category, if there is an arrow going from $A$ to $B$ and an arrow going from $B$ to $C$
-then there must also be a direct arrow from $A$ to $C$ that is their composition. This diagram is not a full
-category because it’s missing identity morphisms (see later).}
+ \centering
+ \includegraphics[width=0.8\textwidth]{images/img_1330.jpg}
+ \caption{In a category, if there is an arrow going from $A$ to $B$ and an arrow going from $B$ to $C$
+ then there must also be a direct arrow from $A$ to $C$ that is their composition. This diagram is not a full
+ category because it’s missing identity morphisms (see later).}
\end{figure}
\section{Arrows as Functions}
@@ -100,30 +100,30 @@ There are two extremely important properties that the composition in any
category must satisfy.
\begin{enumerate}
-\item
-Composition is associative. If you have three morphisms, $f$, $g$, and $h$,
-that can be composed (that is, their objects match end-to-end), you
-don't need parentheses to compose them. In math notation this is
-expressed as:
-\[h \circ (g \circ f) = (h \circ g) \circ f = h \circ g \circ f\]
-In (pseudo) Haskell:
+ \item
+ Composition is associative. If you have three morphisms, $f$, $g$, and $h$,
+ that can be composed (that is, their objects match end-to-end), you
+ don't need parentheses to compose them. In math notation this is
+ expressed as:
+ \[h \circ (g \circ f) = (h \circ g) \circ f = h \circ g \circ f\]
+ In (pseudo) Haskell:
-\src{snippet04}[b]
-(I said ``pseudo,'' because equality is not defined for functions.)
+ \src{snippet04}[b]
+ (I said ``pseudo,'' because equality is not defined for functions.)
-Associativity is pretty obvious when dealing with functions, but it may
-be not as obvious in other categories.
+ Associativity is pretty obvious when dealing with functions, but it may
+ be not as obvious in other categories.
-\item
-For every object $A$ there is an arrow which is a unit of composition.
-This arrow loops from the object to itself. Being a unit of composition
-means that, when composed with any arrow that either starts at $A$ or ends
-at $A$, respectively, it gives back the same arrow. The unit arrow for
-object A is called $\idarrow[A]$ (\newterm{identity} on $A$). In math
-notation, if $f$ goes from $A$ to $B$ then
-\[f \circ \idarrow[A] = f\]
-and
-\[\idarrow[B] \circ f = f\]
+ \item
+ For every object $A$ there is an arrow which is a unit of composition.
+ This arrow loops from the object to itself. Being a unit of composition
+ means that, when composed with any arrow that either starts at $A$ or ends
+ at $A$, respectively, it gives back the same arrow. The unit arrow for
+ object A is called $\idarrow[A]$ (\newterm{identity} on $A$). In math
+ notation, if $f$ goes from $A$ to $B$ then
+ \[f \circ \idarrow[A] = f\]
+ and
+ \[\idarrow[B] \circ f = f\]
\end{enumerate}
When dealing with functions, the identity arrow is implemented as the
identity function that just returns back its argument. The
@@ -209,7 +209,7 @@ imposed on us by computers. It reflects the limitations of the human
mind. Our brains can only deal with a small number of concepts at a
time. One of the most cited papers in psychology,
\urlref{http://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two}{The
-Magical Number Seven, Plus or Minus Two}, postulated that we can only
+ Magical Number Seven, Plus or Minus Two}, postulated that we can only
keep $7 \pm 2$ ``chunks'' of information in our minds. The details of our
understanding of the human short-term memory might be changing, but we
know for sure that it's limited. The bottom line is that we are unable
@@ -251,23 +251,23 @@ advantages of your programming paradigm.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Implement, as best as you can, the identity function in your favorite
- language (or the second favorite, if your favorite language happens to
- be Haskell).
-\item
- Implement the composition function in your favorite language. It takes
- two functions as arguments and returns a function that is their
- composition.
-\item
- Write a program that tries to test that your composition function
- respects identity.
-\item
- Is the world-wide web a category in any sense? Are links morphisms?
-\item
- Is Facebook a category, with people as objects and friendships as
- morphisms?
-\item
- When is a directed graph a category?
+ \tightlist
+ \item
+ Implement, as best as you can, the identity function in your favorite
+ language (or the second favorite, if your favorite language happens to
+ be Haskell).
+ \item
+ Implement the composition function in your favorite language. It takes
+ two functions as arguments and returns a function that is their
+ composition.
+ \item
+ Write a program that tries to test that your composition function
+ respects identity.
+ \item
+ Is the world-wide web a category in any sense? Are links morphisms?
+ \item
+ Is Facebook a category, with people as objects and friendships as
+ morphisms?
+ \item
+ When is a directed graph a category?
\end{enumerate}
diff --git a/src/content/1.10/natural-transformations.tex b/src/content/1.10/natural-transformations.tex
index 85f5b2d..a614e82 100644
--- a/src/content/1.10/natural-transformations.tex
+++ b/src/content/1.10/natural-transformations.tex
@@ -10,7 +10,7 @@ category inside another. The source category serves as a model, a
blueprint, for some structure that's part of the target category.
\begin{figure}[H]
-\centering\includegraphics[width=0.4\textwidth]{images/1_functors.jpg}
+ \centering\includegraphics[width=0.4\textwidth]{images/1_functors.jpg}
\end{figure}
\noindent
@@ -29,8 +29,8 @@ A mapping of functors should therefore map $F a$ to
$G a$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/2_natcomp.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/2_natcomp.jpg}
\end{figure}
\noindent
@@ -64,26 +64,26 @@ and $b$ in $\cat{C}$. It's mapped to two morphisms, $F\ f$
and $G f$ in $\cat{D}$:
\begin{gather*}
-F f \Colon F a \to F b \\
-G f \Colon G a \to G b
+ F f \Colon F a \to F b \\
+ G f \Colon G a \to G b
\end{gather*}
The natural transformation $\alpha$ provides two additional morphisms
that complete the diagram in \emph{D}:
\begin{gather*}
-\alpha_a \Colon F a \to G a \\
-\alpha_b \Colon F b \to G b
+ \alpha_a \Colon F a \to G a \\
+ \alpha_b \Colon F b \to G b
\end{gather*}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/3_naturality.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/3_naturality.jpg}
\end{figure}
\noindent
Now we have two ways of getting from $F a$ to $G b$. To
make sure that they are equal, we must impose the \newterm{naturality
-condition} that holds for any $f$:
+ condition} that holds for any $f$:
\[G f \circ \alpha_a = \alpha_b \circ F f\]
The naturality condition is a pretty stringent requirement. For
@@ -94,8 +94,8 @@ $\alpha_a$ along $f$:
\[\alpha_b = (G f) \circ \alpha_a \circ (F f)^{-1}\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/4_transport.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/4_transport.jpg}
\end{figure}
\noindent
@@ -114,8 +114,8 @@ also say that it maps morphisms to commuting squares --- there is one
commuting naturality square in $\cat{D}$ for every morphism in $\cat{C}$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/naturality.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/naturality.jpg}
\end{figure}
\noindent
@@ -215,9 +215,9 @@ limitations on the implementation --- one formula for all types. These
limitations translate into equational theorems about such functions. In
the case of functions that transform functors, free theorems are the
naturality conditions.\footnote{
-You may read more about free theorems in my
-blog \href{https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/}{``Parametricity:
-Money for Nothing and Theorems for Free}.''}
+ You may read more about free theorems in my
+ blog \href{https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/}{``Parametricity:
+ Money for Nothing and Theorems for Free}.''}
One way of thinking about functors in Haskell that I mentioned earlier
is to consider them generalized containers. We can continue this analogy
@@ -405,8 +405,8 @@ $\beta \cdot \alpha$ --- the composition of two natural transformations $\beta$
\[(\beta \cdot \alpha)_a = \beta_a \circ \alpha_a\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/5_vertical.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/5_vertical.jpg}
\end{figure}
\noindent
@@ -415,8 +415,8 @@ composition is indeed a natural transformation from F to H:
\[H f \circ (\beta \cdot \alpha)_a = (\beta \cdot \alpha)_b \circ F f\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/6_verticalnaturality.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/6_verticalnaturality.jpg}
\end{figure}
\noindent
@@ -438,8 +438,8 @@ composition is important in defining the functor category. I'll explain
horizontal composition shortly.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/6a_vertical.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/6a_vertical.jpg}
\end{figure}
\noindent
@@ -458,8 +458,8 @@ functors. A Hom-set in $\Cat$ is a set of functors. For instance
$\cat{Cat(C, D)}$ is a set of functors between two categories $\cat{C}$ and $\cat{D}$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/7_cathomset.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/7_cathomset.jpg}
\end{figure}
\noindent
@@ -506,18 +506,18 @@ morphisms between morphisms.
In the case of $\Cat$ seen as a $\cat{2}$-category we have:
\begin{itemize}
-\tightlist
-\item
- Objects: (Small) categories
-\item
- 1-morphisms: Functors between categories
-\item
- 2-morphisms: Natural transformations between functors.
+ \tightlist
+ \item
+ Objects: (Small) categories
+ \item
+ 1-morphisms: Functors between categories
+ \item
+ 2-morphisms: Natural transformations between functors.
\end{itemize}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/8_cat-2-cat.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/8_cat-2-cat.jpg}
\end{figure}
\noindent
@@ -534,21 +534,21 @@ do they interact with each other?
Let's pick two functors, or 1-morphisms, in $\Cat$:
\begin{gather*}
-F \Colon \cat{C} \to \cat{D} \\
-G \Colon \cat{D} \to \cat{E}
+ F \Colon \cat{C} \to \cat{D} \\
+ G \Colon \cat{D} \to \cat{E}
\end{gather*}
and their composition:
\[G \circ F \Colon \cat{C} \to \cat{E}\]
Suppose we have two natural transformations, $\alpha$ and $\beta$, that act,
respectively, on functors $F$ and $G$:
\begin{gather*}
-\alpha \Colon F \to F' \\
-\beta \Colon G \to G'
+ \alpha \Colon F \to F' \\
+ \beta \Colon G \to G'
\end{gather*}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/10_horizontal.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/10_horizontal.jpg}
\end{figure}
\noindent
@@ -563,8 +563,8 @@ Having $\alpha$ and $\beta$ at our disposal, can we define a natural transformat
from $G \circ F$ to $G' \circ F'$? Let me sketch the construction.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/9_horizontal.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/9_horizontal.jpg}
\end{figure}
\noindent
@@ -577,14 +577,14 @@ objects: $G (F a)$, $G'(F a)$, $G (F'a)$, $G'(F'a)$.
We also have four morphisms forming a square. Two of these morphisms are
the components of the natural transformation $\beta$:
\begin{gather*}
-\beta_{F a} \Colon G (F a) \to G'(F a) \\
-\beta_{F'a} \Colon G (F'a) \to G'(F'a)
+ \beta_{F a} \Colon G (F a) \to G'(F a) \\
+ \beta_{F'a} \Colon G (F'a) \to G'(F'a)
\end{gather*}
The other two are the images of $\alpha_a$ under the two
functors (functors map morphisms):
\begin{gather*}
-G \alpha_a \Colon G (F a) \to G (F'a) \\
-G'\alpha_a \Colon G'(F a) \to G'(F'a)
+ G \alpha_a \Colon G (F a) \to G (F'a) \\
+ G'\alpha_a \Colon G'(F a) \to G'(F'a)
\end{gather*}
That's a lot of morphisms. Our goal is to find a morphism that goes from
$G (F a)$ to $G'(F'a)$, a candidate for the
@@ -592,8 +592,8 @@ component of a natural transformation connecting the two functors $G \circ F$
and $G' \circ F'$. In fact there's not one but two paths we can take from
$G (F a)$ to $G'(F'a)$:
\begin{gather*}
-G'\alpha_a \circ \beta_{F a} \\
-\beta_{F'a} \circ G \alpha_a
+ G'\alpha_a \circ \beta_{F a} \\
+ \beta_{F'a} \circ G \alpha_a
\end{gather*}
Luckily for us, they are equal, because the square we have formed turns
out to be the naturality square for $\beta$.
@@ -620,8 +620,8 @@ categories, the ones that are connected by the functors it transforms.
We can think of it as connecting these two categories.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/sideways.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/sideways.jpg}
\end{figure}
\noindent
@@ -689,36 +689,36 @@ natural transformation is a special type of polymorphic function.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Define a natural transformation from the \code{Maybe} functor to the
- list functor. Prove the naturality condition for it.
-\item
- Define at least two different natural transformations between
- \code{Reader ()} and the list functor. How many different lists of
- \code{()} are there?
-\item
- Continue the previous exercise with \code{Reader Bool} and
- \code{Maybe}.
-\item
- Show that horizontal composition of natural transformation satisfies
- the naturality condition (hint: use components). It's a good exercise
- in diagram chasing.
-\item
- Write a short essay about how you may enjoy writing down the evident
- diagrams needed to prove the interchange law.
-\item
- Create a few test cases for the opposite naturality condition of
- transformations between different \code{Op} functors. Here's one
- choice:
+ \tightlist
+ \item
+ Define a natural transformation from the \code{Maybe} functor to the
+ list functor. Prove the naturality condition for it.
+ \item
+ Define at least two different natural transformations between
+ \code{Reader ()} and the list functor. How many different lists of
+ \code{()} are there?
+ \item
+ Continue the previous exercise with \code{Reader Bool} and
+ \code{Maybe}.
+ \item
+ Show that horizontal composition of natural transformation satisfies
+ the naturality condition (hint: use components). It's a good exercise
+ in diagram chasing.
+ \item
+ Write a short essay about how you may enjoy writing down the evident
+ diagrams needed to prove the interchange law.
+ \item
+ Create a few test cases for the opposite naturality condition of
+ transformations between different \code{Op} functors. Here's one
+ choice:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
op :: Op Bool Int
op = Op (\x -> x > 0)
\end{snip}
-and
+ and
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
f :: String -> Int
f x = read x
\end{snip}
diff --git a/src/content/1.2/types-and-functions.tex b/src/content/1.2/types-and-functions.tex
index b286b60..dc0b21a 100644
--- a/src/content/1.2/types-and-functions.tex
+++ b/src/content/1.2/types-and-functions.tex
@@ -12,8 +12,8 @@ happily hitting random keys, producing programs, compiling, and running
them.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/img_1329.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/img_1329.jpg}
\end{figure}
\noindent
@@ -71,7 +71,7 @@ optional. Programmers tend to use them anyway, because they can tell a
lot about the semantics of code, and they make compilation errors easier
to understand. It's a common practice in Haskell to start a project by
designing the types. \sloppy{Later, type annotations drive the implementation
-and become compiler-enforced comments.}
+ and become compiler-enforced comments.}
Strong static typing is often used as an excuse for not testing the
code. You may sometimes hear Haskell programmers saying, ``If it
@@ -178,8 +178,8 @@ complications, so at this point I will use my butcher's knife and
terminate this line of reasoning. From the pragmatic point of view, it's
okay to ignore non-terminating functions and bottoms, and treat
$\Hask$ as bona fide $\Set$.\footnote{Nils Anders Danielsson,
-John Hughes, Patrik Jansson, Jeremy Gibbons, \href{http://www.cs.ox.ac.uk/jeremy.gibbons/publications/fast+loose.pdf}{
-Fast and Loose Reasoning is Morally Correct}. This paper provides justification for ignoring bottoms in most contexts.}
+ John Hughes, Patrik Jansson, Jeremy Gibbons, \href{http://www.cs.ox.ac.uk/jeremy.gibbons/publications/fast+loose.pdf}{
+ Fast and Loose Reasoning is Morally Correct}. This paper provides justification for ignoring bottoms in most contexts.}
\section{Why Do We Need a Mathematical Model?}
@@ -292,7 +292,7 @@ cannot be easily modelled as a mathematical function.
In programming languages, functions that always produce the same result
given the same input and have no side effects are called \newterm{pure
-functions}. In a pure functional language like Haskell all functions are
+ functions}. In a pure functional language like Haskell all functions are
pure. Because of that, it's easier to give these languages denotational
semantics and model them using category theory. As for other languages,
it's always possible to restrict yourself to a pure subset, or reason
@@ -433,61 +433,61 @@ have the form \code{ctype::is(alpha, c)}, \code{ctype::is(digit, c)}, etc.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Define a higher-order function (or a function object) \code{memoize}
- in your favorite language. This function takes a pure function
- \code{f} as an argument and returns a function that behaves almost
- exactly like \code{f}, except that it only calls the original
- function once for every argument, stores the result internally, and
- subsequently returns this stored result every time it's called with
- the same argument. You can tell the memoized function from the
- original by watching its performance. For instance, try to memoize a
- function that takes a long time to evaluate. You'll have to wait for
- the result the first time you call it, but on subsequent calls, with
- the same argument, you should get the result immediately.
-\item
- Try to memoize a function from your standard library that you normally
- use to produce random numbers. Does it work?
-\item
- Most random number generators can be initialized with a seed.
- Implement a function that takes a seed, calls the random number
- generator with that seed, and returns the result. Memoize that
- function. Does it work?
-\item
- Which of these C++ functions are pure? Try to memoize them and observe
- what happens when you call them multiple times: memoized and not.
-
- \begin{enumerate}
\tightlist
\item
- The factorial function from the example in the text.
+ Define a higher-order function (or a function object) \code{memoize}
+ in your favorite language. This function takes a pure function
+ \code{f} as an argument and returns a function that behaves almost
+ exactly like \code{f}, except that it only calls the original
+ function once for every argument, stores the result internally, and
+ subsequently returns this stored result every time it's called with
+ the same argument. You can tell the memoized function from the
+ original by watching its performance. For instance, try to memoize a
+ function that takes a long time to evaluate. You'll have to wait for
+ the result the first time you call it, but on subsequent calls, with
+ the same argument, you should get the result immediately.
\item
-\begin{minted}{cpp}
+ Try to memoize a function from your standard library that you normally
+ use to produce random numbers. Does it work?
+ \item
+ Most random number generators can be initialized with a seed.
+ Implement a function that takes a seed, calls the random number
+ generator with that seed, and returns the result. Memoize that
+ function. Does it work?
+ \item
+ Which of these C++ functions are pure? Try to memoize them and observe
+ what happens when you call them multiple times: memoized and not.
+
+ \begin{enumerate}
+ \tightlist
+ \item
+ The factorial function from the example in the text.
+ \item
+ \begin{minted}{cpp}
std::getchar()
\end{minted}
- \item
-\begin{minted}{cpp}
+ \item
+ \begin{minted}{cpp}
bool f() {
std::cout << "Hello!" << std::endl;
return true;
}
\end{minted}
- \item
-\begin{minted}{cpp}
+ \item
+ \begin{minted}{cpp}
int f(int x) {
static int y = 0;
y += x;
return y;
}
\end{minted}
- \end{enumerate}
-\item
- How many different functions are there from \code{Bool} to
- \code{Bool}? Can you implement them all?
-\item
- Draw a picture of a category whose only objects are the types
- \code{Void}, \code{()} (unit), and \code{Bool}; with arrows
- corresponding to all possible functions between these types. Label the
- arrows with the names of the functions.
+ \end{enumerate}
+ \item
+ How many different functions are there from \code{Bool} to
+ \code{Bool}? Can you implement them all?
+ \item
+ Draw a picture of a category whose only objects are the types
+ \code{Void}, \code{()} (unit), and \code{Bool}; with arrows
+ corresponding to all possible functions between these types. Label the
+ arrows with the names of the functions.
\end{enumerate}
diff --git a/src/content/1.3/categories-great-and-small.tex b/src/content/1.3/categories-great-and-small.tex
index cf064f2..2242dd1 100644
--- a/src/content/1.3/categories-great-and-small.tex
+++ b/src/content/1.3/categories-great-and-small.tex
@@ -95,7 +95,7 @@ The neutral element is zero, because:
and
\[a + 0 = a\]
The second equation is redundant, because addition is commutative $(a + b
-= b + a)$, but commutativity is not part of the definition of a monoid.
+ = b + a)$, but commutativity is not part of the definition of a monoid.
For instance, string concatenation is not commutative and yet it forms a
monoid. The neutral element for string concatenation, by the way, is an
empty string, which can be attached to either side of a string without
@@ -260,8 +260,8 @@ monoid can be described as a single object category with a set of
morphisms that follow appropriate rules of composition.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/monoid.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/monoid.jpg}
\end{figure}
\noindent
@@ -289,9 +289,9 @@ this product. So we can always recover a set monoid from a category
monoid. For all intents and purposes they are one and the same.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/monoidhomset.jpg}
-\caption{Monoid hom-set seen as morphisms and as points in a set.}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/monoidhomset.jpg}
+ \caption{Monoid hom-set seen as morphisms and as points in a set.}
\end{figure}
\noindent
@@ -310,43 +310,43 @@ set $\cat{M}(m, m)$.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Generate a free category from:
-
- \begin{enumerate}
\tightlist
\item
- A graph with one node and no edges
- \item
- A graph with one node and one (directed) edge (hint: this edge can
- be composed with itself)
- \item
- A graph with two nodes and a single arrow between them
- \item
- A graph with a single node and 26 arrows marked with the letters of
- the alphabet: a, b, c \ldots{} z.
- \end{enumerate}
-\item
- What kind of order is this?
+ Generate a free category from:
- \begin{enumerate}
- \tightlist
+ \begin{enumerate}
+ \tightlist
+ \item
+ A graph with one node and no edges
+ \item
+ A graph with one node and one (directed) edge (hint: this edge can
+ be composed with itself)
+ \item
+ A graph with two nodes and a single arrow between them
+ \item
+ A graph with a single node and 26 arrows marked with the letters of
+ the alphabet: a, b, c \ldots{} z.
+ \end{enumerate}
\item
- A set of sets with the inclusion relation: $A$ is included in $B$ if
- every element of $A$ is also an element of $B$.
+ What kind of order is this?
+
+ \begin{enumerate}
+ \tightlist
+ \item
+ A set of sets with the inclusion relation: $A$ is included in $B$ if
+ every element of $A$ is also an element of $B$.
+ \item
+ C++ types with the following subtyping relation: \code{T1} is a subtype of
+ \code{T2} if a pointer to \code{T1} can be passed to a function that expects a
+ pointer to \code{T2} without triggering a compilation error.
+ \end{enumerate}
\item
- C++ types with the following subtyping relation: \code{T1} is a subtype of
- \code{T2} if a pointer to \code{T1} can be passed to a function that expects a
- pointer to \code{T2} without triggering a compilation error.
- \end{enumerate}
-\item
- Considering that \code{Bool} is a set of two values \code{True} and \code{False}, show that
- it forms two (set-theoretical) monoids with respect to, respectively,
- operator \code{\&\&} (AND) and \code{||} (OR).
-\item
- Represent the \code{Bool} monoid with the AND operator as a category: List
- the morphisms and their rules of composition.
-\item
- Represent addition modulo 3 as a monoid category.
+ Considering that \code{Bool} is a set of two values \code{True} and \code{False}, show that
+ it forms two (set-theoretical) monoids with respect to, respectively,
+ operator \code{\&\&} (AND) and \code{||} (OR).
+ \item
+ Represent the \code{Bool} monoid with the AND operator as a category: List
+ the morphisms and their rules of composition.
+ \item
+ Represent addition modulo 3 as a monoid category.
\end{enumerate}
\ No newline at end of file
diff --git a/src/content/1.4/kleisli-categories.tex b/src/content/1.4/kleisli-categories.tex
index c8243ca..76707e3 100644
--- a/src/content/1.4/kleisli-categories.tex
+++ b/src/content/1.4/kleisli-categories.tex
@@ -110,8 +110,8 @@ that they piggyback a message string on top of their regular return
values.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/piggyback.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/piggyback.jpg}
\end{figure}
\noindent
We will ``embellish'' the return values of these functions. Let's do it
@@ -156,7 +156,7 @@ Now imagine a whole program written in this style. It's a nightmare of
repetitive, error-prone code. But we are programmers. We know how to
deal with repetitive code: we abstract it! This is, however, not your
run of the mill abstraction --- we have to abstract \newterm{function
-composition} itself. But composition is the essence of category theory,
+ composition} itself. But composition is the essence of category theory,
so before we write more code, let's analyze the problem from the
categorical point of view.
@@ -205,18 +205,18 @@ So here's the recipe for the composition of two morphisms in this new
category we are constructing:
\begin{enumerate}
-\tightlist
-\item
- Execute the embellished function corresponding to the first morphism
-\item
- Extract the first component of the result pair and pass it to the
- embellished function corresponding to the second morphism
-\item
- Concatenate the second component (the string) of the first result
- and the second component (the string) of the second result
-\item
- Return a new pair combining the first component of the final result
- with the concatenated string.
+ \tightlist
+ \item
+ Execute the embellished function corresponding to the first morphism
+ \item
+ Extract the first component of the result pair and pass it to the
+ embellished function corresponding to the second morphism
+ \item
+ Concatenate the second component (the string) of the first result
+ and the second component (the string) of the second result
+ \item
+ Return a new pair combining the first component of the final result
+ with the concatenated string.
\end{enumerate}
If we want to abstract this composition as a higher order function in
@@ -431,16 +431,16 @@ optional safe_root(double x) {
Here's the challenge:
\begin{enumerate}
-\tightlist
-\item
- Construct the Kleisli category for partial functions (define
- composition and identity).
-\item
- Implement the embellished function \code{safe\_reciprocal} that
- returns a valid reciprocal of its argument, if it's different from
- zero.
-\item
- Compose the functions \code{safe\_root} and \code{safe\_reciprocal} to implement
- \code{safe\_root\_reciprocal} that calculates \code{sqrt(1/x)}
- whenever possible.
+ \tightlist
+ \item
+ Construct the Kleisli category for partial functions (define
+ composition and identity).
+ \item
+ Implement the embellished function \code{safe\_reciprocal} that
+ returns a valid reciprocal of its argument, if it's different from
+ zero.
+ \item
+ Compose the functions \code{safe\_root} and \code{safe\_reciprocal} to implement
+ \code{safe\_root\_reciprocal} that calculates \code{sqrt(1/x)}
+ whenever possible.
\end{enumerate}
diff --git a/src/content/1.5/products-and-coproducts.tex b/src/content/1.5/products-and-coproducts.tex
index ca7589d..a3b418c 100644
--- a/src/content/1.5/products-and-coproducts.tex
+++ b/src/content/1.5/products-and-coproducts.tex
@@ -45,13 +45,13 @@ or equal-to another object. Which leads us to this definition of the
initial object:
\begin{quote}
-The \textbf{initial object} is the object that has one and only one
-morphism going to any object in the category.
+ The \textbf{initial object} is the object that has one and only one
+ morphism going to any object in the category.
\end{quote}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/initial.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/initial.jpg}
\end{figure}
\noindent
@@ -87,13 +87,13 @@ object that's more terminal than any other object in the category.
Again, we will insist on uniqueness:
\begin{quote}
-The \textbf{terminal object} is the object with one and only one
-morphism coming to it from any object in the category.
+ The \textbf{terminal object} is the object with one and only one
+ morphism coming to it from any object in the category.
\end{quote}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/final.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/final.jpg}
\end{figure}
\noindent
@@ -192,9 +192,9 @@ $i_{2}$ to $i_{1}$. What's the composition of
these two morphisms?
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/uniqueness.jpg}
-\caption{All morphisms in this diagram are unique.}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/uniqueness.jpg}
+ \caption{All morphisms in this diagram are unique.}
\end{figure}
\noindent
@@ -259,8 +259,8 @@ respectively:
\src{snippet09}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/productpattern.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/productpattern.jpg}
\end{figure}
\noindent
@@ -268,8 +268,8 @@ All $c$s that fit this pattern will be considered candidates for
the product. There may be lots of them.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/productcandidates.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/productcandidates.jpg}
\end{figure}
\noindent
@@ -307,8 +307,8 @@ $p'$ and $q'$ can be reconstructed from $p$ and $q$ using $m$:
\src{snippet12}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/productranking.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/productranking.jpg}
\end{figure}
\noindent
@@ -323,8 +323,8 @@ and \code{snd} is indeed \emph{better} than the two candidates I
presented before.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/not-a-product.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/not-a-product.jpg}
\end{figure}
\noindent
@@ -375,10 +375,10 @@ category using the same universal construction. Such a product doesn't
always exist, but when it does, it is unique up to a unique isomorphism.
\begin{quote}
-A \textbf{product} of two objects $a$ and $b$ is the object
-$c$ equipped with two projections such that for any other object
-$c'$ equipped with two projections there is a unique morphism
-$m$ from $c'$ to $c$ that factorizes those projections.
+ A \textbf{product} of two objects $a$ and $b$ is the object
+ $c$ equipped with two projections such that for any other object
+ $c'$ equipped with two projections there is a unique morphism
+ $m$ from $c'$ to $c$ that factorizes those projections.
\end{quote}
\noindent
@@ -399,8 +399,8 @@ and $b$ to $c$.
\src{snippet21}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/coproductpattern.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/coproductpattern.jpg}
\end{figure}
\noindent
@@ -412,8 +412,8 @@ factorizes the injections:
\src{snippet22}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/coproductranking.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/coproductranking.jpg}
\end{figure}
\noindent
@@ -422,10 +422,10 @@ any other pattern, is called a coproduct and, if it exists, is unique up
to unique isomorphism.
\begin{quote}
-A \textbf{coproduct} of two objects $a$ and $b$ is the object
-$c$ equipped with two injections such that for any other object
-$c'$ equipped with two injections there is a unique morphism
-$m$ from $c$ to $c'$ that factorizes those injections.
+ A \textbf{coproduct} of two objects $a$ and $b$ is the object
+ $c$ equipped with two injections such that for any other object
+ $c'$ equipped with two injections there is a unique morphism
+ $m$ from $c$ to $c'$ that factorizes those injections.
\end{quote}
\noindent
@@ -588,41 +588,41 @@ isomorphism is the same as a bijection.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Show that the terminal object is unique up to unique isomorphism.
-\item
- What is a product of two objects in a poset? Hint: Use the universal
- construction.
-\item
- What is a coproduct of two objects in a poset?
-\item
- Implement the equivalent of Haskell \code{Either} as a generic type
- in your favorite language (other than Haskell).
-\item
- Show that \code{Either} is a ``better'' coproduct than \code{int}
- equipped with two injections:
+ \tightlist
+ \item
+ Show that the terminal object is unique up to unique isomorphism.
+ \item
+ What is a product of two objects in a poset? Hint: Use the universal
+ construction.
+ \item
+ What is a coproduct of two objects in a poset?
+ \item
+ Implement the equivalent of Haskell \code{Either} as a generic type
+ in your favorite language (other than Haskell).
+ \item
+ Show that \code{Either} is a ``better'' coproduct than \code{int}
+ equipped with two injections:
-\begin{snip}{cpp}
+ \begin{snip}{cpp}
int i(int n) { return n; }
int j(bool b) { return b ? 0: 1; }
\end{snip}
- Hint: Define a function
+ Hint: Define a function
-\begin{snip}{cpp}
+ \begin{snip}{cpp}
int m(Either const & e);
\end{snip}
- that factorizes \code{i} and \code{j}.
-\item
- Continuing the previous problem: How would you argue that \code{int}
- with the two injections \code{i} and \code{j} cannot be ``better''
- than \code{Either}?
-\item
- Still continuing: What about these injections?
+ that factorizes \code{i} and \code{j}.
+ \item
+ Continuing the previous problem: How would you argue that \code{int}
+ with the two injections \code{i} and \code{j} cannot be ``better''
+ than \code{Either}?
+ \item
+ Still continuing: What about these injections?
-\begin{snip}{cpp}
+ \begin{snip}{cpp}
int i(int n) {
if (n < 0) return n;
return n + 2;
@@ -630,18 +630,18 @@ int i(int n) {
int j(bool b) { return b ? 0: 1; }
\end{snip}
-\item
- Come up with an inferior candidate for a coproduct of \code{int} and
- \code{bool} that cannot be better than \code{Either} because it
- allows multiple acceptable morphisms from it to \code{Either}.
+ \item
+ Come up with an inferior candidate for a coproduct of \code{int} and
+ \code{bool} that cannot be better than \code{Either} because it
+ allows multiple acceptable morphisms from it to \code{Either}.
\end{enumerate}
\section{Bibliography}
\begin{enumerate}
-\tightlist
-\item
- The Catsters,
- \urlref{https://www.youtube.com/watch?v=upCSDIO9pjc}{Products and
- Coproducts} video.
+ \tightlist
+ \item
+ The Catsters,
+ \urlref{https://www.youtube.com/watch?v=upCSDIO9pjc}{Products and
+ Coproducts} video.
\end{enumerate}
diff --git a/src/content/1.6/simple-algebraic-data-types.tex b/src/content/1.6/simple-algebraic-data-types.tex
index 4dc6e5e..ea45e60 100644
--- a/src/content/1.6/simple-algebraic-data-types.tex
+++ b/src/content/1.6/simple-algebraic-data-types.tex
@@ -22,8 +22,8 @@ in C++ it's a relatively complex template defined in the Standard
Library.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/pair.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/pair.jpg}
\end{figure}
\noindent
@@ -384,17 +384,17 @@ statements about, say, natural numbers, which form a rig, to statements
about types. Here's a translation table with some entries of interest:
\begin{longtable}[]{@{}ll@{}}
-\toprule
-Numbers & Types\tabularnewline
-\midrule
-\endhead
-$0$ & \code{Void}\tabularnewline
-$1$ & \code{()}\tabularnewline
-$a + b$ & \code{Either a b = Left a | Right b}\tabularnewline
-$a \times b$ & \code{(a, b)} or \code{Pair a b = Pair a b}\tabularnewline
-$2 = 1 + 1$ & \code{data Bool = True | False}\tabularnewline
-$1 + a$ & \code{data Maybe = Nothing | Just a}\tabularnewline
-\bottomrule
+ \toprule
+ Numbers & Types\tabularnewline
+ \midrule
+ \endhead
+ $0$ & \code{Void}\tabularnewline
+ $1$ & \code{()}\tabularnewline
+ $a + b$ & \code{Either a b = Left a | Right b}\tabularnewline
+ $a \times b$ & \code{(a, b)} or \code{Pair a b = Pair a b}\tabularnewline
+ $2 = 1 + 1$ & \code{data Bool = True | False}\tabularnewline
+ $1 + a$ & \code{data Maybe = Nothing | Just a}\tabularnewline
+ \bottomrule
\end{longtable}
\noindent
@@ -407,7 +407,7 @@ If we do our usual substitutions, and also replace \code{List a} with
\code{x}, we get the equation:
\begin{Verbatim}
-x = 1 + a * x
+ x = 1 + a * x
\end{Verbatim}
We can't solve it using traditional algebraic methods because we can't
subtract or divide types. But we can try a series of substitutions,
@@ -416,11 +416,11 @@ where we keep replacing \code{x} on the right hand side with
the following series:
\begin{Verbatim}
-x = 1 + a*x
-x = 1 + a*(1 + a*x) = 1 + a + a*a*x
-x = 1 + a + a*a*(1 + a*x) = 1 + a + a*a + a*a*a*x
-...
-x = 1 + a + a*a + a*a*a + a*a*a*a...
+ x = 1 + a*x
+ x = 1 + a*(1 + a*x) = 1 + a + a*a*x
+ x = 1 + a + a*a*(1 + a*x) = 1 + a + a*a + a*a*a*x
+ ...
+ x = 1 + a + a*a + a*a*a + a*a*a*a...
\end{Verbatim}
We end up with an infinite sum of products (tuples), which can be
interpreted as: A list is either empty, \code{1}; or a singleton,
@@ -445,15 +445,15 @@ of them is inhabited. Logical \emph{and} and \emph{or} also form a
semiring, and it too can be mapped into type theory:
\begin{longtable}[]{@{}ll@{}}
-\toprule
-Logic & Types\tabularnewline
-\midrule
-\endhead
-$\mathit{false}$ & \code{Void}\tabularnewline
-$\mathit{true}$ & \code{()}\tabularnewline
-$a \mathbin{||} b$ & \code{Either a b = Left a | Right b}\tabularnewline
-$a \mathbin{\&\&} b$ & \code{(a, b)}\tabularnewline
-\bottomrule
+ \toprule
+ Logic & Types\tabularnewline
+ \midrule
+ \endhead
+ $\mathit{false}$ & \code{Void}\tabularnewline
+ $\mathit{true}$ & \code{()}\tabularnewline
+ $a \mathbin{||} b$ & \code{Either a b = Left a | Right b}\tabularnewline
+ $a \mathbin{\&\&} b$ & \code{(a, b)}\tabularnewline
+ \bottomrule
\end{longtable}
\noindent
@@ -464,47 +464,47 @@ talk about function types.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Show the isomorphism between \code{Maybe a} and
- \code{Either () a}.
-\item
- Here's a sum type defined in Haskell:
+ \tightlist
+ \item
+ Show the isomorphism between \code{Maybe a} and
+ \code{Either () a}.
+ \item
+ Here's a sum type defined in Haskell:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
data Shape = Circle Float
| Rect Float Float
\end{snip}
- When we want to define a function like \code{area} that acts on a
- \code{Shape}, we do it by pattern matching on the two constructors:
+ When we want to define a function like \code{area} that acts on a
+ \code{Shape}, we do it by pattern matching on the two constructors:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
area :: Shape -> Float
area (Circle r) = pi * r * r
area (Rect d h) = d * h
\end{snip}
- Implement \code{Shape} in C++ or Java as an interface and create two
- classes: \code{Circle} and \code{Rect}. Implement \code{area} as
- a virtual function.
-\item
- Continuing with the previous example: We can easily add a new function
- \code{circ} that calculates the circumference of a \code{Shape}.
- We can do it without touching the definition of \code{Shape}:
+ Implement \code{Shape} in C++ or Java as an interface and create two
+ classes: \code{Circle} and \code{Rect}. Implement \code{area} as
+ a virtual function.
+ \item
+ Continuing with the previous example: We can easily add a new function
+ \code{circ} that calculates the circumference of a \code{Shape}.
+ We can do it without touching the definition of \code{Shape}:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
circ :: Shape -> Float
circ (Circle r) = 2.0 * pi * r
circ (Rect d h) = 2.0 * (d + h)
\end{snip}
- Add \code{circ} to your C++ or Java implementation. What parts of
- the original code did you have to touch?
-\item
- Continuing further: Add a new shape, \code{Square}, to
- \code{Shape} and make all the necessary updates. What code did you
- have to touch in Haskell vs. C++ or Java? (Even if you're not a
- Haskell programmer, the modifications should be pretty obvious.)
-\item
- Show that $a + a = 2 \times a$ holds for types (up to
- isomorphism). Remember that $2$ corresponds to \code{Bool},
- according to our translation table.
+ Add \code{circ} to your C++ or Java implementation. What parts of
+ the original code did you have to touch?
+ \item
+ Continuing further: Add a new shape, \code{Square}, to
+ \code{Shape} and make all the necessary updates. What code did you
+ have to touch in Haskell vs. C++ or Java? (Even if you're not a
+ Haskell programmer, the modifications should be pretty obvious.)
+ \item
+ Show that $a + a = 2 \times a$ holds for types (up to
+ isomorphism). Remember that $2$ corresponds to \code{Bool},
+ according to our translation table.
\end{enumerate}
diff --git a/src/content/1.7/functors.tex b/src/content/1.7/functors.tex
index 0ef457e..434a893 100644
--- a/src/content/1.7/functors.tex
+++ b/src/content/1.7/functors.tex
@@ -21,7 +21,7 @@ makes sense by now. I won't use parentheses when applying functors to
objects or morphisms.)
\begin{figure}[H]
-\centering\includegraphics[width=0.3\textwidth]{images/functor.jpg}
+ \centering\includegraphics[width=0.3\textwidth]{images/functor.jpg}
\end{figure}
\noindent
@@ -36,8 +36,8 @@ and $g$:
\[F h = F g~.~F f\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/functorcompos.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/functorcompos.jpg}
\end{figure}
\noindent
@@ -50,8 +50,8 @@ Here, $\idarrow[a]$ is the identity at the object $a$,
and $\idarrow[F a]$ the identity at $F a$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/functorid.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/functorid.jpg}
\end{figure}
\noindent
@@ -124,8 +124,8 @@ signature:
\src{snippet04}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/functormaybe.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/functormaybe.jpg}
\end{figure}
\noindent
@@ -707,23 +707,23 @@ We'll see later that functors form categories as well.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Can we turn the \code{Maybe} type constructor into a functor by
- defining:
+ \tightlist
+ \item
+ Can we turn the \code{Maybe} type constructor into a functor by
+ defining:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
fmap _ _ = Nothing
\end{snip}
- which ignores both of its arguments? (Hint: Check the functor laws.)
-\item
- Prove functor laws for the reader functor. Hint: it's really simple.
-\item
- Implement the reader functor in your second favorite language (the
- first being Haskell, of course).
-\item
- Prove the functor laws for the list functor. Assume that the laws are
- true for the tail part of the list you're applying it to (in other
- words, use \emph{induction}).
+ which ignores both of its arguments? (Hint: Check the functor laws.)
+ \item
+ Prove functor laws for the reader functor. Hint: it's really simple.
+ \item
+ Implement the reader functor in your second favorite language (the
+ first being Haskell, of course).
+ \item
+ Prove the functor laws for the list functor. Assume that the laws are
+ true for the tail part of the list you're applying it to (in other
+ words, use \emph{induction}).
\end{enumerate}
diff --git a/src/content/1.8/functoriality.tex b/src/content/1.8/functoriality.tex
index 28f73ce..70fc574 100644
--- a/src/content/1.8/functoriality.tex
+++ b/src/content/1.8/functoriality.tex
@@ -18,7 +18,7 @@ $\cat{E}$. Notice that this is just saying that it's a mapping from a
\newterm{Cartesian product} of categories $\cat{C}\times{}\cat{D}$ to $\cat{E}$.
\begin{figure}[H]
-\centering\includegraphics[width=0.3\textwidth]{images/bifunctor.jpg}
+ \centering\includegraphics[width=0.3\textwidth]{images/bifunctor.jpg}
\end{figure}
\noindent
@@ -52,8 +52,8 @@ constructor that takes two type arguments. Here's the definition of the
\src{snippet01}
\begin{figure}[H]
-\centering\includegraphics[width=0.3\textwidth]{images/bimap.jpg}
-\caption{bimap}
+ \centering\includegraphics[width=0.3\textwidth]{images/bimap.jpg}
+ \caption{bimap}
\end{figure}
The type variable \code{f} represents the bifunctor. You can see that
@@ -76,14 +76,14 @@ first and the second argument, respectively.
\begin{figure}[H]
\centering
\begin{minipage}{0.45\textwidth}
- \centering
- \includegraphics[width=0.65\textwidth]{images/first.jpg} % first figure itself
- \caption{first}
+ \centering
+ \includegraphics[width=0.65\textwidth]{images/first.jpg} % first figure itself
+ \caption{first}
\end{minipage}\hfill
\begin{minipage}{0.45\textwidth}
- \centering
- \includegraphics[width=0.6\textwidth]{images/second.jpg} % second figure itself
- \caption{second}
+ \centering
+ \includegraphics[width=0.6\textwidth]{images/second.jpg} % second figure itself
+ \caption{second}
\end{minipage}
\end{figure}
@@ -102,7 +102,7 @@ make sure they are related to each other in this manner).
An important example of a bifunctor is the categorical product --- a
product of two objects that is defined by a \hyperref[products-and-coproducts]{universal
-construction}. If the product exists for any pair of objects, the
+ construction}. If the product exists for any pair of objects, the
mapping from those objects to the product is bifunctorial. This is true
in general, and in Haskell in particular. Here's the \code{Bifunctor}
instance for a pair constructor --- the simplest product type:
@@ -362,7 +362,7 @@ This implementation can also be automatically derived by the compiler.
\section{The Writer Functor}
I promised that I would come back to the \hyperref[kleisli-categories]{Kleisli
-category} I described earlier. Morphisms in that category were
+ category} I described earlier. Morphisms in that category were
represented as ``embellished'' functions returning the \code{Writer}
data structure.
@@ -488,8 +488,8 @@ by the way --- the kind we've been studying thus far --- are called
\emph{covariant} functors.
\begin{figure}[H]
-\centering
-\includegraphics[width=40mm]{images/contravariant.jpg}
+ \centering
+ \includegraphics[width=40mm]{images/contravariant.jpg}
\end{figure}
\noindent
@@ -538,9 +538,9 @@ the defaults for \code{lmap} and \code{rmap}, or implementing both
\code{dimap}.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/dimap.jpg}
-\caption{dimap}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/dimap.jpg}
+ \caption{dimap}
\end{figure}
\noindent
@@ -562,8 +562,8 @@ category $\cat{C}^{op}\times{}\cat{C}$ to the category of sets, $\Set$.
Let's define its action on morphisms. A morphism in
$\cat{C}^{op}\times{}\cat{C}$ is a pair of morphisms from $\cat{C}$:
\begin{gather*}
-f \Colon a' \to a \\
-g \Colon b \to b'
+ f \Colon a' \to a \\
+ g \Colon b \to b'
\end{gather*}
The lifting of this pair must be a morphism (a function) from the set
$\cat{C}(a, b)$ to the set $\cat{C}(a', b')$. Just pick
@@ -577,48 +577,48 @@ As you can see, the hom-functor is a special case of a profunctor.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Show that the data type:
+ \tightlist
+ \item
+ Show that the data type:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
data Pair a b = Pair a b
\end{snip}
- is a bifunctor. For additional credit implement all three methods of
- \code{Bifunctor} and use equational reasoning to show that these
- definitions are compatible with the default implementations whenever
- they can be applied.
-\item
- Show the isomorphism between the standard definition of \code{Maybe}
- and this desugaring:
+ is a bifunctor. For additional credit implement all three methods of
+ \code{Bifunctor} and use equational reasoning to show that these
+ definitions are compatible with the default implementations whenever
+ they can be applied.
+ \item
+ Show the isomorphism between the standard definition of \code{Maybe}
+ and this desugaring:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
type Maybe' a = Either (Const () a) (Identity a)
\end{snip}
- Hint: Define two mappings between the two implementations. For
- additional credit, show that they are the inverse of each other using
- equational reasoning.
-\item
- Let's try another data structure. I call it a \code{PreList} because
- it's a precursor to a \code{List}. It replaces recursion with a type
- parameter \code{b}.
+ Hint: Define two mappings between the two implementations. For
+ additional credit, show that they are the inverse of each other using
+ equational reasoning.
+ \item
+ Let's try another data structure. I call it a \code{PreList} because
+ it's a precursor to a \code{List}. It replaces recursion with a type
+ parameter \code{b}.
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
data PreList a b = Nil | Cons a b
\end{snip}
- You could recover our earlier definition of a \code{List} by
- recursively applying \code{PreList} to itself (we'll see how it's
- done when we talk about fixed points).
+ You could recover our earlier definition of a \code{List} by
+ recursively applying \code{PreList} to itself (we'll see how it's
+ done when we talk about fixed points).
- Show that \code{PreList} is an instance of \code{Bifunctor}.
-\item
- Show that the following data types define bifunctors in \code{a} and
- \code{b}:
+ Show that \code{PreList} is an instance of \code{Bifunctor}.
+ \item
+ Show that the following data types define bifunctors in \code{a} and
+ \code{b}:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
data K2 c a b = K2 c
data Fst a b = Fst a
@@ -626,14 +626,14 @@ data Fst a b = Fst a
data Snd a b = Snd b
\end{snip}
- For additional credit, check your solutions against Conor McBride's
- paper \urlref{http://strictlypositive.org/CJ.pdf}{Clowns to the Left of
- me, Jokers to the Right}.
-\item
- Define a bifunctor in a language other than Haskell. Implement
- \code{bimap} for a generic pair in that language.
-\item
- Should \code{std::map} be considered a bifunctor or a profunctor in
- the two template arguments \code{Key} and \code{T}? How would you
- redesign this data type to make it so?
+ For additional credit, check your solutions against Conor McBride's
+ paper \urlref{http://strictlypositive.org/CJ.pdf}{Clowns to the Left of
+ me, Jokers to the Right}.
+ \item
+ Define a bifunctor in a language other than Haskell. Implement
+ \code{bimap} for a generic pair in that language.
+ \item
+ Should \code{std::map} be considered a bifunctor or a profunctor in
+ the two template arguments \code{Key} and \code{T}? How would you
+ redesign this data type to make it so?
\end{enumerate}
diff --git a/src/content/1.9/function-types.tex b/src/content/1.9/function-types.tex
index ba598fa..9684aee 100644
--- a/src/content/1.9/function-types.tex
+++ b/src/content/1.9/function-types.tex
@@ -12,9 +12,9 @@ in the category $\Set$ every hom-set is itself an object in the
same category ---because it is, after all, a \emph{set}.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/set-hom-set.jpg}
-\caption{Hom-set in Set is just a set}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/set-hom-set.jpg}
+ \caption{Hom-set in Set is just a set}
\end{figure}
\noindent
@@ -22,9 +22,9 @@ The same is not true of other categories where hom-sets are external to
a category. They are even called \emph{external} hom-sets.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/hom-set.jpg}
-\caption{Hom-set in category C is an external set}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/hom-set.jpg}
+ \caption{Hom-set in category C is an external set}
\end{figure}
\noindent
@@ -46,7 +46,7 @@ relationship to the argument type and the result type. We've already
seen the constructions of composite types --- those that involved
relationships between objects. We used universal constructions to define
a \hyperref[products-and-coproducts]{product
-and coproduct types}. We can use the same trick to define a
+ and coproduct types}. We can use the same trick to define a
function type. We will need a pattern that involves three objects: the
function type that we are constructing, the argument type, and the
result type.
@@ -68,10 +68,10 @@ $f x$ (the application of $f$ to $x$, which is an
element of $b$).
\begin{figure}[H]
-\centering\includegraphics[width=0.35\textwidth]{images/functionset.jpg}
-\caption{In Set we can pick a function $f$ from a set of functions $z$ and we can
-pick an argument $x$ from the set (type) $a$. We get an element $f x$ in the
-set (type) $b$.}
+ \centering\includegraphics[width=0.35\textwidth]{images/functionset.jpg}
+ \caption{In Set we can pick a function $f$ from a set of functions $z$ and we can
+ pick an argument $x$ from the set (type) $a$. We get an element $f x$ in the
+ set (type) $b$.}
\end{figure}
\noindent
@@ -86,10 +86,10 @@ So that's the pattern: a product of two objects $z$ and
$a$ connected to another object $b$ by a morphism $g$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/functionpattern.jpg}
-\caption{A pattern of objects and morphisms that is the starting point of the
-universal construction}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/functionpattern.jpg}
+ \caption{A pattern of objects and morphisms that is the starting point of the
+ universal construction}
\end{figure}
\noindent
@@ -121,9 +121,9 @@ through the application of $g$. (Hint: Read this sentence while
looking at the picture.)
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/functionranking.jpg}
-\caption{Establishing a ranking between candidates for the function object}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/functionranking.jpg}
+ \caption{Establishing a ranking between candidates for the function object}
\end{figure}
\noindent
@@ -134,7 +134,7 @@ that has both $z'$ and $z$ crossed with $a$.
What we really need, given the mapping $h$ from $z'$
to $z$, is a mapping from $z' \times a$ to $z \times a$.
And now, after discussing the \hyperref[functoriality]{functoriality
-of the product}, we know how to do it. Because the product itself is a
+ of the product}, we know how to do it. Because the product itself is a
functor (more precisely an endo-bi-functor), it's possible to lift pairs
of morphisms. In other words, we can define not only products of objects
but also products of morphisms.
@@ -161,29 +161,29 @@ $eval$. This object is better than any other object according to
our ranking.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/universalfunctionobject.jpg}
-\caption{The definition of the universal function object. This is the same
-diagram as above, but now the object $a \Rightarrow b$ is \emph{universal}.}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/universalfunctionobject.jpg}
+ \caption{The definition of the universal function object. This is the same
+ diagram as above, but now the object $a \Rightarrow b$ is \emph{universal}.}
\end{figure}
\noindent
Formally:
\begin{longtable}[]{@{}l@{}}
-\toprule
-\begin{minipage}[t]{0.97\columnwidth}\raggedright\strut
-A \emph{function object} from $a$ to $b$ is an object
-$a \Rightarrow b$ together with the morphism
-\[eval \Colon ((a \Rightarrow b) \times a) \to b\]
-such that for any other object $z$ with a morphism
-\[g \Colon z \times a \to b\]
-there is a unique morphism
-\[h \Colon z \to (a \Rightarrow b)\]
-that factors $g$ through $eval$:
-\[g = eval \circ (h \times \id)\]
-\end{minipage}\tabularnewline
-\bottomrule
+ \toprule
+ \begin{minipage}[t]{0.97\columnwidth}\raggedright\strut
+ A \emph{function object} from $a$ to $b$ is an object
+ $a \Rightarrow b$ together with the morphism
+ \[eval \Colon ((a \Rightarrow b) \times a) \to b\]
+ such that for any other object $z$ with a morphism
+ \[g \Colon z \times a \to b\]
+ there is a unique morphism
+ \[h \Colon z \to (a \Rightarrow b)\]
+ that factors $g$ through $eval$:
+ \[g = eval \circ (h \times \id)\]
+ \end{minipage}\tabularnewline
+ \bottomrule
\end{longtable}
\noindent
@@ -365,13 +365,13 @@ such a category.
A Cartesian closed category must contain:
\begin{enumerate}
-\tightlist
-\item
- The terminal object,
-\item
- A product of any pair of objects, and
-\item
- An exponential for any pair of objects.
+ \tightlist
+ \item
+ The terminal object,
+ \item
+ A product of any pair of objects, and
+ \item
+ An exponential for any pair of objects.
\end{enumerate}
If you consider an exponential as an iterated product (possibly
infinitely many times), then you can think of a Cartesian closed
@@ -388,8 +388,8 @@ The terminal object and the product have their duals: the initial object
and the coproduct. A Cartesian closed category that also supports those
two, and in which product can be distributed over coproduct
\begin{gather*}
-a \times (b + c) = a \times b + a \times c \\
-(b + c) \times a = b \times a + c \times a
+ a \times (b + c) = a \times b + a \times c \\
+ (b + c) \times a = b \times a + c \times a
\end{gather*}
is called a \newterm{bicartesian closed} category. We'll see in the next
section that bicartesian closed categories, of which $\Set$ is a
@@ -596,11 +596,11 @@ revolutionizing the world in more than one way.
\section{Bibliography}
\begin{enumerate}
-\tightlist
-\item
- Ralph Hinze, Daniel W. H. James,
- \urlref{http://www.cs.ox.ac.uk/ralf.hinze/publications/WGP10.pdf}{Reason
- Isomorphically!}. This paper contains proofs of all those high-school
- algebraic identities in category theory that I mentioned in this
- chapter.
+ \tightlist
+ \item
+ Ralph Hinze, Daniel W. H. James,
+ \urlref{http://www.cs.ox.ac.uk/ralf.hinze/publications/WGP10.pdf}{Reason
+ Isomorphically!}. This paper contains proofs of all those high-school
+ algebraic identities in category theory that I mentioned in this
+ chapter.
\end{enumerate}
diff --git a/src/content/2.1/declarative-programming.tex b/src/content/2.1/declarative-programming.tex
index 425fca1..d20ad02 100644
--- a/src/content/2.1/declarative-programming.tex
+++ b/src/content/2.1/declarative-programming.tex
@@ -37,7 +37,7 @@ if we could find it, we would probably revolutionize our understanding
of the universe.
\begin{wrapfigure}{R}{0pt}
-\includegraphics[width=0.5\textwidth]{images/asteroids.png}
+ \includegraphics[width=0.5\textwidth]{images/asteroids.png}
\end{wrapfigure}
Let me elaborate. There is a similar duality in physics, which either
@@ -66,8 +66,8 @@ which is given by force divided by mass.
These are the direct encodings of the differential equations
corresponding to Newton's laws of motion:
\begin{align*}
-F &= m \frac{dv}{dt} \\
-v &= \frac{dx}{dt}
+ F & = m \frac{dv}{dt} \\
+ v & = \frac{dx}{dt}
\end{align*}
Similar methods may be applied to more complex problems, like the
propagation of electromagnetic fields using Maxwell's equations, or even
@@ -93,14 +93,14 @@ then take a shortcut through water. The path of minimum time makes the
ray refract at the boundary of air and water, resulting in Snell's law
of refraction:
\begin{equation*}
-\frac{sin(\theta_1)}{sin(\theta_2)} = \frac{v_1}{v_2}
+ \frac{sin(\theta_1)}{sin(\theta_2)} = \frac{v_1}{v_2}
\end{equation*}
where $v_1$ is the speed of light in the air and $v_2$ is
the speed of light in the water.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/snell.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/snell.jpg}
\end{figure}
\noindent
@@ -116,8 +116,8 @@ minimize kinetic energy. Then it will speed up to go quickly through the
area of low potential energy.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/mortar.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/mortar.jpg}
\end{figure}
\noindent
@@ -128,8 +128,8 @@ Feynman path integral between those states is used to calculate the
probability of transition.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/feynman.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/feynman.jpg}
\end{figure}
\noindent
@@ -180,8 +180,8 @@ best such object --- it optimizes a certain property: the property of
factorizing the projections of other such objects.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/productranking.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/productranking.jpg}
\end{figure}
\noindent
@@ -200,7 +200,7 @@ built in, rather than being defined by universal constructions; although
there have been attempts at creating categorical programming languages
(see, e.g.,
\urlref{http://web.sfc.keio.ac.jp/~hagino/thesis.pdf}{Tatsuya
-Hagino's thesis}).
+ Hagino's thesis}).
Whether used directly or not, categorical definitions justify
pre-existing programming constructs, and give rise to new ones. Most
diff --git a/src/content/2.2/limits-and-colimits.tex b/src/content/2.2/limits-and-colimits.tex
index 9ff3d82..5afd1d0 100644
--- a/src/content/2.2/limits-and-colimits.tex
+++ b/src/content/2.2/limits-and-colimits.tex
@@ -8,8 +8,8 @@ Now that we know more about \hyperref[functors]{functors} and
try.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/productpattern.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/productpattern.jpg}
\end{figure}
\noindent
@@ -36,10 +36,10 @@ nothing can stop us from using categories more complex than $\cat{2}$
to define our patterns.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/two.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/two.jpg}
\end{figure}
-
+
\noindent
But let's continue. The next step in the definition of a product is the
selection of the candidate object $c$. Here again, we could
@@ -52,8 +52,8 @@ done with $\Delta_c$. Remember, $\Delta_c$ maps all
objects into $c$ and all morphisms into $\idarrow[c]$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/twodelta.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/twodelta.jpg}
\end{figure}
\noindent
@@ -75,8 +75,8 @@ is trivially satisfied, because there are no morphisms (other than the
identities) in $\cat{2}$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/productcone.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/productcone.jpg}
\end{figure}
\noindent
@@ -99,8 +99,8 @@ morphisms connecting $c$ to the diagram: the image of $\cat{I}$
under $D$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/cone.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/cone.jpg}
\end{figure}
\noindent
@@ -114,13 +114,13 @@ the naturality square becomes a commuting triangle. The two arms of this
triangle are the components of the natural transformation.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/conenaturality.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/conenaturality.jpg}
\end{figure}
\noindent
So that's one cone. What we are interested in is the \newterm{universal
-cone} --- just like we picked a universal object for our definition of a
+ cone} --- just like we picked a universal object for our definition of a
product.
There are many ways to go about it. For instance, we may define a
@@ -139,19 +139,19 @@ instance:
\src{snippet01}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/productranking.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/productranking.jpg}
\end{figure}
This condition translates, in the general case, to the condition that
the triangles whose one side is the factorizing morphism all commute.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/conecommutativity.jpg}
-\caption{The commuting triangle connecting two cones, with the factorizing
-morphism $h$ (here, the lower cone is the universal one, with
-$\Lim[D]$ as its apex)}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/conecommutativity.jpg}
+ \caption{The commuting triangle connecting two cones, with the factorizing
+ morphism $h$ (here, the lower cone is the universal one, with
+ $\Lim[D]$ as its apex)}
\end{figure}
\noindent
@@ -231,8 +231,8 @@ Notice the inversion in the order of $c$ and $c'$
characteristic of a \emph{contravariant} functor.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/homsetmapping.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/homsetmapping.jpg}
\end{figure}
\noindent
@@ -265,8 +265,8 @@ It's relatively easy to show that those components indeed add up to a
natural transformation.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/natmapping.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/natmapping.jpg}
\end{figure}
\noindent
@@ -346,8 +346,8 @@ and two projections:
\src{snippet04}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/equalizercone.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/equalizercone.jpg}
\end{figure}
\noindent
@@ -401,8 +401,8 @@ with
\src{snippet12}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/equilizerlimit.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/equilizerlimit.jpg}
\end{figure}
\noindent
@@ -428,8 +428,8 @@ and three morphisms:
\src{snippet14}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/pullbackcone.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/pullbackcone.jpg}
\end{figure}
\noindent
@@ -441,8 +441,8 @@ So we are only left with the following condition:
A pullback is a universal cone of this shape.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/pullbacklimit.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/pullbacklimit.jpg}
\end{figure}
\noindent
@@ -490,8 +490,8 @@ overriding of methods. And, of course, there would be no pullback if
there is a name conflict between some methods of \code{B} and \code{C}.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.25\textwidth]{images/classes.jpg}
+ \centering
+ \includegraphics[width=0.25\textwidth]{images/classes.jpg}
\end{figure}
\noindent
@@ -551,9 +551,9 @@ morphism, which now flows from the universal co-cone to any other
co-cone.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/colimit.jpg}
-\caption{Cocone with a factorizing morphism $h$ connecting two apexes.}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/colimit.jpg}
+ \caption{Cocone with a factorizing morphism $h$ connecting two apexes.}
\end{figure}
\noindent
@@ -562,8 +562,8 @@ diagram generated by $\cat{2}$, the category we've used in the
definition of the product.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/coproductranking.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/coproductranking.jpg}
\end{figure}
\noindent
@@ -582,7 +582,7 @@ $1\leftarrow2\rightarrow3$.
I said previously that functors come close to the idea of continuous
mappings of categories, in the sense that they never break existing
connections (morphisms). The actual definition of a \emph{continuous
-functor} $F$ from a category $\cat{C}$ to $\cat{C'}$ includes the
+ functor} $F$ from a category $\cat{C}$ to $\cat{C'}$ includes the
requirement that the functor preserve limits. Every diagram $D$
in $\cat{C}$ can be mapped to a diagram $F \circ D$ in $\cat{C'}$ by
simply composing two functors. The continuity condition for $F$
@@ -591,8 +591,8 @@ the diagram $F \circ D$ also has a limit, and it is equal to
$F (\Lim[D])$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.6\textwidth]{images/continuity.jpg}
+ \centering
+ \includegraphics[width=0.6\textwidth]{images/continuity.jpg}
\end{figure}
\noindent
@@ -650,23 +650,23 @@ poset).
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- How would you describe a pushout in the category of C++ classes?
-\item
- Show that the limit of the identity functor
- $\mathbf{Id} \Colon \cat{C} \to \cat{C}$ is the initial object.
-\item
- Subsets of a given set form a category. A morphism in that category is
- defined to be an arrow connecting two sets if the first is the subset
- of the second. What is a pullback of two sets in such a category?
- What's a pushout? What are the initial and terminal objects?
-\item
- Can you guess what a coequalizer is?
-\item
- Show that, in a category with a terminal object, a pullback towards
- the terminal object is a product.
-\item
- Similarly, show that a pushout from an initial object (if one exists)
- is the coproduct.
+ \tightlist
+ \item
+ How would you describe a pushout in the category of C++ classes?
+ \item
+ Show that the limit of the identity functor
+ $\mathbf{Id} \Colon \cat{C} \to \cat{C}$ is the initial object.
+ \item
+ Subsets of a given set form a category. A morphism in that category is
+ defined to be an arrow connecting two sets if the first is the subset
+ of the second. What is a pullback of two sets in such a category?
+ What's a pushout? What are the initial and terminal objects?
+ \item
+ Can you guess what a coequalizer is?
+ \item
+ Show that, in a category with a terminal object, a pullback towards
+ the terminal object is a product.
+ \item
+ Similarly, show that a pushout from an initial object (if one exists)
+ is the coproduct.
\end{enumerate}
diff --git a/src/content/2.3/free-monoids.tex b/src/content/2.3/free-monoids.tex
index bf2417d..ff1e2c5 100644
--- a/src/content/2.3/free-monoids.tex
+++ b/src/content/2.3/free-monoids.tex
@@ -1,7 +1,7 @@
% !TEX root = ../../ctfp-print.tex
\lettrine[lhang=0.17]{M}{onoids are an important} concept in both category
-theory and in programming. Categories correspond to strongly typed languages,
+theory and in programming. Categories correspond to strongly typed languages,
monoids to untyped languages. That's because in a monoid you can compose any
two arrows, just as in an untyped language you can compose any two functions
(of course, you may end up with a runtime error when you execute your
@@ -43,8 +43,8 @@ $(b, b)$, and end up with the set
$\{e, a, b, (a, a), (a, b), (b, a), (b, b)\}$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.8\textwidth]{images/bunnies.jpg}
+ \centering
+ \includegraphics[width=0.8\textwidth]{images/bunnies.jpg}
\end{figure}
\noindent
@@ -63,7 +63,7 @@ This kind of construction, in which you keep generating all possible
combinations of elements, and perform the minimum number of
identifications --- just enough to uphold the laws --- is called a free
construction. What we have just done is to construct a \newterm{free
-monoid} from the set of generators $\{a, b\}$.
+ monoid} from the set of generators $\{a, b\}$.
\section{Free Monoid in Haskell}
@@ -186,8 +186,8 @@ collapse them). It will all be sorted out by the universal construction,
which will pick the best representative of this pattern.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/monoid-pattern.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/monoid-pattern.jpg}
\end{figure}
\noindent
@@ -213,8 +213,8 @@ be mapped to a product of the corresponding two generators in the second
monoid, and so on.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/monoid-ranking.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/monoid-ranking.jpg}
\end{figure}
\noindent
@@ -222,11 +222,11 @@ This ranking may be used to find the best candidate --- the free monoid.
Here's the definition:
\begin{quote}
-We'll say that $m$ (together with the function $p$) is the
-\textbf{free monoid} with the generators $x$ if and only if there
-is a \emph{unique} morphism $h$ from $m$ to any other
-monoid $n$ (together with the function $q$) that satisfies
-the above factorization property.
+ We'll say that $m$ (together with the function $p$) is the
+ \textbf{free monoid} with the generators $x$ if and only if there
+ is a \emph{unique} morphism $h$ from $m$ to any other
+ monoid $n$ (together with the function $q$) that satisfies
+ the above factorization property.
\end{quote}
Incidentally, this answers our second question. The function
$U h$ is the one that has the power to collapse multiple
@@ -242,30 +242,30 @@ We'll come back to free monoids when we talk about adjunctions.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- You might think (as I did, originally) that the requirement that a
- homomorphism of monoids preserve the unit is redundant. After all, we
- know that for all $a$
+ \tightlist
+ \item
+ You might think (as I did, originally) that the requirement that a
+ homomorphism of monoids preserve the unit is redundant. After all, we
+ know that for all $a$
-\begin{snip}{text}
+ \begin{snip}{text}
h a * h e = h (a * e) = h a
\end{snip}
- So $h e$ acts like a right unit (and, by analogy, as a left
- unit). The problem is that $h a$, for all $a$ might
- only cover a sub-monoid of the target monoid. There may be a ``true''
- unit outside of the image of $h$. Show that an isomorphism
- between monoids that preserves multiplication must automatically
- preserve unit.
-\item
- Consider a monoid homomorphism from lists of integers with
- concatenation to integers with multiplication. What is the image of
- the empty list \code{{[}{]}}? Assume that all singleton lists are
- mapped to the integers they contain, that is \code{{[}3{]}} is
- mapped to 3, etc. What's the image of \code{{[}1, 2, 3, 4{]}}?
- How many different lists map to the integer 12? Is there any other
- homomorphism between the two monoids?
-\item
- What is the free monoid generated by a one-element set? Can you see
- what it's isomorphic to?
+ So $h e$ acts like a right unit (and, by analogy, as a left
+ unit). The problem is that $h a$, for all $a$ might
+ only cover a sub-monoid of the target monoid. There may be a ``true''
+ unit outside of the image of $h$. Show that an isomorphism
+ between monoids that preserves multiplication must automatically
+ preserve unit.
+ \item
+ Consider a monoid homomorphism from lists of integers with
+ concatenation to integers with multiplication. What is the image of
+ the empty list \code{{[}{]}}? Assume that all singleton lists are
+ mapped to the integers they contain, that is \code{{[}3{]}} is
+ mapped to 3, etc. What's the image of \code{{[}1, 2, 3, 4{]}}?
+ How many different lists map to the integer 12? Is there any other
+ homomorphism between the two monoids?
+ \item
+ What is the free monoid generated by a one-element set? Can you see
+ what it's isomorphic to?
\end{enumerate}
diff --git a/src/content/2.4/representable-functors.tex b/src/content/2.4/representable-functors.tex
index d177b9a..64874a5 100644
--- a/src/content/2.4/representable-functors.tex
+++ b/src/content/2.4/representable-functors.tex
@@ -58,8 +58,8 @@ fixed, $\cat{C}(a, x)$ will also vary in $\Set$. Thus we have a
mapping from $x$ to $\Set$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.45\textwidth]{images/hom-set.jpg}
+ \centering
+ \includegraphics[width=0.45\textwidth]{images/hom-set.jpg}
\end{figure}
\noindent
@@ -85,8 +85,8 @@ is a morphism going from $a$ to $y$. It is therefore a
member of $\cat{C}(a, y)$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.45\textwidth]{images/hom-functor.jpg}
+ \centering
+ \includegraphics[width=0.45\textwidth]{images/hom-functor.jpg}
\end{figure}
\noindent
@@ -202,7 +202,7 @@ It must respect naturality conditions, and it must be the inverse of \code{alpha
alpha . beta = id = beta . alpha
\end{snip}
We will see later that a natural transformation from $\cat{C}(a, -)$
-to any $\Set$-valued functor always exists as long as $F a$ is
+to any $\Set$-valued functor always exists as long as $F a$ is
non-empty (Yoneda's lemma) but it is not necessarily invertible.
Let me give you an example in Haskell with the list functor and
@@ -297,36 +297,36 @@ explore alternative implementations that have practical value.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Show that the hom-functors map identity morphisms in \emph{C} to
- corresponding identity functions in $\Set$.
-\item
- Show that \code{Maybe} is not representable.
-\item
- Is the \code{Reader} functor representable?
-\item
- Using \code{Stream} representation, memoize a function that squares
- its argument.
-\item
- Show that \code{tabulate} and \code{index} for \code{Stream} are
- indeed the inverse of each other. (Hint: use induction.)
-\item
- The functor:
+ \tightlist
+ \item
+ Show that the hom-functors map identity morphisms in \emph{C} to
+ corresponding identity functions in $\Set$.
+ \item
+ Show that \code{Maybe} is not representable.
+ \item
+ Is the \code{Reader} functor representable?
+ \item
+ Using \code{Stream} representation, memoize a function that squares
+ its argument.
+ \item
+ Show that \code{tabulate} and \code{index} for \code{Stream} are
+ indeed the inverse of each other. (Hint: use induction.)
+ \item
+ The functor:
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
Pair a = Pair a a
\end{snip}
- is representable. Can you guess the type that represents it? Implement
- \code{tabulate} and \code{index}.
+ is representable. Can you guess the type that represents it? Implement
+ \code{tabulate} and \code{index}.
\end{enumerate}
\section{Bibliography}
\begin{enumerate}
-\tightlist
-\item
- The Catsters video about
- \urlref{https://www.youtube.com/watch?v=4QgjKUzyrhM}{representable
- functors}.
+ \tightlist
+ \item
+ The Catsters video about
+ \urlref{https://www.youtube.com/watch?v=4QgjKUzyrhM}{representable
+ functors}.
\end{enumerate}
diff --git a/src/content/2.5/the-yoneda-lemma.tex b/src/content/2.5/the-yoneda-lemma.tex
index 93eac73..6192adc 100644
--- a/src/content/2.5/the-yoneda-lemma.tex
+++ b/src/content/2.5/the-yoneda-lemma.tex
@@ -50,13 +50,13 @@ $\alpha$. Because we are operating in $\Set$, the components of
the natural transformation, like $\alpha_x$ or $\alpha_y$, are just
regular functions between sets:
\begin{gather*}
-\alpha_x \Colon \cat{C}(a, x) \to F x \\
-\alpha_y \Colon \cat{C}(a, y) \to F y
+ \alpha_x \Colon \cat{C}(a, x) \to F x \\
+ \alpha_y \Colon \cat{C}(a, y) \to F y
\end{gather*}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/yoneda1.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/yoneda1.png}
\end{figure}
\noindent
@@ -79,8 +79,8 @@ Just how strong this condition is can be seen by specializing it to the
case of $x = a$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/yoneda2.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/yoneda2.png}
\end{figure}
\noindent
@@ -102,8 +102,8 @@ get a point in $F a$.
We have just proven the Yoneda lemma:
\begin{quote}
-There is a one-to-one correspondence between natural transformations
-from $\cat{C}(a, -)$ to $F$ and elements of $F a$.
+ There is a one-to-one correspondence between natural transformations
+ from $\cat{C}(a, -)$ to $F$ and elements of $F a$.
\end{quote}
in other words,
\[\cat{Nat}(\cat{C}(a, -), F) \cong F a\]
@@ -133,8 +133,8 @@ $p$ to some point $q$ in $F a$. I'll show you that
any choice of $q$ leads to a unique natural transformation.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/yoneda3.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/yoneda3.png}
\end{figure}
\noindent
@@ -149,8 +149,8 @@ hom-functor, the morphism $g$ is mapped to a function
$\cat{C}(a, g)$; and under $F$ it's mapped to $F g$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/yoneda4.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/yoneda4.png}
\end{figure}
\noindent
@@ -186,8 +186,8 @@ Since $p'$ was arbitrary, the whole function $\alpha_x$ is
thus determined.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/yoneda5.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/yoneda5.png}
\end{figure}
\noindent
@@ -315,35 +315,35 @@ called the Yoneda lemma.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Show that the two functions \code{phi} and \code{psi} that form
- the Yoneda isomorphism in Haskell are inverses of each other.
+ \tightlist
+ \item
+ Show that the two functions \code{phi} and \code{psi} that form
+ the Yoneda isomorphism in Haskell are inverses of each other.
-\begin{snip}{haskell}
+ \begin{snip}{haskell}
phi :: (forall x . (a -> x) -> F x) -> F a
phi alpha = alpha id
psi :: F a -> (forall x . (a -> x) -> F x)
psi fa h = fmap h fa
\end{snip}
-\item
- A discrete category is one that has objects but no morphisms other
- than identity morphisms. How does the Yoneda lemma work for functors
- from such a category?
-\item
- A list of units \code{{[}(){]}} contains no other information but
- its length. So, as a data type, it can be considered an encoding of
- integers. An empty list encodes zero, a singleton \code{{[}(){]}} (a
- value, not a type) encodes one, and so on. Construct another
- representation of this data type using the Yoneda lemma for the list
- functor.
+ \item
+ A discrete category is one that has objects but no morphisms other
+ than identity morphisms. How does the Yoneda lemma work for functors
+ from such a category?
+ \item
+ A list of units \code{{[}(){]}} contains no other information but
+ its length. So, as a data type, it can be considered an encoding of
+ integers. An empty list encodes zero, a singleton \code{{[}(){]}} (a
+ value, not a type) encodes one, and so on. Construct another
+ representation of this data type using the Yoneda lemma for the list
+ functor.
\end{enumerate}
\section{Bibliography}
\begin{enumerate}
-\tightlist
-\item
- \urlref{https://www.youtube.com/watch?v=TLMxHB19khE}{Catsters} video.
+ \tightlist
+ \item
+ \urlref{https://www.youtube.com/watch?v=TLMxHB19khE}{Catsters} video.
\end{enumerate}
diff --git a/src/content/2.6/yoneda-embedding.tex b/src/content/2.6/yoneda-embedding.tex
index e369a64..ea7ccc6 100644
--- a/src/content/2.6/yoneda-embedding.tex
+++ b/src/content/2.6/yoneda-embedding.tex
@@ -15,11 +15,11 @@ It's a mapping of objects from category $\cat{C}$ to functors, which are
\emph{objects} in the functor category (see the section about functor
categories in
\hyperref[natural-transformations]{Natural
-Transformations}). Let's use the notation $[\cat{C}, \Set]$ for the
+ Transformations}). Let's use the notation $[\cat{C}, \Set]$ for the
functor category from $\cat{C}$ to $\Set$. You may also recall that
hom-functors are the prototypical
\hyperref[representable-functors]{representable
-functors}.
+ functors}.
Every time we have a mapping of objects between two categories, it's
natural to ask if such a mapping is also a functor. In other words
@@ -41,8 +41,8 @@ and replace the generic $F$ with the hom-functor
$\cat{C}(b, -)$. We get:
\[[\cat{C}, \Set](\cat{C}(a, -), \cat{C}(b, -)) \cong \cat{C}(b, a)\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.6\textwidth]{images/yoneda-embedding.jpg}
+ \centering
+ \includegraphics[width=0.6\textwidth]{images/yoneda-embedding.jpg}
\end{figure}
\noindent
@@ -53,8 +53,8 @@ $\cat{C}(b, a)$ --- that goes in the ``wrong'' direction. But that's
okay; it only means that the functor we are looking at is contravariant.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.65\textwidth]{images/yoneda-embedding-2.jpg}
+ \centering
+ \includegraphics[width=0.65\textwidth]{images/yoneda-embedding-2.jpg}
\end{figure}
\noindent
@@ -105,7 +105,7 @@ hom-set, $\cat{C}(-, a)$. That would give us a contravariant
hom-functor. Contravariant functors from $\cat{C}$ to $\Set$ are
our familiar presheaves (see, for instance,
\hyperref[limits-and-colimits]{Limits
-and Colimits}). The co-Yoneda embedding defines the embedding of a
+ and Colimits}). The co-Yoneda embedding defines the embedding of a
category $\cat{C}$ in the category of presheaves. Its action on morphisms
is given by:
\[[\cat{C}, \Set](\cat{C}(-, a), \cat{C}(-, b)) \cong \cat{C}(a, b)\]
@@ -275,23 +275,23 @@ to go wrong.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Express the co-Yoneda embedding in Haskell.
-\item
- Show that the bijection we established between \code{fromY} and
- \code{btoa} is an isomorphism (the two mappings are the inverse of
- each other).
-\item
- Work out the Yoneda embedding for a monoid. What functor corresponds
- to the monoid's single object? What natural transformations correspond
- to monoid morphisms?
-\item
- What is the application of the \emph{covariant} Yoneda embedding to
- preorders? (Question suggested by Gershom Bazerman.)
-\item
- Yoneda embedding can be used to embed an arbitrary functor category
- $[\cat{C}, \cat{D}]$ in the functor category
- $[[\cat{C}, \cat{D}], \Set]$. Figure out how it works on morphisms
- (which in this case are natural transformations).
+ \tightlist
+ \item
+ Express the co-Yoneda embedding in Haskell.
+ \item
+ Show that the bijection we established between \code{fromY} and
+ \code{btoa} is an isomorphism (the two mappings are the inverse of
+ each other).
+ \item
+ Work out the Yoneda embedding for a monoid. What functor corresponds
+ to the monoid's single object? What natural transformations correspond
+ to monoid morphisms?
+ \item
+ What is the application of the \emph{covariant} Yoneda embedding to
+ preorders? (Question suggested by Gershom Bazerman.)
+ \item
+ Yoneda embedding can be used to embed an arbitrary functor category
+ $[\cat{C}, \cat{D}]$ in the functor category
+ $[[\cat{C}, \cat{D}], \Set]$. Figure out how it works on morphisms
+ (which in this case are natural transformations).
\end{enumerate}
\ No newline at end of file
diff --git a/src/content/3.1/its-all-about-morphisms.tex b/src/content/3.1/its-all-about-morphisms.tex
index 53bdc04..1f49b26 100644
--- a/src/content/3.1/its-all-about-morphisms.tex
+++ b/src/content/3.1/its-all-about-morphisms.tex
@@ -38,8 +38,8 @@ $c$, together with a pair of morphisms $p$ and $q$,
that has the universal property of being their product.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/productranking.jpg}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/productranking.jpg}
\end{figure}
\noindent
@@ -59,8 +59,8 @@ functors $F$ and $G$. The other sides are the components
of the natural transformation (which are also morphisms).
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/3_naturality.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/3_naturality.jpg}
\end{figure}
\noindent
@@ -77,8 +77,8 @@ transformation maps one such sheet corresponding to F, to another,
corresponding to G.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/sheets.png}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/sheets.png}
\end{figure}
\noindent
@@ -204,15 +204,15 @@ empty. We can visualize a general category as a ``thick'' preorder.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Consider some degenerate cases of a naturality condition and draw the
- appropriate diagrams. For instance, what happens if either functor
- $F$ or $G$ map both objects $a$ and $b$
- (the ends of $f \Colon a \to b$) to the same
- object, e.g., $F a = F b$ or $G a = G b$?
- (Notice that you get a cone or a co-cone this way.) Then consider
- cases where either $F a = G a$ or $F b = G b$.
- Finally, what if you start with a morphism that loops on itself ---
- $f \Colon a \to a$?
+ \tightlist
+ \item
+ Consider some degenerate cases of a naturality condition and draw the
+ appropriate diagrams. For instance, what happens if either functor
+ $F$ or $G$ map both objects $a$ and $b$
+ (the ends of $f \Colon a \to b$) to the same
+ object, e.g., $F a = F b$ or $G a = G b$?
+ (Notice that you get a cone or a co-cone this way.) Then consider
+ cases where either $F a = G a$ or $F b = G b$.
+ Finally, what if you start with a morphism that loops on itself ---
+ $f \Colon a \to a$?
\end{enumerate}
\ No newline at end of file
diff --git a/src/content/3.10/ends-and-coends.tex b/src/content/3.10/ends-and-coends.tex
index 7b7a2f4..2747cf4 100644
--- a/src/content/3.10/ends-and-coends.tex
+++ b/src/content/3.10/ends-and-coends.tex
@@ -77,8 +77,8 @@ family of morphisms:
for which the following diagram commutes, for any $f \Colon a \to b$:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/end.jpg}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/end.jpg}
\end{figure}
\noindent
@@ -89,8 +89,8 @@ from two naturality squares and one functoriality condition (profunctor
$q$ preserving composition):
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/end-1.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/end-1.jpg}
\end{figure}
\noindent
@@ -126,8 +126,8 @@ $p\ a\ b$. We therefore insist that the following diagram
commute:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/end-2.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/end-2.jpg}
\end{figure}
\noindent
@@ -144,8 +144,8 @@ $h \Colon a \to e$ that makes all triangles commute:
\[\pi_a \circ h = \alpha_a\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/end-21.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/end-21.jpg}
\end{figure}
\noindent
@@ -245,8 +245,8 @@ is a profunctor, so it makes sense to study its end. This is the wedge
condition:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/end1.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/end1.jpg}
\end{figure}
\noindent
@@ -254,8 +254,8 @@ Let's just pick one element from the set $\int_c \cat{C}(F\ c, G\ c)$.
The two projections will map this element to two components of a
particular transformation, let's call them:
\begin{align*}
-\tau_a &\Colon F\ a \to G\ a \\
-\tau_b &\Colon F\ b \to G\ b
+ \tau_a & \Colon F\ a \to G\ a \\
+ \tau_b & \Colon F\ b \to G\ b
\end{align*}
In the left branch, we lift a pair of morphisms
$\langle \idarrow[a], G\ f \rangle$ using the hom-functor. You
@@ -273,9 +273,9 @@ from a dual to a wedge called a cowedge (pronounced co-wedge, not
cow-edge).
\begin{figure}[H]
-\centering
-\includegraphics[width=0.25\textwidth]{images/end-31.jpg}
-\caption{An edgy cow?}
+ \centering
+ \includegraphics[width=0.25\textwidth]{images/end-31.jpg}
+ \caption{An edgy cow?}
\end{figure}
\noindent
@@ -336,9 +336,9 @@ known as taking a quotient. To define a quotient we need an
\newterm{equivalence relation} $\sim$, a relation that
is reflexive, symmetric, and transitive:
\begin{align*}
-&a \sim a \\
-&\text{if}\ a \sim b\ \text{then}\ b \sim a \\
-&\text{if}\ a \sim b\ \text{and}\ b \sim c\ \text{then}\ a \sim c
+ & a \sim a \\
+ & \text{if}\ a \sim b\ \text{then}\ b \sim a \\
+ & \text{if}\ a \sim b\ \text{and}\ b \sim c\ \text{then}\ a \sim c
\end{align*}
Such a relation splits the set into equivalence classes. Each class
consists of elements that are related to each other. We form a quotient
@@ -405,7 +405,7 @@ exponential:
\[\int_z \Set(\cat{C}(z, a), c^{(F\ z)})\]
We can ``perform the integration'' by using the Yoneda lemma to get:
\[c^{(F\ a)}\]
-(Notice that we used the contravariant version of the Yoneda lemma,
+(Notice that we used the contravariant version of the Yoneda lemma,
since the functor $c^{(F z)}$ is contravariant in $z$.)
This exponential object is isomorphic to the hom-set:
\[\Set(F\ a, c)\]
diff --git a/src/content/3.11/kan-extensions.tex b/src/content/3.11/kan-extensions.tex
index 26ab55d..7d54935 100644
--- a/src/content/3.11/kan-extensions.tex
+++ b/src/content/3.11/kan-extensions.tex
@@ -16,8 +16,8 @@ category $\cat{I}$ to $\cat{C}$. This is the functor that selects the base
of the cone --- the diagram functor.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan2.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan2.jpg}
\end{figure}
\noindent
@@ -29,8 +29,8 @@ morphism. Any functor $F$ from $\cat{1}$ to $\cat{C}$ picks a
potential apex for our cone.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan15.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan15.jpg}
\end{figure}
\noindent
@@ -40,8 +40,8 @@ our original $\Delta_c$. The following diagram shows this
transformation.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan3-e1492120491591.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan3-e1492120491591.jpg}
\end{figure}
\noindent
@@ -59,8 +59,8 @@ transformation $\varepsilon'$ from $F' \circ K$ to
$D$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan31-e1492120512209.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan31-e1492120512209.jpg}
\end{figure}
\noindent
@@ -74,8 +74,8 @@ on $K$). This transformation is then vertically composed with
$\varepsilon$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan5.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan5.jpg}
\end{figure}
\noindent
@@ -108,8 +108,8 @@ that factorizes $\varepsilon'$:
This is quite a mouthful, but it can be visualized in this nice diagram:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan7.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan7.jpg}
\end{figure}
\noindent
@@ -133,8 +133,8 @@ just half of it, namely a one-way natural transformation $\varepsilon$ from
$F \circ K$ to $D$. (The left Kan extension picks the other direction.)
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan6.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan6.jpg}
\end{figure}
\noindent
@@ -158,8 +158,8 @@ transformation we called $\varepsilon'$ corresponds a unique natural
transformation we called $\sigma$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan92.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan92.jpg}
\end{figure}
\noindent
@@ -205,8 +205,8 @@ cocone by using the functor $D \Colon \cat{I} \to \cat{C}$ to form its
base, and the functor $F \Colon \cat{1} \to \cat{C}$ to select its apex.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan81.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan81.jpg}
\end{figure}
\noindent
@@ -214,8 +214,8 @@ The sides of the cocone, the injections, are components of a natural
transformation $\eta$ from $D$ to $F \circ K$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan10a.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan10a.jpg}
\end{figure}
\noindent
@@ -224,16 +224,16 @@ $F'$ and a natural transformation
\[\eta' \Colon D \to F' \circ K\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan10b.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan10b.jpg}
\end{figure}
\noindent
there is a unique natural transformation $\sigma$ from $F$ to $F'$
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan14.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan14.jpg}
\end{figure}
\noindent
@@ -242,8 +242,8 @@ such that:
This is illustrated in the following diagram:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan112.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan112.jpg}
\end{figure}
\noindent
@@ -252,8 +252,8 @@ definition naturally generalized to the definition of the left Kan
extension, denoted by $\Lan_{K}D$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan12.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan12.jpg}
\end{figure}
\noindent
@@ -300,8 +300,8 @@ hom-functor:
\[\cat{A}(a, K\ -)\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/kan13.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/kan13.jpg}
\end{figure}
\noindent
@@ -423,15 +423,15 @@ Notice that, as described earlier in the general case, we performed the
following steps:
\begin{enumerate}
-\tightlist
-\item
-Retrieved the container of \code{x} (here, it's
-just a trivial identity container), and the function \code{f}.
-\item
-Repackaged the container using the natural transformation between the
-identity functor and the pair functor.
-\item
-Called the function \code{f}.
+ \tightlist
+ \item
+ Retrieved the container of \code{x} (here, it's
+ just a trivial identity container), and the function \code{f}.
+ \item
+ Repackaged the container using the natural transformation between the
+ identity functor and the pair functor.
+ \item
+ Called the function \code{f}.
\end{enumerate}
\section{Free Functor}
@@ -469,7 +469,7 @@ recording both the function and its argument. It accumulates the lifted
functions by recording their composition. Functor rules are
automatically satisfied. This construction was used in a paper
\urlref{http://okmij.org/ftp/Haskell/extensible/more.pdf}{Freer Monads,
-More Extensible Effects}.
+ More Extensible Effects}.
Alternatively, we can use the right Kan extension for the same purpose:
diff --git a/src/content/3.12/enriched-categories.tex b/src/content/3.12/enriched-categories.tex
index 758984c..38a3794 100644
--- a/src/content/3.12/enriched-categories.tex
+++ b/src/content/3.12/enriched-categories.tex
@@ -84,37 +84,37 @@ that serves as the unit of the tensor product; again, up to natural
isomorphism. The two isomorphisms are called, respectively, the left and
the right unitor, and their components are:
\begin{align*}
-\lambda_a &\Colon i \otimes a \to a \\
-\rho_a &\Colon a \otimes i \to a
+ \lambda_a & \Colon i \otimes a \to a \\
+ \rho_a & \Colon a \otimes i \to a
\end{align*}
The associator and the unitors must satisfy coherence conditions:
\begin{figure}[H]
-\centering
-\begin{tikzcd}[row sep=large]
-((a \otimes b) \otimes c) \otimes d
-\arrow[d, "\alpha_{(a \otimes b)cd}"]
-\arrow[rr, "\alpha_{abc} \otimes \id_d"]
- & & (a \otimes (b \otimes c)) \otimes d
- \arrow[d, "\alpha_{a(b \otimes c)d}"] \\
-(a \otimes b) \otimes (c \otimes d)
-\arrow[rd, "\alpha_{ab(c \otimes d)}"]
- & & a \otimes ((b \otimes c) \otimes d)
- \arrow[ld, "\id_a \otimes \alpha_{bcd}"] \\
- & a \otimes (b \otimes (c \otimes d))
-\end{tikzcd}
+ \centering
+ \begin{tikzcd}[row sep=large]
+ ((a \otimes b) \otimes c) \otimes d
+ \arrow[d, "\alpha_{(a \otimes b)cd}"]
+ \arrow[rr, "\alpha_{abc} \otimes \id_d"]
+ & & (a \otimes (b \otimes c)) \otimes d
+ \arrow[d, "\alpha_{a(b \otimes c)d}"] \\
+ (a \otimes b) \otimes (c \otimes d)
+ \arrow[rd, "\alpha_{ab(c \otimes d)}"]
+ & & a \otimes ((b \otimes c) \otimes d)
+ \arrow[ld, "\id_a \otimes \alpha_{bcd}"] \\
+ & a \otimes (b \otimes (c \otimes d))
+ \end{tikzcd}
\end{figure}
\begin{figure}[H]
-\centering
-\begin{tikzcd}[row sep=large]
-(a \otimes i) \otimes b
-\arrow[dr, "\rho_{a} \otimes \id_b"']
-\arrow[rr, "\alpha_{aib}"]
- & & a \otimes (i \otimes b)
- \arrow[dl, "\id_a \otimes \lambda_b"] \\
- & a \otimes b
-\end{tikzcd}
+ \centering
+ \begin{tikzcd}[row sep=large]
+ (a \otimes i) \otimes b
+ \arrow[dr, "\rho_{a} \otimes \id_b"']
+ \arrow[rr, "\alpha_{aib}"]
+ & & a \otimes (i \otimes b)
+ \arrow[dl, "\id_a \otimes \lambda_b"] \\
+ & a \otimes b
+ \end{tikzcd}
\end{figure}
\noindent
@@ -135,7 +135,7 @@ that defines the internal hom in a monoidal category:
\[\cat{V}(a \otimes b, c) \sim \cat{V}(a, [b, c])\]
Following
\urlref{http://www.tac.mta.ca/tac/reprints/articles/10/tr10.pdf}{G. M.
-Kelly}, I'm using the notation ${[}b, c{]}$ for the internal
+ Kelly}, I'm using the notation ${[}b, c{]}$ for the internal
hom. The counit of this adjunction is the natural transformation whose
components are called evaluation morphisms:
\[\varepsilon_{a b} \Colon ([a, b] \otimes a) \to b\]
@@ -164,8 +164,8 @@ of morphisms is replaced by a family of morphisms in $\cat{V}$:
\[\circ \Colon \cat{C}(b, c) \otimes \cat{C}(a, b) \to \cat{C}(a, c)\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.45\textwidth]{images/composition.jpg}
+ \centering
+ \includegraphics[width=0.45\textwidth]{images/composition.jpg}
\end{figure}
\noindent
@@ -175,8 +175,8 @@ $\cat{V}$:
where $i$ is the tensor unit in $\cat{V}$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/id.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/id.jpg}
\end{figure}
\noindent
@@ -184,19 +184,19 @@ Associativity of composition is defined in terms of the associator in
$\cat{V}$:
\begin{figure}[H]
-\centering
-\begin{tikzcd}[column sep=large]
-(\cat{C}(c,d) \otimes \cat{C}(b,c)) \otimes \cat{C}(a,b)
-\arrow[r, "\circ\otimes\id"]
-\arrow[dd, "\alpha"]
- & \cat{C}(b,d) \otimes \cat{C}(a,b)
+ \centering
+ \begin{tikzcd}[column sep=large]
+ (\cat{C}(c,d) \otimes \cat{C}(b,c)) \otimes \cat{C}(a,b)
+ \arrow[r, "\circ\otimes\id"]
+ \arrow[dd, "\alpha"]
+ & \cat{C}(b,d) \otimes \cat{C}(a,b)
\arrow[dr, "\circ"] \\
- & & \cat{C}(a,d) \\
-\cat{C}(c,d) \otimes (\cat{C}(b,c) \otimes \cat{C}(a,b))
-\arrow[r, "\id\otimes\circ"]
- & \cat{C}(c,d) \otimes \cat{C}(a,c)
+ & & \cat{C}(a,d) \\
+ \cat{C}(c,d) \otimes (\cat{C}(b,c) \otimes \cat{C}(a,b))
+ \arrow[r, "\id\otimes\circ"]
+ & \cat{C}(c,d) \otimes \cat{C}(a,c)
\arrow[ur, "\circ"]
-\end{tikzcd}
+ \end{tikzcd}
\end{figure}
\noindent
@@ -210,9 +210,9 @@ Unit laws are likewise expressed in terms of unitors:
\cat{C}(a,b) \otimes i
\arrow[rr, "\id \otimes j_a"]
\arrow[dr, "\rho"]
- & & \cat{C}(a,b) \otimes \cat{C}(a,a)
- \arrow[dl, "\circ"] \\
- & \cat{C}(a,b)
+ & & \cat{C}(a,b) \otimes \cat{C}(a,a)
+ \arrow[dl, "\circ"] \\
+ & \cat{C}(a,b)
\end{tikzcd}
\end{subfigure}
\hspace{1cm}
@@ -222,9 +222,9 @@ Unit laws are likewise expressed in terms of unitors:
i \otimes \cat{C}(a,b)
\arrow[rr, "j_b \otimes \id"]
\arrow[dr, "\lambda"]
- & & \cat{C}(b,b) \otimes \cat{C}(a,b)
- \arrow[dl, "\circ"] \\
- & \cat{C}(a,b)
+ & & \cat{C}(b,b) \otimes \cat{C}(a,b)
+ \arrow[dl, "\circ"] \\
+ & \cat{C}(a,b)
\end{tikzcd}
\end{subfigure}
\end{figure}
@@ -271,7 +271,7 @@ enforced, if we implement a preorder as an enriched category.
An interesting example is due to
\urlref{http://www.tac.mta.ca/tac/reprints/articles/1/tr1.pdf}{William
-Lawvere}. He noticed that metric spaces can be defined using enriched
+ Lawvere}. He noticed that metric spaces can be defined using enriched
categories. A metric space defines a distance between any two objects.
This distance is a non-negative real number. It's convenient to include
infinity as a possible value. If the distance is infinite, there is no
@@ -344,17 +344,17 @@ meant preserving composition and identity. In the enriched setting, the
preservation of composition means that the following diagram commute:
\begin{figure}[H]
-\centering
-\begin{tikzcd}[column sep=large, row sep=large]
- \cat{C}(b,c) \otimes \cat{C}(a,b)
- \arrow[r, "\circ"]
- \arrow[d, "F_{bc} \otimes F_{ab}"]
+ \centering
+ \begin{tikzcd}[column sep=large, row sep=large]
+ \cat{C}(b,c) \otimes \cat{C}(a,b)
+ \arrow[r, "\circ"]
+ \arrow[d, "F_{bc} \otimes F_{ab}"]
& \cat{C}(a,c)
- \arrow[d, "F_{ac}"] \\
- \cat{D}(F\ b, F\ c) \otimes \cat{D}(F\ a, F\ b)
- \arrow[r, "\circ"]
+ \arrow[d, "F_{ac}"] \\
+ \cat{D}(F\ b, F\ c) \otimes \cat{D}(F\ a, F\ b)
+ \arrow[r, "\circ"]
& \cat{D}(F\ a, F\ c)
-\end{tikzcd}
+ \end{tikzcd}
\end{figure}
\noindent
@@ -362,13 +362,13 @@ The preservation of identity is replaced by the preservation of the
morphisms in $\cat{V}$ that ``select'' the identity:
\begin{figure}[H]
-\centering
-\begin{tikzcd}[row sep=large]
+ \centering
+ \begin{tikzcd}[row sep=large]
& i \arrow[dl, "j_a"'] \arrow[dr, "j_{F a}"] & \\
- \cat{C}(a,a)
- \arrow[rr, "F_{aa}"]
+ \cat{C}(a,a)
+ \arrow[rr, "F_{aa}"]
& & \cat{D}(F\ a, F\ a)
-\end{tikzcd}
+ \end{tikzcd}
\end{figure}
\section{Self Enrichment}
diff --git a/src/content/3.13/topoi.tex b/src/content/3.13/topoi.tex
index 9659392..78e5f56 100644
--- a/src/content/3.13/topoi.tex
+++ b/src/content/3.13/topoi.tex
@@ -52,8 +52,8 @@ to be isomorphic to $a$. We can use this fact to define a subset
as a family of injective functions that are related by isomorphisms of
their domains. More precisely, we say that two injective functions:
\begin{align*}
-f &\Colon a \to b \\
-f' &\Colon a' \to b
+ f & \Colon a \to b \\
+ f' & \Colon a' \to b
\end{align*}
are equivalent if there is an isomorphism:
\[h \Colon a \to a'\]
@@ -62,8 +62,8 @@ such that:
Such a family of equivalent injections defines a subset of $b$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/subsetinjection.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/subsetinjection.jpg}
\end{figure}
\noindent
@@ -72,16 +72,16 @@ injective functions with monomorphism. Just to remind you, a
monomorphism $m$ from $a$ to $b$ is defined by its
universal property. For any object $c$ and any pair of morphisms:
\begin{align*}
-g &\Colon c \to a \\
-g' &\Colon c \to a
+ g & \Colon c \to a \\
+ g' & \Colon c \to a
\end{align*}
such that:
\[m\ .\ g = m\ .\ g'\]
it must be that $g = g'$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/monomorphism.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/monomorphism.jpg}
\end{figure}
\noindent
@@ -93,8 +93,8 @@ $g'$ that differ only at those two elements. The
postcomposition with $m$ would then mask this difference.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/notmono.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/notmono.jpg}
\end{figure}
\noindent
@@ -112,8 +112,8 @@ $true$:
\[true \Colon 1 \to \Omega\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/true.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/true.jpg}
\end{figure}
\noindent
@@ -136,8 +136,8 @@ and the injective function that embeds it in $b$. Here's the
pullback diagram:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/pullback.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/pullback.jpg}
\end{figure}
\noindent
@@ -197,14 +197,14 @@ representation is the object $\Omega$.
A topos is a category that:
\begin{enumerate}
-\tightlist
-\item
- Is Cartesian closed: It has all products, the terminal object, and
- exponentials (defined as right adjoints to products),
-\item
- Has limits for all finite diagrams,
-\item
- Has a subobject classifier $\Omega$.
+ \tightlist
+ \item
+ Is Cartesian closed: It has all products, the terminal object, and
+ exponentials (defined as right adjoints to products),
+ \item
+ Has limits for all finite diagrams,
+ \item
+ Has a subobject classifier $\Omega$.
\end{enumerate}
This set of properties makes a topos a shoe-in for $\Set$ in most
@@ -251,8 +251,8 @@ logics.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Show that the function $f$ that is the pullback of
- $true$ along the characteristic function must be injective.
+ \tightlist
+ \item
+ Show that the function $f$ that is the pullback of
+ $true$ along the characteristic function must be injective.
\end{enumerate}
diff --git a/src/content/3.14/lawvere-theories.tex b/src/content/3.14/lawvere-theories.tex
index 4e8f0ed..8b6112a 100644
--- a/src/content/3.14/lawvere-theories.tex
+++ b/src/content/3.14/lawvere-theories.tex
@@ -52,23 +52,23 @@ The derivation of Lawvere theories goes through many steps, so here's
the roadmap:
\begin{enumerate}
-\tightlist
-\item
- Category of finite sets $\cat{FinSet}$.
-\item
- Its skeleton $\cat{F}$.
-\item
- Its opposite $\Fop$.
-\item
- Lawvere theory $\cat{L}$: an object in the category $\cat{Law}$.
-\item
- Model $M$ of a Lawvere category: an object in the category\\
- $\cat{Mod}(\cat{Law}, \Set)$.
+ \tightlist
+ \item
+ Category of finite sets $\cat{FinSet}$.
+ \item
+ Its skeleton $\cat{F}$.
+ \item
+ Its opposite $\Fop$.
+ \item
+ Lawvere theory $\cat{L}$: an object in the category $\cat{Law}$.
+ \item
+ Model $M$ of a Lawvere category: an object in the category\\
+ $\cat{Mod}(\cat{Law}, \Set)$.
\end{enumerate}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.8\textwidth]{images/lawvere1.png}
+ \centering
+ \includegraphics[width=0.8\textwidth]{images/lawvere1.png}
\end{figure}
\section{Lawvere Theories}
@@ -112,7 +112,7 @@ corresponding to all $n$-element sets in $\cat{FinSet}$ that have been
identified through isomorphisms.
Using the category $\cat{F}$ we can formally define a \newterm{Lawvere
-theory} as a category $\cat{L}$ equipped with a special functor:
+ theory} as a category $\cat{L}$ equipped with a special functor:
\[I_{\cat{L}} \Colon \Fop \to \cat{L}\]
This functor must be a bijection on objects and it must preserve finite
products (products in $\Fop$ are the same as
@@ -162,12 +162,12 @@ functions (or, as we've seen earlier, that the hom-functor is
continuous).
\begin{figure}[H]
-\centering
-\includegraphics[width=0.8\textwidth]{images/lawvere1.png}
-\caption{Lawvere theory $\cat{L}$ is based on $\Fop$, from which
-it inherits the ``boring'' morphisms that define the products. It adds
-the ``interesting'' morphisms that describe the $n$-ary operations (dotted
-arrows).}
+ \centering
+ \includegraphics[width=0.8\textwidth]{images/lawvere1.png}
+ \caption{Lawvere theory $\cat{L}$ is based on $\Fop$, from which
+ it inherits the ``boring'' morphisms that define the products. It adds
+ the ``interesting'' morphisms that describe the $n$-ary operations (dotted
+ arrows).}
\end{figure}
Lawvere theories form a category $\cat{Law}$, in which morphisms are
@@ -176,8 +176,8 @@ $I$. Given two such theories, $(\cat{L}, I_{\cat{L}})$ and
$(\cat{L'}, I'_{\cat{L'}})$, a morphism between them is a
functor $F \Colon \cat{L} \to \cat{L'}$ such that:
\begin{gather*}
-F\ (m \times n) = F\ m \times F\ n \\
-F \circ I_{\cat{L}} = I'_{\cat{L'}}
+ F\ (m \times n) = F\ m \times F\ n \\
+ F \circ I_{\cat{L}} = I'_{\cat{L'}}
\end{gather*}
Morphisms between Lawvere theories encapsulate the idea of the
interpretation of one theory inside another. For instance, group
@@ -208,11 +208,11 @@ products, we require that such a functor preserve finite products. A
model of $\cat{L}$, also called the algebra over the Lawvere theory
$\cat{L}$, is therefore defined by a functor:
\begin{gather*}
-M \Colon \cat{L} \to \Set \\
-M\ (a \times b) \cong M\ a \times M\ b
+ M \Colon \cat{L} \to \Set \\
+ M\ (a \times b) \cong M\ a \times M\ b
\end{gather*}
Notice that we require the preservation of products only \emph{up to
-isomorphism}. This is very important, because strict preservation of
+ isomorphism}. This is very important, because strict preservation of
products would eliminate most interesting theories.
The preservation of products by models means that the image of
@@ -269,7 +269,7 @@ structure of monoids. It is a single theory that distills the structure
of all possible monoids, in the sense that the models of this theory
span the whole category $\cat{Mon}$ of monoids. We've already seen a
\hyperref[free-monoids]{universal
-construction}, which showed that every monoid can be obtained from an
+ construction}, which showed that every monoid can be obtained from an
appropriate free monoid by identifying a subset of morphisms. So a
single free monoid already generalizes a whole lot of monoids. There
are, however, infinitely many free monoids. The Lawvere theory for
@@ -320,7 +320,7 @@ $\cat{Mon}$.
As you may remember, algebraic theories can be described using monads
--- in particular
\hyperref[algebras-for-monads]{algebras
-for monads}. It should be no surprise then that there is a connection
+ for monads}. It should be no surprise then that there is a connection
between Lawvere theories and monads.
First, let's see how a Lawvere theory induces a monad. It does it
@@ -366,7 +366,7 @@ a monad.
It turns out that the category of
\hyperref[algebras-for-monads]{algebras
-for this monad} is equivalent to the category of models.
+ for this monad} is equivalent to the category of models.
You may recall that monad algebras define ways to evaluate expressions
that are formed using monads. A Lawvere theory defines n-ary operations
@@ -428,8 +428,8 @@ The lifting simply selects $m$ elements from a tuple of $n$ elements\\
$(a_1, a_2,...a_n)$ (possibly with repetitions).
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/liftpower.png}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/liftpower.png}
\end{figure}
\noindent
@@ -462,11 +462,11 @@ morphism with $\cat{L}(m, 1)$ gives us a subset of
$\cat{L}(n, 1)$.
\begin{figure}[H]
-\centering
-\begin{tikzcd}[column sep=large]
-\cat{L}(m, 1) \arrow[r] & \cat{L}(n, 1)\\
-{}^m \bullet \arrow[r, "f"'] & \bullet^n
-\end{tikzcd}
+ \centering
+ \begin{tikzcd}[column sep=large]
+ \cat{L}(m, 1) \arrow[r] & \cat{L}(n, 1)\\
+ {}^m \bullet \arrow[r, "f"'] & \bullet^n
+ \end{tikzcd}
\end{figure}
\noindent
@@ -485,24 +485,24 @@ Here, the coend starts as the disjoint sum of sets
$a^n \times \cat{L}(n, 1)$ over all $n$s. The identifications can
be generated by expressing the
\hyperref[ends-and-coends]{coend as
-a coequalizer}. We start with an off-diagonal term
+ a coequalizer}. We start with an off-diagonal term
$a^n \times \cat{L}(m, 1)$. To get to the diagonal, we can apply a
morphism $f \Colon m \to n$ either to the first or
the second component of the product. The two results are then
identified.
\begin{figure}[H]
-\centering
-\begin{tikzcd}
- & a^n \times \cat{L}(m, 1)
+ \centering
+ \begin{tikzcd}
+ & a^n \times \cat{L}(m, 1)
\arrow[dl, "\langle f {,} \id \rangle"']
\arrow[dr, "\langle \id {,} f \rangle"]
& \\
-a^m \times \cat{L}(m, 1)
- & \scalebox{2.5}[1]{\sim}
+ a^m \times \cat{L}(m, 1)
+ & \scalebox{2.5}[1]{\sim}
& a^n \times \cat{L}(n, 1) \\
& f \Colon m \to n &
-\end{tikzcd}
+ \end{tikzcd}
\end{figure}
\noindent
@@ -575,17 +575,17 @@ the coend formula, because they can be obtained from:
by lifting $0 \to n$ in two different ways.
\begin{figure}[H]
-\centering
-\begin{tikzcd}
- & a^n \times \cat{L}(0, 1)
+ \centering
+ \begin{tikzcd}
+ & a^n \times \cat{L}(0, 1)
\arrow[dl, "\langle f {,} \id \rangle"']
\arrow[dr, "\langle \id {,} f \rangle"]
& \\
-a^0 \times \cat{L}(0, 1)
- & \scalebox{2.5}[1]{\sim}
+ a^0 \times \cat{L}(0, 1)
+ & \scalebox{2.5}[1]{\sim}
& a^n \times \cat{L}(n, 1) \\
& f \Colon 0 \to n &
-\end{tikzcd}
+ \end{tikzcd}
\end{figure}
\noindent
@@ -603,29 +603,29 @@ not their handling.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Enumerate all morphisms between $2$ and $3$ in $\cat{F}$ (the skeleton of
- $\cat{FinSet}$).
-\item
- Show that the category of models for the Lawvere theory of monoids is
- equivalent to the category of monad algebras for the list monad.
-\item
- The Lawvere theory of monoids generates the list monad. Show that its
- binary operations can be generated using the corresponding Kleisli
- arrows.
-\item
- \textbf{FinSet} is a subcategory of $\Set$ and there is a
- functor that embeds it in $\Set$. Any functor on $\Set$
- can be restricted to $\cat{FinSet}$. Show that a finitary functor is
- the left Kan extension of its own restriction.
+ \tightlist
+ \item
+ Enumerate all morphisms between $2$ and $3$ in $\cat{F}$ (the skeleton of
+ $\cat{FinSet}$).
+ \item
+ Show that the category of models for the Lawvere theory of monoids is
+ equivalent to the category of monad algebras for the list monad.
+ \item
+ The Lawvere theory of monoids generates the list monad. Show that its
+ binary operations can be generated using the corresponding Kleisli
+ arrows.
+ \item
+ \textbf{FinSet} is a subcategory of $\Set$ and there is a
+ functor that embeds it in $\Set$. Any functor on $\Set$
+ can be restricted to $\cat{FinSet}$. Show that a finitary functor is
+ the left Kan extension of its own restriction.
\end{enumerate}
\section{Further Reading}
\begin{enumerate}
\tightlist
\item
- \urlref{http://www.tac.mta.ca/tac/reprints/articles/5/tr5.pdf}{Functorial Semantics of Algebraic Theories}, F. William Lawvere
+ \urlref{http://www.tac.mta.ca/tac/reprints/articles/5/tr5.pdf}{Functorial Semantics of Algebraic Theories}, F. William Lawvere
\item
- \urlref{http://homepages.inf.ed.ac.uk/gdp/publications/Comp_Eff_Monads.pdf}{Notions of computation determine monads}, Gordon Plotkin and John Power
+ \urlref{http://homepages.inf.ed.ac.uk/gdp/publications/Comp_Eff_Monads.pdf}{Notions of computation determine monads}, Gordon Plotkin and John Power
\end{enumerate}
diff --git a/src/content/3.15/monads-monoids-and-categories.tex b/src/content/3.15/monads-monoids-and-categories.tex
index b87a16f..688af14 100644
--- a/src/content/3.15/monads-monoids-and-categories.tex
+++ b/src/content/3.15/monads-monoids-and-categories.tex
@@ -47,9 +47,9 @@ are called $0$-cells, morphisms are $1$-cells, and morphisms between
morphisms are $2$-cells.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/twocat.png}
-\caption{$0$-cells $a, b$; $1$-cells $f, g$; and a $2$-cell $\alpha$.}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/twocat.png}
+ \caption{$0$-cells $a, b$; $1$-cells $f, g$; and a $2$-cell $\alpha$.}
\end{figure}
\noindent
@@ -99,10 +99,10 @@ words, there is a $2$-cell:
that has an inverse.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/bicat.png}
-\caption{Identity law in a bicategory holds up to isomorphism (an invertible
-$2$-cell $\rho$).}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/bicat.png}
+ \caption{Identity law in a bicategory holds up to isomorphism (an invertible
+ $2$-cell $\rho$).}
\end{figure}
\noindent
@@ -117,13 +117,13 @@ An interesting example of a bicategory is the category of spans. A span
between two objects $a$ and $b$ is an object $x$
and a pair of morphisms:
\begin{gather*}
-f \Colon x \to a \\
-g \Colon x \to b
+ f \Colon x \to a \\
+ g \Colon x \to b
\end{gather*}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.35\textwidth]{images/span.png}
+ \centering
+ \includegraphics[width=0.35\textwidth]{images/span.png}
\end{figure}
\noindent
@@ -132,13 +132,13 @@ product. Here, we want to look at spans as $1$-cells in a bicategory. The
first step is to define a composition of spans. Suppose that we have an
adjoining span:
\begin{gather*}
-f' \Colon y \to b \\
-g' \Colon y \to c
+ f' \Colon y \to b \\
+ g' \Colon y \to c
\end{gather*}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/compspan.png}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/compspan.png}
\end{figure}
\noindent
@@ -147,16 +147,16 @@ most natural choice for it is the pullback of $g$ along
$f'$. Remember that a pullback is the object $z$
together with two morphisms:
\begin{align*}
-h &\Colon z \to x \\
-h' &\Colon z \to y
+ h & \Colon z \to x \\
+ h' & \Colon z \to y
\end{align*}
such that:
\[g \circ h = f' \circ h'\]
which is universal among all such objects.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/pullspan.png}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/pullspan.png}
\end{figure}
\noindent
@@ -169,9 +169,9 @@ a morphism $h$ between their apices, such that the appropriate
triangles commute.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/morphspan.png}
-\caption{A $2$-cell in $\cat{Span}$.}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/morphspan.png}
+ \caption{A $2$-cell in $\cat{Span}$.}
\end{figure}
\noindent
@@ -206,8 +206,8 @@ we get:
\[\mu \Colon T \circ T \to T\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/monad.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/monad.png}
\end{figure}
\noindent
@@ -221,14 +221,14 @@ As we've seen earlier, the hom-category $\cat{C}(a, a)$ is a monoidal
category. We can therefore define a monoid in $\cat{C}(a, a)$ by
picking a $1$-cell, $T$, and two $2$-cells:
\begin{align*}
-\eta &\Colon I \to T \\
-\mu &\Colon T \circ T \to T
+ \eta & \Colon I \to T \\
+ \mu & \Colon T \circ T \to T
\end{align*}
satisfying the monoid laws. We call \emph{this} a monad.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/bimonad.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/bimonad.png}
\end{figure}
\noindent
@@ -243,13 +243,13 @@ $Ob$. Next, we pick an endo-$1$-cell: a span from $Ob$ back
to $Ob$. It has a set at the apex, which I will call $Ar$,
equipped with two functions:
\begin{align*}
-dom &\Colon Ar \to Ob \\
-cod &\Colon Ar \to Ob
+ dom & \Colon Ar \to Ob \\
+ cod & \Colon Ar \to Ob
\end{align*}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/spanmonad.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/spanmonad.png}
\end{figure}
\noindent
@@ -266,13 +266,13 @@ $Ob$ and $Ar$. In other words, $\eta$ assigns an
``arrow'' to every ``object.'' A $2$-cell in $\cat{Span}$ must satisfy
commutation conditions --- in this case:
\begin{align*}
-dom &\circ \eta = \id \\
-cod &\circ \eta = \id
+ dom & \circ \eta = \id \\
+ cod & \circ \eta = \id
\end{align*}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/spanunit.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/spanunit.png}
\end{figure}
\noindent
@@ -292,8 +292,8 @@ We say that $a_1$ and $a_2$ are ``composable,'' because the
domain of one is the codomain of the other.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/spanmul.png}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/spanmul.png}
\end{figure}
\noindent
@@ -319,22 +319,22 @@ all of mathematics, this is a very humbling realization.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Derive unit and associativity laws for the tensor product defined as
- composition of endo-$1$-cells in a bicategory.
-\item
- Check that monad laws for a monad in $\cat{Span}$ correspond to
- identity and associativity laws in the resulting category.
-\item
- Show that a monad in $\cat{Prof}$ is an identity-on-objects functor.
-\item
- What's a monad algebra for a monad in $\cat{Span}$?
+ \tightlist
+ \item
+ Derive unit and associativity laws for the tensor product defined as
+ composition of endo-$1$-cells in a bicategory.
+ \item
+ Check that monad laws for a monad in $\cat{Span}$ correspond to
+ identity and associativity laws in the resulting category.
+ \item
+ Show that a monad in $\cat{Prof}$ is an identity-on-objects functor.
+ \item
+ What's a monad algebra for a monad in $\cat{Span}$?
\end{enumerate}
\section{Bibliography}
\begin{enumerate}
\tightlist
\item
- \urlref{https://graphicallinearalgebra.net/2017/04/16/a-monoid-is-a-category-a-category-is-a-monad-a-monad-is-a-monoid/}{Paweł Sobociński’s blog}.
+ \urlref{https://graphicallinearalgebra.net/2017/04/16/a-monoid-is-a-category-a-category-is-a-monad-a-monad-is-a-monoid/}{Paweł Sobociński’s blog}.
\end{enumerate}
diff --git a/src/content/3.2/adjunctions.tex b/src/content/3.2/adjunctions.tex
index e18ef83..0837e6a 100644
--- a/src/content/3.2/adjunctions.tex
+++ b/src/content/3.2/adjunctions.tex
@@ -36,8 +36,8 @@ $L \circ R$; and two possible identity functors: one in $\cat{C}$
and another in $\cat{D}$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/adj-1.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/adj-1.jpg}
\end{figure}
\noindent
@@ -78,20 +78,20 @@ between $L \circ R$ and the identity functor $I_{\cat{C}}$.
Adjunction is even weaker than equivalence, because it doesn't require
that the composition of the two functors be \emph{isomorphic} to the
identity functor. Instead it stipulates the existence of a \newterm{one
-way} natural transformation from $I_{\cat{D}}$ to $R \circ L$, and
+ way} natural transformation from $I_{\cat{D}}$ to $R \circ L$, and
another from $L \circ R$ to $I_{\cat{C}}$. Here are the signatures of
these two natural transformations:
\begin{gather*}
-\eta \Colon I_{\cat{D}} \to R \circ L \\
-\varepsilon \Colon L \circ R \to I_{\cat{C}}
+ \eta \Colon I_{\cat{D}} \to R \circ L \\
+ \varepsilon \Colon L \circ R \to I_{\cat{C}}
\end{gather*}
$\eta$ is called the unit, and $\varepsilon$ the counit of the adjunction.
Notice the asymmetry between these two definitions. In general, we don't
have the two remaining mappings:
\begin{gather*}
-R \circ L \to I_{\cat{D}} \quad\quad\text{not necessarily} \\
-I_{\cat{C}} \to L \circ R \quad\quad\text{not necessarily}
+ R \circ L \to I_{\cat{D}} \quad\quad\text{not necessarily} \\
+ I_{\cat{C}} \to L \circ R \quad\quad\text{not necessarily}
\end{gather*}
Because of this asymmetry, the functor $L$ is called the
\newterm{left adjoint} to the functor $R$, while the functor
@@ -104,8 +104,8 @@ To better understand the adjunction, let's analyze the unit and the
counit in more detail.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/adj-unit.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/adj-unit.jpg}
\end{figure}
\noindent
@@ -123,8 +123,8 @@ $R \circ L$ to pick our target object $d'$. Then we
shoot an arrow --- the morphism $\eta_d$ --- to our target.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/adj-counit.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/adj-counit.jpg}
\end{figure}
\noindent
@@ -144,8 +144,8 @@ identity on $\cat{C}$. That leads to some ``obvious'' consistency
conditions, which make sure that introduction followed by elimination
doesn't change anything:
\begin{gather*}
-L = L \circ I_{\cat{D}} \to L \circ R \circ L \to I_{\cat{C}} \circ L = L \\
-R = I_{\cat{D}} \circ R \to R \circ L \circ R \to R \circ I_{\cat{C}} = R
+ L = L \circ I_{\cat{D}} \to L \circ R \circ L \to I_{\cat{C}} \circ L = L \\
+ R = I_{\cat{D}} \circ R \to R \circ L \circ R \to R \circ I_{\cat{C}} = R
\end{gather*}
These are called triangular identities because they make the following
diagrams commute:
@@ -156,18 +156,18 @@ diagrams commute:
\begin{subfigure}
\centering
\begin{tikzcd}[column sep=large, row sep=large]
- L \arrow[rd, equal] \arrow[r, "L \circ \eta"]
- & L \circ R \circ L \arrow[d, "\epsilon \circ L"] \\
- & L
+ L \arrow[rd, equal] \arrow[r, "L \circ \eta"]
+ & L \circ R \circ L \arrow[d, "\epsilon \circ L"] \\
+ & L
\end{tikzcd}
\end{subfigure}%
\hspace{1cm}
\begin{subfigure}
\centering
\begin{tikzcd}[column sep=large, row sep=large]
- R \arrow[rd, equal] \arrow[r, "\eta \circ R"]
- & R \circ L \circ R \arrow[d, "R \circ \epsilon"] \\
- & R
+ R \arrow[rd, equal] \arrow[r, "\eta \circ R"]
+ & R \circ L \circ R \arrow[d, "R \circ \epsilon"] \\
+ & R
\end{tikzcd}
\end{subfigure}
\end{figure}
@@ -177,8 +177,8 @@ These are diagrams in the functor category: the arrows are natural
transformations, and their composition is the horizontal composition of
natural transformations. In components, these identities become:
\begin{gather*}
-\varepsilon_{L d} \circ L \eta_d = \id_{L d} \\
-R \varepsilon_{c} \circ \eta_{R c} = \id_{R c}
+ \varepsilon_{L d} \circ L \eta_d = \id_{L d} \\
+ R \varepsilon_{c} \circ \eta_{R c} = \id_{R c}
\end{gather*}
We often see unit and counit in Haskell under different names. Unit is
known as \code{return} (or \code{pure}, in the definition of
@@ -254,8 +254,8 @@ objects exists in a category, it can be also defined through an
adjunction.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/adj-homsets.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/adj-homsets.jpg}
\end{figure}
\noindent
@@ -281,14 +281,14 @@ precisely, we have a natural transformation $\varphi$ between the
following two (covariant) functors from $\cat{C}$ to $\Set$. Here's
the action of these functors on objects:
\begin{gather*}
-c \to \cat{C}(L d, c) \\
-c \to \cat{D}(d, R c)
+ c \to \cat{C}(L d, c) \\
+ c \to \cat{D}(d, R c)
\end{gather*}
The other natural transformation, $\psi$, acts between the following
(contravariant) functors:
\begin{gather*}
-d \to \cat{C}(L d, c) \\
-d \to \cat{D}(d, R c)
+ d \to \cat{C}(L d, c) \\
+ d \to \cat{D}(d, R c)
\end{gather*}
Both natural transformations must be invertible.
@@ -345,7 +345,7 @@ as an exercise.
We are now ready to explain why, in Haskell, the right adjoint is
automatically a \hyperref[representable-functors]{representable
-functor}. The reason for this is that, to the first approximation, we
+ functor}. The reason for this is that, to the first approximation, we
can treat the category of Haskell types as the category of sets.
When the right category $\cat{D}$ is $\Set$, the right adjoint
@@ -373,7 +373,7 @@ We have previously introduced several concepts using universal
constructions. Many of those concepts, when defined globally, are easier
to express using adjunctions. The simplest non-trivial example is that
of the product. The gist of the \hyperref[products-and-coproducts]{universal
-construction of the product} is the ability to factorize any
+ construction of the product} is the ability to factorize any
product-like candidate through the universal product.
More precisely, the product of two objects $a$ and $b$ is
@@ -411,8 +411,8 @@ product category $\cat{C}\times{}\cat{C}$. Pairs of morphism from $\cat{C}$ are
morphisms in the product category $\cat{C}\times{}\cat{C}$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/adj-productcat.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/adj-productcat.jpg}
\end{figure}
\noindent
@@ -439,8 +439,8 @@ first hom-set is in the product category $\cat{C}\times{}\cat{C}$, and the secon
in $\cat{C}$. A general morphism in $\cat{C}\times{}\cat{C}$ would be a pair of
morphisms $\langle f, g \rangle$:
\begin{gather*}
-f \Colon c' \to a \\
-g \Colon c'' \to b
+ f \Colon c' \to a \\
+ g \Colon c'' \to b
\end{gather*}
with $c''$ potentially different from
$c'$. But to define a product, we are interested in a
@@ -466,8 +466,8 @@ $a\times{}b$. We recognize this element of the hom-set as the
\[\ldots{} \to (c \to (a, b))\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/adj-product.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/adj-product.jpg}
\end{figure}
\noindent
@@ -517,13 +517,13 @@ for instance:
The exponential $b^a$, or the function object $a \Rightarrow b$, can be
defined using a \hyperref[function-types]{universal
-construction}. This construction, if it exists for all pairs of objects,
+ construction}. This construction, if it exists for all pairs of objects,
can be seen as an adjunction. Again, the trick is to concentrate on the
statement:
\begin{quote}
-For any other object $z$ with a morphism $g \Colon z\times{}a \to b$
-there is a unique morphism $h \Colon z \to (a \Rightarrow b)$
+ For any other object $z$ with a morphism $g \Colon z\times{}a \to b$
+ there is a unique morphism $h \Colon z \to (a \Rightarrow b)$
\end{quote}
This statement establishes a mapping between hom-sets.
@@ -541,13 +541,13 @@ The mapping of hom-sets that underlies this adjunction is best seen by
redrawing the diagram that we used in the universal construction.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/adj-expo.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/adj-expo.jpg}
\end{figure}
\noindent
Notice that the $eval$ morphism\footnote{See ch.9 on \hyperref[function-types]{universal
-construction}.} is nothing else but the counit of
+ construction}.} is nothing else but the counit of
this adjunction:
\[(a \Rightarrow b)\times{}a \to b\]
where:
@@ -560,26 +560,26 @@ a functor has an adjoint, this adjoint is unique up to isomorphism.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Derive the naturality square for $\psi$, the transformation
- between the two (contravariant) functors:
-\begin{gather*}
-a \to \cat{C}(L a, b) \\
-a \to \cat{D}(a, R b)
-\end{gather*}
-\item
- Derive the counit $\varepsilon$ starting from the hom-sets isomorphism in
- the second definition of the adjunction.
-\item
- Complete the proof of equivalence of the two definitions of the
- adjunction.
-\item
- Show that the coproduct can be defined by an adjunction. Start with
- the definition of the factorizer for a coproduct.
-\item
- Show that the coproduct is the left adjoint of the diagonal functor.
-\item
- Define the adjunction between a product and a function object in
- Haskell.
+ \tightlist
+ \item
+ Derive the naturality square for $\psi$, the transformation
+ between the two (contravariant) functors:
+ \begin{gather*}
+ a \to \cat{C}(L a, b) \\
+ a \to \cat{D}(a, R b)
+ \end{gather*}
+ \item
+ Derive the counit $\varepsilon$ starting from the hom-sets isomorphism in
+ the second definition of the adjunction.
+ \item
+ Complete the proof of equivalence of the two definitions of the
+ adjunction.
+ \item
+ Show that the coproduct can be defined by an adjunction. Start with
+ the definition of the factorizer for a coproduct.
+ \item
+ Show that the coproduct is the left adjoint of the diagonal functor.
+ \item
+ Define the adjunction between a product and a function object in
+ Haskell.
\end{enumerate}
diff --git a/src/content/3.3/free-forgetful-adjunctions.tex b/src/content/3.3/free-forgetful-adjunctions.tex
index adb4acf..e0e6b0e 100644
--- a/src/content/3.3/free-forgetful-adjunctions.tex
+++ b/src/content/3.3/free-forgetful-adjunctions.tex
@@ -2,7 +2,7 @@
\lettrine[lhang=0.17]{F}{ree constructions are} a powerful application of adjunctions. A
\newterm{free functor} is defined as the left adjoint to a \newterm{forgetful
-functor}. A forgetful functor is usually a pretty simple functor that
+ functor}. A forgetful functor is usually a pretty simple functor that
forgets some structure. For instance, lots of interesting categories are
built on top of sets. But categorical objects, which abstract those
sets, have no internal structure --- they have no elements. Still, those
@@ -27,12 +27,12 @@ morphism in $\cat{Mon}$.\\
Things to keep in mind:
\begin{itemize}
-\tightlist
-\item
- There may be many monoids that map to the same set, and
-\item
- There are fewer (or at most as many as) monoid morphisms than there
- are functions between their underlying sets.
+ \tightlist
+ \item
+ There may be many monoids that map to the same set, and
+ \item
+ There are fewer (or at most as many as) monoid morphisms than there
+ are functions between their underlying sets.
\end{itemize}
\noindent
@@ -40,40 +40,40 @@ The functor $F$ that's the left adjoint to the forgetful functor
$U$ is the free functor that builds free monoids from their
generator sets. The adjunction follows from the free monoid
universal construction we've discussed before.\footnote{See ch.13 on
-\hyperref[free-monoids]{free monoids}.}
+ \hyperref[free-monoids]{free monoids}.}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.6\textwidth]{images/forgetful.jpg}
-\caption{Monoids $m_1$ and $m_2$ have the same
- underlying set. There are more functions between the underlying sets of
- $m_2$ and $m_3$ than there are morphisms
- between them.}
+ \centering
+ \includegraphics[width=0.6\textwidth]{images/forgetful.jpg}
+ \caption{Monoids $m_1$ and $m_2$ have the same
+ underlying set. There are more functions between the underlying sets of
+ $m_2$ and $m_3$ than there are morphisms
+ between them.}
\end{figure}
-
+
\noindent
In terms of hom-sets, we can write this adjunction as:
\[\cat{Mon}(F x, m) \cong \Set(x, U m)\]
This (natural in $x$ and $m$) isomorphism tells us that:
\begin{itemize}
-\tightlist
-\item
- For every monoid homomorphism between the free monoid $F x$
- generated by $x$ and an arbitrary monoid $m$ there is a
- unique function that embeds the set of generators $x$ in the
- underlying set of $m$. It's a function in
- $\Set(x, U m)$.
-\item
- For every function that embeds $x$ in the underlying set of
- some $m$ there is a unique monoid morphism between the free
- monoid generated by $x$ and the monoid $m$. (This is the
- morphism we called $h$ in our universal construction.)
+ \tightlist
+ \item
+ For every monoid homomorphism between the free monoid $F x$
+ generated by $x$ and an arbitrary monoid $m$ there is a
+ unique function that embeds the set of generators $x$ in the
+ underlying set of $m$. It's a function in
+ $\Set(x, U m)$.
+ \item
+ For every function that embeds $x$ in the underlying set of
+ some $m$ there is a unique monoid morphism between the free
+ monoid generated by $x$ and the monoid $m$. (This is the
+ morphism we called $h$ in our universal construction.)
\end{itemize}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.8\textwidth]{images/freemonadjunction.jpg}
+ \centering
+ \includegraphics[width=0.8\textwidth]{images/freemonadjunction.jpg}
\end{figure}
\noindent
@@ -90,7 +90,7 @@ versa.
In Haskell, the list data structure is a free monoid (with some caveats:
see \urlref{http://comonad.com/reader/2015/free-monoids-in-haskell/}{Dan
-Doel's blog post}). A list type \code{{[}a{]}} is a free monoid with
+ Doel's blog post}). A list type \code{{[}a{]}} is a free monoid with
the type \code{a} representing the set of generators. For instance,
the type \code{{[}Char{]}} contains the unit element --- the empty
list \code{{[}{]}} --- and the singletons like
@@ -174,8 +174,8 @@ $\cat{C}(c', c)$ have to preserve the additional structure,
whereas the ones in $\cat{D}(U c', U c)$ don't.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.45\textwidth]{images/forgettingmorphisms.jpg}
+ \centering
+ \includegraphics[width=0.45\textwidth]{images/forgettingmorphisms.jpg}
\end{figure}
\noindent
@@ -195,8 +195,8 @@ preserve by morphisms). Such ``structure-free'' objects are called free
objects.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.45\textwidth]{images/freeimage.jpg}
+ \centering
+ \includegraphics[width=0.45\textwidth]{images/freeimage.jpg}
\end{figure}
\noindent
@@ -209,7 +209,7 @@ there is no identification of ${[}2, 3{]}$ and $6$, a morphism from this
free monoid to any other monoid $m$ is allowed to map them
separately. But it's also okay for it to map both ${[}2, 3{]}$ and $6$
(their product) to the same element of $m$. Or to identify ${[}2,
-3{]}$ and $5$ (their sum) in an additive monoid, and so on. Different
+ 3{]}$ and $5$ (their sum) in an additive monoid, and so on. Different
identifications give you different monoids.
This leads to another interesting intuition: Free monoids, instead of
@@ -234,10 +234,10 @@ intermediate results.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Consider a free monoid built from a singleton set as its generator.
- Show that there is a one-to-one correspondence between morphisms from
- this free monoid to any monoid $m$, and functions from the
- singleton set to the underlying set of $m$.
+ \tightlist
+ \item
+ Consider a free monoid built from a singleton set as its generator.
+ Show that there is a one-to-one correspondence between morphisms from
+ this free monoid to any monoid $m$, and functions from the
+ singleton set to the underlying set of $m$.
\end{enumerate}
diff --git a/src/content/3.4/monads-programmers-definition.tex b/src/content/3.4/monads-programmers-definition.tex
index 7a9e3aa..f7332f6 100644
--- a/src/content/3.4/monads-programmers-definition.tex
+++ b/src/content/3.4/monads-programmers-definition.tex
@@ -21,19 +21,19 @@ tape) and its applications. Here's a little sample of things that you
can do with it:
\begin{itemize}
-\tightlist
-\item
- sealing ducts
-\item
- fixing CO\textsubscript{2} scrubbers on board Apollo 13
-\item
- wart treatment
-\item
- fixing Apple's iPhone 4 dropped call issue
-\item
- making a prom dress
-\item
- building a suspension bridge
+ \tightlist
+ \item
+ sealing ducts
+ \item
+ fixing CO\textsubscript{2} scrubbers on board Apollo 13
+ \item
+ wart treatment
+ \item
+ fixing Apple's iPhone 4 dropped call issue
+ \item
+ making a prom dress
+ \item
+ building a suspension bridge
\end{itemize}
\noindent
@@ -83,7 +83,7 @@ the first place.
We have previously arrived at the
\hyperref[kleisli-categories]{writer
-monad} by embellishing regular functions. The particular embellishment
+ monad} by embellishing regular functions. The particular embellishment
was done by pairing their return values with strings or, more generally,
with elements of a monoid. We can now recognize that such an embellishment
is a functor:
@@ -311,7 +311,7 @@ Interestingly, the equivalent of the \code{do} notation has found its
application in imperative languages, C++ in particular. I'm talking
about resumable functions or coroutines. It's not a secret that C++
\urlref{https://bartoszmilewski.com/2014/02/26/c17-i-see-a-monad-in-your-future/}{futures
-form a monad}. It's an example of the continuation monad, which we'll
+ form a monad}. It's an example of the continuation monad, which we'll
discuss shortly. The problem with continuations is that they are very
hard to compose. In Haskell, we use the \code{do} notation to turn the
spaghetti of ``my handler will call your handler'' into something that
@@ -319,7 +319,7 @@ looks very much like sequential code. Resumable functions make the same
transformation possible in C++. And the same mechanism can be applied to
turn the
\urlref{https://bartoszmilewski.com/2014/04/21/getting-lazy-with-c/}{spaghetti
-of nested loops} into list comprehensions or ``generators,'' which are
+ of nested loops} into list comprehensions or ``generators,'' which are
essentially the \code{do} notation for the list monad. Without the
unifying abstraction of the monad, each of these problems is typically
addressed by providing custom extensions to the language. In Haskell,
diff --git a/src/content/3.5/monads-and-effects.tex b/src/content/3.5/monads-and-effects.tex
index 9cbff6c..1299502 100644
--- a/src/content/3.5/monads-and-effects.tex
+++ b/src/content/3.5/monads-and-effects.tex
@@ -13,36 +13,36 @@ functions.
Here is a short list of similar problems, copied from
\urlref{https://core.ac.uk/download/pdf/21173011.pdf}{Eugenio Moggi's
-seminal paper}, all of which are traditionally solved by abandoning the
+ seminal paper}, all of which are traditionally solved by abandoning the
purity of functions.
\begin{itemize}
-\tightlist
-\item
- Partiality: Computations that may not terminate
-\item
- Nondeterminism: Computations that may return many results
-\item
- Side effects: Computations that access/modify state
-
- \begin{itemize}
\tightlist
\item
- Read-only state, or the environment
+ Partiality: Computations that may not terminate
\item
- Write-only state, or a log
+ Nondeterminism: Computations that may return many results
\item
- Read/write state
- \end{itemize}
-\item
- Exceptions: Partial functions that may fail
-\item
- Continuations: Ability to save state of the program and then restore
- it on demand
-\item
- Interactive Input
-\item
- Interactive Output
+ Side effects: Computations that access/modify state
+
+ \begin{itemize}
+ \tightlist
+ \item
+ Read-only state, or the environment
+ \item
+ Write-only state, or a log
+ \item
+ Read/write state
+ \end{itemize}
+ \item
+ Exceptions: Partial functions that may fail
+ \item
+ Continuations: Ability to save state of the program and then restore
+ it on demand
+ \item
+ Interactive Input
+ \item
+ Interactive Output
\end{itemize}
What really is mind blowing is that all these problems may be solved
@@ -102,7 +102,7 @@ Haskell (lifted) types and functions rather than the simpler
$\Set$. It is not clear, though, that $\Hask$ is a real
category (see this
\urlref{http://math.andrej.com/2016/08/06/hask-is-not-a-category/}{Andrej
-Bauer post}).
+ Bauer post}).
\subsection{Nondeterminism}
@@ -134,7 +134,7 @@ From the programmer's point of view, working with a list is easier than,
for instance, calling a non-deterministic function in a loop, or
implementing a function that returns an iterator (although,
\urlref{http://ericniebler.com/2014/04/27/range-comprehensions/}{in modern
-C++}, returning a lazy range would be almost equivalent to returning a
+ C++}, returning a lazy range would be almost equivalent to returning a
list in Haskell).
A good example of using non-determinism creatively is in game
diff --git a/src/content/3.6/monads-categorically.tex b/src/content/3.6/monads-categorically.tex
index 4e76834..3e34d9b 100644
--- a/src/content/3.6/monads-categorically.tex
+++ b/src/content/3.6/monads-categorically.tex
@@ -15,8 +15,8 @@ like $1$ or $2$, bound together with operators like plus or times. As
programmers, we often think of expressions as trees.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/exptree.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/exptree.png}
\end{figure}
\noindent
@@ -79,8 +79,8 @@ implemented using $\mu$:
\[g \circ_T f = \mu_c \circ (T\ g) \circ f\]
where
\begin{gather*}
-f \Colon a \to T\ b \\
-g \Colon b \to T\ c
+ f \Colon a \to T\ b \\
+ g \Colon b \to T\ c
\end{gather*}
Here $T$, being a functor, can be applied to the morphism
$g$. It might be easier to recognize this formula in Haskell
@@ -114,8 +114,8 @@ horizontal composition of two natural transformations:
\[I_T \circ \mu\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/assoc1.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/assoc1.png}
\end{figure}
\noindent
@@ -131,8 +131,8 @@ must mean $I_T$ in this context.
We can also draw the diagram in the (endo-) functor category ${[}\cat{C}, \cat{C}{]}$:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/assoc2.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/assoc2.png}
\end{figure}
\noindent
@@ -142,8 +142,8 @@ $T \circ T$ which, again, can be reduced to $T$ using $\mu$. We
require that the two paths produce the same result.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/assoc.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/assoc.png}
\end{figure}
\noindent
@@ -155,8 +155,8 @@ transformation directly to \code{T}. And, by analogy, the same should
be true for $T \circ \eta$.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/unitlawcomp-1.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/unitlawcomp-1.png}
\end{figure}
\noindent
@@ -275,8 +275,8 @@ up to isomorphism. The associator and the two unitors are natural
isomorphisms. The laws can be represented by commuting diagrams.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/assocmon.png}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/assocmon.png}
\end{figure}
\noindent
@@ -312,9 +312,9 @@ and a distinct object $i$ called the unit object, together with
three natural isomorphisms called, respectively, the associator and the
left and right unitors:
\begin{align*}
-\alpha_{a b c} &\Colon (a \otimes b) \otimes c \to a \otimes (b \otimes c) \\
-\lambda_a &\Colon i \otimes a \to a \\
-\rho_a &\Colon a \otimes i \to a
+ \alpha_{a b c} & \Colon (a \otimes b) \otimes c \to a \otimes (b \otimes c) \\
+ \lambda_a & \Colon i \otimes a \to a \\
+ \rho_a & \Colon a \otimes i \to a
\end{align*}
(There is also a coherence condition for simplifying a quadruple tensor
product.)
@@ -335,14 +335,14 @@ of $m$, but they are isomorphic through the associator. Similarly
for higher powers of $m$ (that's where we need the coherence
conditions). To form a monoid we need to pick two morphisms:
\begin{align*}
-\mu &\Colon m \otimes m \to m \\
-\eta &\Colon i \to m
+ \mu & \Colon m \otimes m \to m \\
+ \eta & \Colon i \to m
\end{align*}
where $i$ is the unit object for our tensor product.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/monoid-1.jpg}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/monoid-1.jpg}
\end{figure}
\noindent
@@ -350,13 +350,13 @@ These morphisms have to satisfy associativity and unit laws, which can
be expressed in terms of the following commuting diagrams:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/assoctensor.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/assoctensor.jpg}
\end{figure}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/unitmon.jpg}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/unitmon.jpg}
\end{figure}
\noindent
@@ -395,8 +395,8 @@ transformations, and tensor products by composition, you get:
which you may recognize as the special case of horizontal composition.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/horizcomp.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/horizcomp.png}
\end{figure}
\noindent
@@ -411,19 +411,19 @@ What's a monoid in this category? It's an object --- that is an
endofunctor $T$; and two morphisms --- that is natural
transformations:
\begin{gather*}
-\mu \Colon T \circ T \to T \\
-\eta \Colon I \to T
+ \mu \Colon T \circ T \to T \\
+ \eta \Colon I \to T
\end{gather*}
Not only that, here are the monoid laws:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/assoc.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/assoc.png}
\end{figure}
\begin{figure}[H]
-\centering
-\includegraphics[width=0.5\textwidth]{images/unitlawcomp.png}
+ \centering
+ \includegraphics[width=0.5\textwidth]{images/unitlawcomp.png}
\end{figure}
\noindent
@@ -431,7 +431,7 @@ They are exactly the monad laws we've seen before. Now you understand
the famous quote from Saunders Mac Lane:
\begin{quote}
-All told, monad is just a monoid in the category of endofunctors.
+ All told, monad is just a monoid in the category of endofunctors.
\end{quote}
You might have seen it emblazoned on some t-shirts at functional
programming conferences.
@@ -445,8 +445,8 @@ giving rise to two endofunctors, $R \circ L$ and $L \circ R$.
As per an adjunction, these endofunctors are related to identity
functors through two natural transformations called unit and counit:
\begin{gather*}
-\eta \Colon I_{\cat{D}} \to R \circ L \\
-\varepsilon \Colon L \circ R \to I_{\cat{C}}
+ \eta \Colon I_{\cat{D}} \to R \circ L \\
+ \varepsilon \Colon L \circ R \to I_{\cat{C}}
\end{gather*}
Immediately we see that the unit of an adjunction looks just like the
unit of a monad. It turns out that the endofunctor $R \circ L$ is
@@ -467,8 +467,8 @@ because an adjunction usually involves two categories. However, the
definitions of an exponential, or a function object, is an exception.
Here are the two endofunctors that form this adjunction:
\begin{gather*}
-L\ z = z\times{}s \\
-R\ b = s \Rightarrow b
+ L\ z = z\times{}s \\
+ R\ b = s \Rightarrow b
\end{gather*}
You may recognize their composition as the familiar state monad:
\[R\ (L\ z) = s \Rightarrow (z\times{}s)\]
diff --git a/src/content/3.7/comonads.tex b/src/content/3.7/comonads.tex
index 67879df..a471b3c 100644
--- a/src/content/3.7/comonads.tex
+++ b/src/content/3.7/comonads.tex
@@ -226,8 +226,8 @@ duality. As with the monad, we start with an endofunctor \code{T}. The
two natural transformations, $\eta$ and $\mu$, that define the monad are simply
reversed for the comonad:
\begin{align*}
-\varepsilon &\Colon T \to I \\
-\delta &\Colon T \to T^2
+ \varepsilon & \Colon T \to I \\
+ \delta & \Colon T \to T^2
\end{align*}
The components of these transformations correspond to \code{extract}
and \code{duplicate}. Comonad laws are the mirror image of monad laws.
@@ -255,14 +255,14 @@ approach to a monad, we used a more general definition of a monoid as an
object in a monoidal category. The construction was based on two
morphisms:
\begin{align*}
-\mu &\Colon m \otimes m \to m \\
-\eta &\Colon i \to m
+ \mu & \Colon m \otimes m \to m \\
+ \eta & \Colon i \to m
\end{align*}
The reversal of these morphisms produces a comonoid in a monoidal
category:
\begin{align*}
-\delta &\Colon m \to m \otimes m \\
-\varepsilon &\Colon m \to i
+ \delta & \Colon m \to m \otimes m \\
+ \varepsilon & \Colon m \to i
\end{align*}
One can write a definition of a comonoid in Haskell:
@@ -280,7 +280,7 @@ Now consider comonoid laws that are dual to the monoid unit laws.
Here, \code{lambda} and \code{rho} are the left and right unitors,
respectively (see the definition of
\hyperref[monads-categorically]{monoidal
-categories}). Plugging in the definitions, we get:
+ categories}). Plugging in the definitions, we get:
\src{snippet29}
which proves that \code{g = id}. Similarly, the second law expands
@@ -296,7 +296,7 @@ And it turns out that, just like the monad is a monoid in the category
of endofunctors,
\begin{quote}
-The comonad is a comonoid in the category of endofunctors.
+ The comonad is a comonoid in the category of endofunctors.
\end{quote}
\section{The Store Comonad}
@@ -307,8 +307,8 @@ It's called the costate comonad or, alternatively, the store comonad.
We've seen before that the state monad is generated by the adjunction
that defines the exponentials:
\begin{align*}
-L\ z &= z\times{}s \\
-R\ a &= s \Rightarrow a
+ L\ z & = z\times{}s \\
+ R\ a & = s \Rightarrow a
\end{align*}
We'll use the same adjunction to define the costate comonad. A comonad
is defined by the composition $L \circ R$:
@@ -336,8 +336,8 @@ can be rewritten as partially applied data constructor:
\src{snippet35}
We construct $\delta$, or \code{duplicate}, as the horizontal composition:
\begin{align*}
-\delta &\Colon L \circ R \to L \circ R \circ L \circ R \\
-\delta &= L \circ \eta \circ R
+ \delta & \Colon L \circ R \to L \circ R \circ L \circ R \\
+ \delta & = L \circ \eta \circ R
\end{align*}
We have to sneak $\eta$ through the leftmost $L$, which is the
\code{Product} functor. It means acting with $\eta$, or \code{Store f}, on
@@ -393,8 +393,8 @@ could be implemented to read the value of the \code{s} field from
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Implement the Conway's Game of Life using the \code{Store} comonad.
- Hint: What type do you pick for \code{s}?
+ \tightlist
+ \item
+ Implement the Conway's Game of Life using the \code{Store} comonad.
+ Hint: What type do you pick for \code{s}?
\end{enumerate}
diff --git a/src/content/3.8/f-algebras.tex b/src/content/3.8/f-algebras.tex
index 7effb5e..95cc062 100644
--- a/src/content/3.8/f-algebras.tex
+++ b/src/content/3.8/f-algebras.tex
@@ -7,8 +7,8 @@ more juice can we squeeze out of this simple concept?
Let's try. Take this definition of a monoid as a set $m$ with a
pair of functions:
\begin{align*}
-\mu &\Colon m\times{}m \to m \\
-\eta &\Colon 1 \to m
+ \mu & \Colon m\times{}m \to m \\
+ \eta & \Colon 1 \to m
\end{align*}
Here, 1 is the terminal object in $\Set$ --- the singleton set.
The first function defines multiplication (it takes a pair of elements
@@ -20,8 +20,8 @@ and just consider ``potential monoids.'' A pair of functions is an
element of a Cartesian product of two sets of functions. We know that
these sets may be represented as exponential objects:
\begin{align*}
-\mu &\in m^{m\times{}m} \\
-\eta &\in m^1
+ \mu & \in m^{m\times{}m} \\
+ \eta & \in m^1
\end{align*}
The Cartesian product of these two sets is:
\[m^{m\times{}m}\times{}m^1\]
@@ -42,9 +42,9 @@ $m \to m$. As an example, integers form a group with
addition as a binary operation, zero as the unit, and negation as the
inverse. To define a group we would start with a triple of functions:
\begin{align*}
-m\times{}m \to m \\
-m \to m \\
-1 \to m
+ m\times{}m \to m \\
+ m \to m \\
+ 1 \to m
\end{align*}
As before, we can combine all these triples into one set of functions:
\[m\times{}m + m + 1 \to m\]
@@ -94,7 +94,7 @@ In the monoid example, the functor in question is:
\src{snippet02}
This is Haskell for $1 + a\times{}a$ (remember
\hyperref[simple-algebraic-data-types]{algebraic
-data structures}).
+ data structures}).
A ring would be defined using the following functor:
@@ -159,7 +159,7 @@ Of course, this is a hand-waving argument, and I'll make it more
rigorous later.
Applying an endofunctor infinitely many times produces a \newterm{fixed
-point}, an object defined as:
+ point}, an object defined as:
\[Fix\ f = f\ (Fix\ f)\]
The intuition behind this definition is that, since we applied
$f$ infinitely many times to get $Fix\ f$, applying it one
@@ -208,8 +208,8 @@ be equal:
\[g \circ F\ m = m \circ f\]
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/alg.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/alg.png}
\end{figure}
\noindent
@@ -227,8 +227,8 @@ $m$ from it to any other F-algebra. Since $m$ is a
homomorphism, the following diagram must commute:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/alg2.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/alg2.png}
\end{figure}
\noindent
@@ -242,8 +242,8 @@ homomorphism $m$ from it to $(F\ i, F\ j)$. The following
diagram must commute:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/alg3a.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/alg3a.png}
\end{figure}
\noindent
@@ -251,8 +251,8 @@ But we also have this trivially commuting diagram (both paths are the
same!):
\begin{figure}[H]
-\centering
-\includegraphics[width=0.3\textwidth]{images/alg3.png}
+ \centering
+ \includegraphics[width=0.3\textwidth]{images/alg3.png}
\end{figure}
\noindent
@@ -261,8 +261,8 @@ algebras, mapping $(F\ i, F\ j)$ to $(i, j)$. We can
glue these two diagrams together to get:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.6\textwidth]{images/alg4.png}
+ \centering
+ \includegraphics[width=0.6\textwidth]{images/alg4.png}
\end{figure}
\noindent
@@ -292,8 +292,8 @@ the fixed point does not depend on $a$.
Natural numbers can also be defined as an F-algebra. The starting point
is the pair of morphisms:
\begin{align*}
-zero &\Colon 1 \to N \\
-succ &\Colon N \to N
+ zero & \Colon 1 \to N \\
+ succ & \Colon N \to N
\end{align*}
The first one picks the zero, and the second one maps all numbers to
their successors. As before, we can combine the two into one:
@@ -318,8 +318,8 @@ algebra to any other algebra over the same functor. Let's pick an
algebra whose carrier is \code{a} and the evaluator is \code{alg}.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/alg5.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/alg5.png}
\end{figure}
\noindent
@@ -332,8 +332,8 @@ isomorphism. We called its inverse \code{unFix}. We can therefore flip
one arrow in this diagram to get:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/alg6.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/alg6.png}
\end{figure}
\noindent
@@ -431,8 +431,8 @@ coalgebra. For every other algebra $(a, f)$ there is a unique
homomorphism $m$ that makes the following diagram commute:
\begin{figure}[H]
-\centering
-\includegraphics[width=0.4\textwidth]{images/alg7.png}
+ \centering
+ \includegraphics[width=0.4\textwidth]{images/alg7.png}
\end{figure}
\noindent
@@ -523,21 +523,21 @@ with the comonad structure. We'll talk about this in the next section.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- Implement the evaluation function for a ring of polynomials of one
- variable. You can represent a polynomial as a list of coefficients in
- front of powers of $x$. For instance, $4x^2-1$ would be
- represented as (starting with the zero'th power)
- \code{{[}-1, 0, 4{]}}.
-\item
- Generalize the previous construction to polynomials of many
- independent variables, like $x^2y-3y^3z$.
-\item
- Implement the algebra for the ring of $2\times{}2$ matrices.
-\item
- Define a coalgebra whose anamorphism produces a list of squares of
- natural numbers.
-\item
- Use \code{unfoldr} to generate a list of the first $n$ primes.
+ \tightlist
+ \item
+ Implement the evaluation function for a ring of polynomials of one
+ variable. You can represent a polynomial as a list of coefficients in
+ front of powers of $x$. For instance, $4x^2-1$ would be
+ represented as (starting with the zero'th power)
+ \code{{[}-1, 0, 4{]}}.
+ \item
+ Generalize the previous construction to polynomials of many
+ independent variables, like $x^2y-3y^3z$.
+ \item
+ Implement the algebra for the ring of $2\times{}2$ matrices.
+ \item
+ Define a coalgebra whose anamorphism produces a list of squares of
+ natural numbers.
+ \item
+ Use \code{unfoldr} to generate a list of the first $n$ primes.
\end{enumerate}
diff --git a/src/content/3.9/algebras-for-monads.tex b/src/content/3.9/algebras-for-monads.tex
index 070280b..1d77efe 100644
--- a/src/content/3.9/algebras-for-monads.tex
+++ b/src/content/3.9/algebras-for-monads.tex
@@ -7,14 +7,14 @@ but we can also answer a few interesting questions.
One such question concerns the relation between monads and adjunctions.
As we've seen, every adjunction \hyperref[monads-categorically]{defines
-a monad} (and a comonad). The question is: Can every monad (comonad) be
+ a monad} (and a comonad). The question is: Can every monad (comonad) be
derived from an adjunction? The answer is positive. There is a whole
family of adjunctions that generate a given monad. I'll show you two
such adjunctions.
\begin{figure}[H]
-\centering
-\includegraphics[width=0.25\textwidth]{images/pigalg.png}
+ \centering
+ \includegraphics[width=0.25\textwidth]{images/pigalg.png}
\end{figure}
\noindent
@@ -22,8 +22,8 @@ Let's review the definitions. A monad is an endofunctor $m$
equipped with two natural transformations that satisfy some coherence
conditions. The components of these transformations at $a$ are:
\begin{align*}
-\eta_a &\Colon a \to m\ a \\
-\mu_a &\Colon m\ (m\ a) \to m\ a
+ \eta_a & \Colon a \to m\ a \\
+ \mu_a & \Colon m\ (m\ a) \to m\ a
\end{align*}
An algebra for the same endofunctor is a selection of a particular
object --- the carrier $a$ --- together with the morphism:
@@ -53,8 +53,8 @@ $T$ in anticipation of what follows):
\centering
\begin{tikzcd}[column sep=large, row sep=large]
a \arrow[rd, equal] \arrow[r, "\eta_a"]
- & Ta \arrow[d, "alg"] \\
- & a
+ & Ta \arrow[d, "alg"] \\
+ & a
\end{tikzcd}
\end{subfigure}
\hspace{1cm}
@@ -62,9 +62,9 @@ $T$ in anticipation of what follows):
\centering
\begin{tikzcd}[column sep=large, row sep=large]
T(Ta) \arrow[r, "T\ alg"] \arrow[d, "\mu_a"]
- & Ta \arrow[d, "alg"] \\
+ & Ta \arrow[d, "alg"] \\
Ta \arrow[r, "alg"]
- & a
+ & a
\end{tikzcd}
\end{subfigure}
\end{figure}
@@ -130,8 +130,8 @@ evaluator.
We still have to show that this is a T-algebra. For that, two coherence
conditions must be satisfied:
\begin{align*}
-alg &\circ \eta_{Ta} = \id_{Ta} \\
-alg &\circ \mu_a = alg \circ T\ alg
+ alg & \circ \eta_{Ta} = \id_{Ta} \\
+ alg & \circ \mu_a = alg \circ T\ alg
\end{align*}
But these are just monadic laws, if you plug in $\mu$ for the
algebra.
@@ -174,13 +174,13 @@ diagram that makes $f$ a T-algebra may be re-interpreted to show
that it's a homomorphism of T-algebras:
\begin{figure}[H]
-\centering
-\begin{tikzcd}[column sep=large, row sep=large]
- T(Ta) \arrow[r, "T f"] \arrow[d, "\mu_a"]
- & Ta \arrow[d, "f"] \\
- Ta \arrow[r, "f"]
- & a
-\end{tikzcd}
+ \centering
+ \begin{tikzcd}[column sep=large, row sep=large]
+ T(Ta) \arrow[r, "T f"] \arrow[d, "\mu_a"]
+ & Ta \arrow[d, "f"] \\
+ Ta \arrow[r, "f"]
+ & a
+ \end{tikzcd}
\end{figure}
\noindent
@@ -197,8 +197,8 @@ counit satisfy triangular identities. These are:
\centering
\begin{tikzcd}[column sep=large, row sep=large]
Ta \arrow[rd, equal] \arrow[r, "T \eta_a"]
- & T(Ta) \arrow[d, "\mu_a"] \\
- & Ta
+ & T(Ta) \arrow[d, "\mu_a"] \\
+ & Ta
\end{tikzcd}
\end{subfigure}%
\hspace{1cm}
@@ -206,8 +206,8 @@ counit satisfy triangular identities. These are:
\centering
\begin{tikzcd}[column sep=large, row sep=large]
a \arrow[rd, equal] \arrow[r, "\eta_a"]
- & Ta \arrow[d, "f"] \\
- & a
+ & Ta \arrow[d, "f"] \\
+ & a
\end{tikzcd}
\end{subfigure}
\end{figure}
@@ -260,20 +260,20 @@ Composition of morphisms in the Kleisli category is defined in terms of
monadic composition of Kleisli arrows. For instance, let's compose
$g_{\cat{K}}$ after $f_{\cat{K}}$. In the Kleisli category we have:
\begin{gather*}
-f_{\cat{K}} \Colon a \to b \\
-g_{\cat{K}} \Colon b \to c
+ f_{\cat{K}} \Colon a \to b \\
+ g_{\cat{K}} \Colon b \to c
\end{gather*}
which, in the category $\cat{C}$, corresponds to:
\begin{gather*}
-f \Colon a \to T\ b \\
-g \Colon b \to T\ c
+ f \Colon a \to T\ b \\
+ g \Colon b \to T\ c
\end{gather*}
We define the composition:
\[h_{\cat{K}} = g_{\cat{K}} \circ f_{\cat{K}}\]
as a Kleisli arrow in $\cat{C}$
\begin{align*}
-h &\Colon a \to T\ c \\
-h &= \mu \circ (T\ g) \circ f
+ h & \Colon a \to T\ c \\
+ h & = \mu \circ (T\ g) \circ f
\end{align*}
In Haskell we would write it as:
@@ -330,8 +330,8 @@ with a comonad. They make the following diagrams commute:
\centering
\begin{tikzcd}[column sep=large, row sep=large]
a \arrow[rd, equal]
- & Wa \arrow[l, "\epsilon_a"'] \\
- & a \arrow[u, "coa"']
+ & Wa \arrow[l, "\epsilon_a"'] \\
+ & a \arrow[u, "coa"']
\end{tikzcd}
\end{subfigure}%
\hspace{1cm}
@@ -339,9 +339,9 @@ with a comonad. They make the following diagrams commute:
\centering
\begin{tikzcd}[column sep=large, row sep=large]
W(Wa)
- & Wa \arrow[l, "W\ coa"'] \\
+ & Wa \arrow[l, "W\ coa"'] \\
Wa \arrow[u, "\delta_a"]
- & a \arrow[u, "coa"] \arrow[l, "coa"']
+ & a \arrow[u, "coa"] \arrow[l, "coa"']
\end{tikzcd}
\end{subfigure}
\end{figure}
@@ -377,8 +377,8 @@ for the functor $Store\ s$:
\src{snippet07}
This coalgebra can be also expressed as a pair of functions:
\begin{align*}
-set &\Colon a \to s \to a \\
-get &\Colon a \to s
+ set & \Colon a \to s \to a \\
+ get & \Colon a \to s
\end{align*}
(Think of $a$ as standing for ``all,'' and $s$ as a
``small'' part of it.) In terms of this pair, we have:
@@ -433,14 +433,14 @@ the \code{Store} functor.
\section{Challenges}
\begin{enumerate}
-\tightlist
-\item
- What is the action of the free functor
- $F \Colon C \to C^T$ on morphisms. Hint: use the
- naturality condition for monadic $\mu$.
-\item
- Define the adjunction:
-\[U^W \dashv F^W\]
-\item
- Prove that the above adjunction reproduces the original comonad.
+ \tightlist
+ \item
+ What is the action of the free functor
+ $F \Colon C \to C^T$ on morphisms. Hint: use the
+ naturality condition for monadic $\mu$.
+ \item
+ Define the adjunction:
+ \[U^W \dashv F^W\]
+ \item
+ Prove that the above adjunction reproduces the original comonad.
\end{enumerate}
diff --git a/src/content/editor-note.tex b/src/content/editor-note.tex
index 0beb5c4..31c42c0 100644
--- a/src/content/editor-note.tex
+++ b/src/content/editor-note.tex
@@ -1,8 +1,8 @@
% !TEX root = ../ctfp-print.tex
\ifdefined\OPTCustomLanguage{%
- \chapter*{A note from the editor}
- \addcontentsline{toc}{chapter}{A note from the editor}
- \input{content/\OPTCustomLanguage/editor-note}
-}
+ \chapter*{A note from the editor}
+ \addcontentsline{toc}{chapter}{A note from the editor}
+ \input{content/\OPTCustomLanguage/editor-note}
+ }
\fi
\ No newline at end of file
diff --git a/src/content/ocaml/colophon.tex b/src/content/ocaml/colophon.tex
index 707e598..9d094a4 100644
--- a/src/content/ocaml/colophon.tex
+++ b/src/content/ocaml/colophon.tex
@@ -1,2 +1,2 @@
-OCaml code translation was done by \urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{Arulselvan Madhavan}
+OCaml code translation was done by \urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{Arulselvan Madhavan}
and reviewed by \urlref{http://www.mseri.me}{Marcello Seri} and \urlref{https://github.com/XVilka}{Anton Kochkov}.
\ No newline at end of file
diff --git a/src/content/ocaml/editor-note.tex b/src/content/ocaml/editor-note.tex
index 6c54cb5..c79ca4a 100644
--- a/src/content/ocaml/editor-note.tex
+++ b/src/content/ocaml/editor-note.tex
@@ -8,17 +8,17 @@ other programming languages.
I am thrilled to present this edition of the book, containing the original Haskell code, followed by
its OCaml counterpart. The OCaml code snippets were generously provided by
-\urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{ocaml-ctfp} contributors, slightly
+\urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{ocaml-ctfp} contributors, slightly
modified to suit the format of this book.
To support code snippets in multiple languages, I am using a \LaTeX{} macro to load the code snippets
-from external files. This allows easily extending the book with other languages, while leaving the
+from external files. This allows easily extending the book with other languages, while leaving the
original text intact. Which is why you should mentally append the words ``and OCaml'' whenever you see
``in Haskell'' in the text.
The code is laid out in the following manner: the original Haskell code, followed by OCaml code.
To distinguish between them, the code snippets are braced from the left with a vertical bar, in the primary
-color of the language's logo, \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/haskell.png}},
+color of the language's logo, \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/haskell.png}},
and \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/ocaml.png}} respectively, e.g.:
\srcsnippet{content/1.1/code/haskell/snippet03.hs}{blue}{haskell}
diff --git a/src/content/reason/editor-note.tex b/src/content/reason/editor-note.tex
index 9a13bcc..910106f 100644
--- a/src/content/reason/editor-note.tex
+++ b/src/content/reason/editor-note.tex
@@ -7,18 +7,18 @@ to improve the book, by fixing typos and errors, as well as translating the code
other programming languages.
I am thrilled to present this edition of the book, containing the original Haskell code, followed by
-its ReasonML counterpart. The ReasonML code snippets were converted from the OCaml snippets which were
+its ReasonML counterpart. The ReasonML code snippets were converted from the OCaml snippets which were
generously provided by \urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{ocaml-ctfp} contributors,
and slightly modified to suit the format of this book.
To support code snippets in multiple languages, I am using a \LaTeX{} macro to load the code snippets
-from external files. This allows easily extending the book with other languages, while leaving the
+from external files. This allows easily extending the book with other languages, while leaving the
original text intact. Which is why you should mentally append the words ``and ReasonML'' whenever you see
``in Haskell'' in the text.
The code is laid out in the following manner: the original Haskell code, followed by ReasonML code.
To distinguish between them, the code snippets are braced from the left with a vertical bar, in the primary
-color of the language's logo, \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/haskell.png}},
+color of the language's logo, \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/haskell.png}},
and \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/reason.png}} respectively, e.g.:
\srcsnippet{content/1.1/code/haskell/snippet03.hs}{blue}{haskell}
diff --git a/src/content/scala/editor-note.tex b/src/content/scala/editor-note.tex
index 398a578..f6bc640 100644
--- a/src/content/scala/editor-note.tex
+++ b/src/content/scala/editor-note.tex
@@ -1,29 +1,29 @@
% !TEX root = ctfp-print.tex
\lettrine[lhang=0.17]{T}{his is the Scala edition} of \emph{Category Theory for Programmers}.
-It's been a tremendous success, making Bartosz Milewski's blog post series available as a nicely
+It's been a tremendous success, making Bartosz Milewski's blog post series available as a nicely
typeset \acronym{PDF}, as well as a hardcover book. There have been numerous contributions made
to improve the book, by fixing typos and errors, as well as translating the code snippets into
other programming languages.
I am thrilled to present this edition of the book, containing the original Haskell code, followed by
-its Scala counterpart. The Scala code snippets were generously provided by
-\urlref{https://github.com/typelevel/CT_from_Programmers.scala}{Typelevel} contributors, slightly
+its Scala counterpart. The Scala code snippets were generously provided by
+\urlref{https://github.com/typelevel/CT_from_Programmers.scala}{Typelevel} contributors, slightly
modified to suit the format of this book.
To support code snippets in multiple languages, I am using a \LaTeX{} macro to load the code snippets
-from external files. This allows easily extending the book with other languages, while leaving the
+from external files. This allows easily extending the book with other languages, while leaving the
original text intact. Which is why you should mentally append the words ``and Scala'' whenever you see
``in Haskell'' in the text.
The code is laid out in the following manner: the original Haskell code, followed by Scala code.
To distinguish between them, the code snippets are braced from the left with a vertical bar, in the primary
-color of the language's logo, \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/haskell.png}},
+color of the language's logo, \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/haskell.png}},
and \raisebox{-.2mm}{\includegraphics[height=.3cm]{fig/icons/scala.png}} respectively, e.g.:
\srcsnippet{content/3.6/code/haskell/snippet03.hs}{blue}{haskell}
\unskip
\srcsnippet{content/3.6/code/scala/snippet03.scala}{red}{scala}
\NoIndentAfterThis
-In addition, some Scala snippets make use of the
+In addition, some Scala snippets make use of the
\urlref{https://github.com/non/kind-projector}{Kind Projector} compiler plugin, to support nicer syntax for partially-applied types.
\ No newline at end of file
diff --git a/src/cover/cover-hardcover-ocaml.tex b/src/cover/cover-hardcover-ocaml.tex
index 52d7c9c..eecd96c 100644
--- a/src/cover/cover-hardcover-ocaml.tex
+++ b/src/cover/cover-hardcover-ocaml.tex
@@ -6,25 +6,14 @@
11pt,
marklength=0pt,
]{bookcover}
-
+
\usepackage{fancybox}
\usepackage{wrapfig}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc,positioning, shadings}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
-
- \setmainfont[
- Path=fonts/,
- Extension=.otf,
- UprightFont=*-Regular,
- ItalicFont=*-Italic,
- BoldFont=*-Bold,
- UprightFeatures={SmallCapsFont=*SC-Regular},
- ItalicFeatures={SmallCapsFont=*SC-Italic},
- BoldFeatures={SmallCapsFont=*SC-Bold},
- BoldItalicFeatures={SmallCapsFont=*SC-BoldItalic},
- ]{AlegreyaSans}
+ \usepackage{Alegreya}
\newcommand{\olpath}{../}
\newcommand{\whitebg}[1]{%
@@ -47,21 +36,21 @@
\end{tcolorbox}
}
\input{\olpath/version}
-
+
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
-
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\input{ribbon-ocaml}
\vspace{1.1cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -71,12 +60,12 @@
\vfil
\vspace*{1cm}
\end{center}}
-
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -85,33 +74,33 @@
\input{blurb}
\vspace{.5cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\bartosz
- &
+ &
\vspace{5pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/cover-hardcover-reason.tex b/src/cover/cover-hardcover-reason.tex
index ae049ae..97f10a9 100644
--- a/src/cover/cover-hardcover-reason.tex
+++ b/src/cover/cover-hardcover-reason.tex
@@ -6,25 +6,14 @@
11pt,
marklength=0pt,
]{bookcover}
-
+
\usepackage{fancybox}
\usepackage{wrapfig}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc,positioning, shadings}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
-
- \setmainfont[
- Path=fonts/,
- Extension=.otf,
- UprightFont=*-Regular,
- ItalicFont=*-Italic,
- BoldFont=*-Bold,
- UprightFeatures={SmallCapsFont=*SC-Regular},
- ItalicFeatures={SmallCapsFont=*SC-Italic},
- BoldFeatures={SmallCapsFont=*SC-Bold},
- BoldItalicFeatures={SmallCapsFont=*SC-BoldItalic},
- ]{AlegreyaSans}
+ \usepackage{Alegreya}
\newcommand{\olpath}{../}
\newcommand{\whitebg}[1]{%
@@ -47,21 +36,21 @@
\end{tcolorbox}
}
\input{\olpath/version}
-
+
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
-
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\input{ribbon-reason}
\vspace{1.1cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -71,12 +60,12 @@
\vfil
\vspace*{1cm}
\end{center}}
-
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -85,33 +74,33 @@
\input{blurb}
\vspace{.5cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\bartosz
- &
+ &
\vspace{5pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/cover-hardcover-scala.tex b/src/cover/cover-hardcover-scala.tex
index 4f73775..ad2ead5 100644
--- a/src/cover/cover-hardcover-scala.tex
+++ b/src/cover/cover-hardcover-scala.tex
@@ -6,25 +6,14 @@
11pt,
marklength=0pt,
]{bookcover}
-
+
\usepackage{fancybox}
\usepackage{wrapfig}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc,positioning, shadings}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
-
- \setmainfont[
- Path=fonts/,
- Extension=.otf,
- UprightFont=*-Regular,
- ItalicFont=*-Italic,
- BoldFont=*-Bold,
- UprightFeatures={SmallCapsFont=*SC-Regular},
- ItalicFeatures={SmallCapsFont=*SC-Italic},
- BoldFeatures={SmallCapsFont=*SC-Bold},
- BoldItalicFeatures={SmallCapsFont=*SC-BoldItalic},
- ]{AlegreyaSans}
+ \usepackage{Alegreya}
\newcommand{\olpath}{../}
\newcommand{\whitebg}[1]{%
@@ -47,21 +36,21 @@
\end{tcolorbox}
}
\input{\olpath/version}
-
+
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
-
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\input{ribbon-scala}
\vspace{1.1cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -71,12 +60,12 @@
\vfil
\vspace*{1cm}
\end{center}}
-
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -85,33 +74,33 @@
\input{blurb}
\vspace{.5cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\bartosz
- &
+ &
\vspace{5pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/cover-hardcover.tex b/src/cover/cover-hardcover.tex
index fabe17d..1e74c1c 100644
--- a/src/cover/cover-hardcover.tex
+++ b/src/cover/cover-hardcover.tex
@@ -46,16 +46,16 @@
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\vspace{2cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -66,11 +66,11 @@
\vspace*{1cm}
\end{center}}
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -79,33 +79,33 @@
\input{blurb}
\vspace{.5cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\bartosz
- &
+ &
\vspace{5pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/cover-paperback-ocaml.tex b/src/cover/cover-paperback-ocaml.tex
index adce136..44f73c9 100644
--- a/src/cover/cover-paperback-ocaml.tex
+++ b/src/cover/cover-paperback-ocaml.tex
@@ -7,33 +7,14 @@
11pt,
marklength=0in,
]{bookcover}
-
+
\usepackage{fancybox}
\usepackage{wrapfig}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc,positioning, shadings}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
-
- % \setmainfont{AlegreyaSans-Regular}[
- % BoldFont={AlegreyaSans-Bold},
- % ItalicFont={AlegreyaSans-Italic},
- % UprightFeatures={SmallCapsFont=AlegreyaSansSC-Regular},
- % ItalicFeatures={SmallCapsFont=AlegreyaSansSC-Italic},
- % BoldFeatures={SmallCapsFont=AlegreyaSansSC-Bold},
- % BoldItalicFeatures={SmallCapsFont=AlegreyaSansSC-BoldItalic},
- % ]
- \setmainfont[
- Path=fonts/,
- Extension=.otf,
- UprightFont=*-Regular,
- ItalicFont=*-Italic,
- BoldFont=*-Bold,
- UprightFeatures={SmallCapsFont=*SC-Regular},
- ItalicFeatures={SmallCapsFont=*SC-Italic},
- BoldFeatures={SmallCapsFont=*SC-Bold},
- BoldItalicFeatures={SmallCapsFont=*SC-BoldItalic},
- ]{AlegreyaSans}
+ \usepackage{Alegreya}
\newcommand{\olpath}{../}
\newcommand{\whitebg}[1]{%
@@ -56,21 +37,21 @@
\end{tcolorbox}
}
\input{\olpath/version}
-
+
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
-
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\input{ribbon-ocaml}
\vspace{1.1cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -80,12 +61,12 @@
\vfil
\vspace*{1cm}
\end{center}}
-
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -94,34 +75,34 @@
\input{blurb}
\vspace{0.6cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\vspace{5pt}
\bartosz
- &
+ &
\vspace{10pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/cover-paperback-reason.tex b/src/cover/cover-paperback-reason.tex
index e496f83..9eac3e5 100644
--- a/src/cover/cover-paperback-reason.tex
+++ b/src/cover/cover-paperback-reason.tex
@@ -7,33 +7,14 @@
11pt,
marklength=0in,
]{bookcover}
-
+
\usepackage{fancybox}
\usepackage{wrapfig}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc,positioning, shadings}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
-
- % \setmainfont{AlegreyaSans-Regular}[
- % BoldFont={AlegreyaSans-Bold},
- % ItalicFont={AlegreyaSans-Italic},
- % UprightFeatures={SmallCapsFont=AlegreyaSansSC-Regular},
- % ItalicFeatures={SmallCapsFont=AlegreyaSansSC-Italic},
- % BoldFeatures={SmallCapsFont=AlegreyaSansSC-Bold},
- % BoldItalicFeatures={SmallCapsFont=AlegreyaSansSC-BoldItalic},
- % ]
- \setmainfont[
- Path=fonts/,
- Extension=.otf,
- UprightFont=*-Regular,
- ItalicFont=*-Italic,
- BoldFont=*-Bold,
- UprightFeatures={SmallCapsFont=*SC-Regular},
- ItalicFeatures={SmallCapsFont=*SC-Italic},
- BoldFeatures={SmallCapsFont=*SC-Bold},
- BoldItalicFeatures={SmallCapsFont=*SC-BoldItalic},
- ]{AlegreyaSans}
+ \usepackage{Alegreya}
\newcommand{\olpath}{../}
\newcommand{\whitebg}[1]{%
@@ -56,21 +37,21 @@
\end{tcolorbox}
}
\input{\olpath/version}
-
+
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
-
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\input{ribbon-reason}
\vspace{1.1cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -80,12 +61,12 @@
\vfil
\vspace*{1cm}
\end{center}}
-
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -94,34 +75,34 @@
\input{blurb}
\vspace{0.6cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\vspace{5pt}
\bartosz
- &
+ &
\vspace{10pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/cover-paperback-scala.tex b/src/cover/cover-paperback-scala.tex
index ecda101..eeec8bc 100644
--- a/src/cover/cover-paperback-scala.tex
+++ b/src/cover/cover-paperback-scala.tex
@@ -7,25 +7,14 @@
11pt,
marklength=0in,
]{bookcover}
-
+
\usepackage{fancybox}
\usepackage{wrapfig}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc,positioning, shadings}
\usepackage[T1]{fontenc}
\usepackage{fontspec}
-
- \setmainfont[
- Path=fonts/,
- Extension=.otf,
- UprightFont=*-Regular,
- ItalicFont=*-Italic,
- BoldFont=*-Bold,
- UprightFeatures={SmallCapsFont=*SC-Regular},
- ItalicFeatures={SmallCapsFont=*SC-Italic},
- BoldFeatures={SmallCapsFont=*SC-Bold},
- BoldItalicFeatures={SmallCapsFont=*SC-BoldItalic},
- ]{AlegreyaSans}
+ \usepackage{Alegreya}
\newcommand{\olpath}{../}
\newcommand{\whitebg}[1]{%
@@ -48,21 +37,21 @@
\end{tcolorbox}
}
\input{\olpath/version}
-
+
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
-
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\input{ribbon-scala}
\vspace{1.1cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -72,12 +61,12 @@
\vfil
\vspace*{1cm}
\end{center}}
-
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -86,34 +75,34 @@
\input{blurb}
\vspace{0.6cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\vspace{5pt}
\bartosz
- &
+ &
\vspace{10pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/cover-paperback.tex b/src/cover/cover-paperback.tex
index c5e86c3..70faf3d 100644
--- a/src/cover/cover-paperback.tex
+++ b/src/cover/cover-paperback.tex
@@ -6,14 +6,14 @@
11pt,
marklength=0pt,
]{bookcover}
-
+
\usepackage{fancybox}
\usepackage{wrapfig}
\usepackage[many]{tcolorbox}
\usetikzlibrary{calc,positioning, shadings}
\usepackage[T1]{fontenc}
- \usepackage{Alegreya} %% Option 'black' gives heavier bold face
-
+ \usepackage{Alegreya} %% Option 'black' gives heavier bold face
+
\setmainfont{Alegreya Sans}[
UprightFeatures={SmallCapsFont=* SC},
ItalicFeatures={SmallCapsFont=* SC Italic},
@@ -42,20 +42,20 @@
\end{tcolorbox}
}
\input{\olpath/version}
-
+
\definecolor{BackgroundColor}{HTML}{f3f6ed}
\definecolor{SpineBackColor}{HTML}{262626}
-
- \begin{document}
-
- \begin{bookcover}
- \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
- \bookcovercomponent{color}{spine}{color=SpineBackColor}
- \bookcovercomponent{normal}{front}{
+
+\begin{document}
+
+\begin{bookcover}
+ \bookcovercomponent{color}{bg whole}{color=BackgroundColor}
+ \bookcovercomponent{color}{spine}{color=SpineBackColor}
+ \bookcovercomponent{normal}{front}{
\vspace{2cm}
\begin{center}
\fontsize{40pt}{5em}\selectfont\bfseries
- CATEGORY THEORY \\FOR PROGRAMMERS
+ CATEGORY THEORY \\FOR PROGRAMMERS
\vfil
\hspace*{-.8cm}\includegraphics[width=.5\coverwidth]{piggie}
\linebreak
@@ -65,12 +65,12 @@
\vfil
\vspace*{1cm}
\end{center}}
-
- \bookcovercomponent{center}{spine}{
- \rotatebox[origin=c]{-90}{\color{orange}
+
+ \bookcovercomponent{center}{spine}{
+ \rotatebox[origin=c]{-90}{\color{orange}
\Huge\bfseries Category Theory for Programmers \hspace{2em} Bartosz Milewski}}
- \bookcovercomponent{normal}{back}{%
+ \bookcovercomponent{normal}{back}{%
\begin{minipage}[b][\coverheight][t]{\coverwidth}
\begin{center}
\vspace{1cm}
@@ -79,33 +79,33 @@
\input{blurb}
\vspace{.5cm}
\end{minipage}
-
+
\begin{minipage}{.85\textwidth}
\rule{\textwidth}{.5pt}
\begin{tabular}[h]{p{3.4cm} p{\textwidth}}
\bartosz
- &
+ &
\vspace{5pt}
\begin{minipage}[b]{.58\coverwidth}
\fontsize{11pt}{1.4em}\selectfont\textit{Category Theory for Programmers}
- is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
- Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
- \end{minipage}
- \end{tabular}
- \begin{flushright}
- \vspace{-2.6cm}
- \begin{minipage}[b]{4cm}
- \raggedleft
- \whitebg{fig/icons/by}
- \whitebg{fig/icons/cc}
- \whitebg{fig/icons/sa}
- \centering\footnotesize{\texttt{\OPTversion}}
- \end{minipage}
- \end{flushright}
- \end{minipage}
- \end{center}
- \end{minipage}
+ is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\
+ Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\
+ \end{minipage}
+ \end{tabular}
+ \begin{flushright}
+ \vspace{-2.6cm}
+ \begin{minipage}[b]{4cm}
+ \raggedleft
+ \whitebg{fig/icons/by}
+ \whitebg{fig/icons/cc}
+ \whitebg{fig/icons/sa}
+ \centering\footnotesize{\texttt{\OPTversion}}
+ \end{minipage}
+ \end{flushright}
+ \end{minipage}
+ \end{center}
+ \end{minipage}
}
- \end{bookcover}
+\end{bookcover}
\end{document}
\ No newline at end of file
diff --git a/src/cover/fonts/AlegreyaSans-Black.otf b/src/cover/fonts/AlegreyaSans-Black.otf
deleted file mode 100755
index 4117b87..0000000
Binary files a/src/cover/fonts/AlegreyaSans-Black.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-BlackItalic.otf b/src/cover/fonts/AlegreyaSans-BlackItalic.otf
deleted file mode 100755
index 6482fbf..0000000
Binary files a/src/cover/fonts/AlegreyaSans-BlackItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-Bold.otf b/src/cover/fonts/AlegreyaSans-Bold.otf
deleted file mode 100755
index 766441f..0000000
Binary files a/src/cover/fonts/AlegreyaSans-Bold.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-BoldItalic.otf b/src/cover/fonts/AlegreyaSans-BoldItalic.otf
deleted file mode 100755
index 97e4775..0000000
Binary files a/src/cover/fonts/AlegreyaSans-BoldItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-ExtraBold.otf b/src/cover/fonts/AlegreyaSans-ExtraBold.otf
deleted file mode 100755
index aeac43c..0000000
Binary files a/src/cover/fonts/AlegreyaSans-ExtraBold.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-ExtraBoldItalic.otf b/src/cover/fonts/AlegreyaSans-ExtraBoldItalic.otf
deleted file mode 100755
index 4baae89..0000000
Binary files a/src/cover/fonts/AlegreyaSans-ExtraBoldItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-Italic.otf b/src/cover/fonts/AlegreyaSans-Italic.otf
deleted file mode 100755
index 91d385e..0000000
Binary files a/src/cover/fonts/AlegreyaSans-Italic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-Light.otf b/src/cover/fonts/AlegreyaSans-Light.otf
deleted file mode 100755
index 43f5e88..0000000
Binary files a/src/cover/fonts/AlegreyaSans-Light.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-LightItalic.otf b/src/cover/fonts/AlegreyaSans-LightItalic.otf
deleted file mode 100755
index 6bfe884..0000000
Binary files a/src/cover/fonts/AlegreyaSans-LightItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-Medium.otf b/src/cover/fonts/AlegreyaSans-Medium.otf
deleted file mode 100755
index b664f36..0000000
Binary files a/src/cover/fonts/AlegreyaSans-Medium.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-MediumItalic.otf b/src/cover/fonts/AlegreyaSans-MediumItalic.otf
deleted file mode 100755
index 2548463..0000000
Binary files a/src/cover/fonts/AlegreyaSans-MediumItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-Regular.otf b/src/cover/fonts/AlegreyaSans-Regular.otf
deleted file mode 100755
index 73b34a0..0000000
Binary files a/src/cover/fonts/AlegreyaSans-Regular.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-Thin.otf b/src/cover/fonts/AlegreyaSans-Thin.otf
deleted file mode 100755
index 9a29113..0000000
Binary files a/src/cover/fonts/AlegreyaSans-Thin.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSans-ThinItalic.otf b/src/cover/fonts/AlegreyaSans-ThinItalic.otf
deleted file mode 100755
index e742caa..0000000
Binary files a/src/cover/fonts/AlegreyaSans-ThinItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-Black.otf b/src/cover/fonts/AlegreyaSansSC-Black.otf
deleted file mode 100755
index 9c030ee..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-Black.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-BlackItalic.otf b/src/cover/fonts/AlegreyaSansSC-BlackItalic.otf
deleted file mode 100755
index 4812e8d..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-BlackItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-Bold.otf b/src/cover/fonts/AlegreyaSansSC-Bold.otf
deleted file mode 100755
index 6a5389f..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-Bold.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-BoldItalic.otf b/src/cover/fonts/AlegreyaSansSC-BoldItalic.otf
deleted file mode 100755
index 00e4cbd..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-BoldItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-ExtraBold.otf b/src/cover/fonts/AlegreyaSansSC-ExtraBold.otf
deleted file mode 100755
index 842260f..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-ExtraBold.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-ExtraBoldItalic.otf b/src/cover/fonts/AlegreyaSansSC-ExtraBoldItalic.otf
deleted file mode 100755
index 2875333..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-ExtraBoldItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-Italic.otf b/src/cover/fonts/AlegreyaSansSC-Italic.otf
deleted file mode 100755
index 86fe3b1..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-Italic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-Light.otf b/src/cover/fonts/AlegreyaSansSC-Light.otf
deleted file mode 100755
index 1d1dda3..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-Light.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-LightItalic.otf b/src/cover/fonts/AlegreyaSansSC-LightItalic.otf
deleted file mode 100755
index 74b9ab2..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-LightItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-Medium.otf b/src/cover/fonts/AlegreyaSansSC-Medium.otf
deleted file mode 100755
index 0b8aeb1..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-Medium.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-MediumItalic.otf b/src/cover/fonts/AlegreyaSansSC-MediumItalic.otf
deleted file mode 100755
index 98a07b5..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-MediumItalic.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-Regular.otf b/src/cover/fonts/AlegreyaSansSC-Regular.otf
deleted file mode 100755
index 424126e..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-Regular.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-Thin.otf b/src/cover/fonts/AlegreyaSansSC-Thin.otf
deleted file mode 100755
index e07b956..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-Thin.otf and /dev/null differ
diff --git a/src/cover/fonts/AlegreyaSansSC-ThinItalic.otf b/src/cover/fonts/AlegreyaSansSC-ThinItalic.otf
deleted file mode 100755
index 2bd07e0..0000000
Binary files a/src/cover/fonts/AlegreyaSansSC-ThinItalic.otf and /dev/null differ
diff --git a/src/cover/ribbon-ocaml.tex b/src/cover/ribbon-ocaml.tex
index 244d2ce..b610b2c 100644
--- a/src/cover/ribbon-ocaml.tex
+++ b/src/cover/ribbon-ocaml.tex
@@ -9,22 +9,22 @@
overlay,
remember picture,
ribbon/.style={anchor=center, rotate = 45,
- font={\fontsize{22}{1}\selectfont\bfseries}}
- ]
- \coordinate (A) at ($ (current page.south east) + (-\stripskip,0) $);% <-- changed coordinate from 'north' to south'
- \coordinate (A') at ($(A) + (-\stripwidth,0) $);
+ font={\fontsize{22}{1}\selectfont\bfseries}}
+ ]
+ \coordinate (A) at ($ (current page.south east) + (-\stripskip,0) $);% <-- changed coordinate from 'north' to south'
+ \coordinate (A') at ($(A) + (-\stripwidth,0) $);
- \coordinate (B) at ($ (current page.south east) + (0,\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \stripskip
- \coordinate (B') at ($(B) + (0,\stripwidth) $);% <-- changed sign for \stripskip
+ \coordinate (B) at ($ (current page.south east) + (0,\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \stripskip
+ \coordinate (B') at ($(B) + (0,\stripwidth) $);% <-- changed sign for \stripskip
- \fill [BurntOrange!20] (A) -- (A') -- (B') -- (B) -- cycle;
+ \fill [BurntOrange!20] (A) -- (A') -- (B') -- (B) -- cycle;
- \coordinate (tempA) at ($(A)!.5!(A')$);
- \coordinate (tempB) at ($(B)!.5!(B')$);
+ \coordinate (tempA) at ($(A)!.5!(A')$);
+ \coordinate (tempB) at ($(B)!.5!(B')$);
- \node [ribbon](text) at ($(tempA)!.5!(tempB)$) {
- \raisebox{-.15\height}{\includegraphics[width=.8cm]{\olpath/fig/icons/ocaml}}
- \hspace{.5mm} OCaml Edition
- };
+ \node [ribbon](text) at ($(tempA)!.5!(tempB)$) {
+ \raisebox{-.15\height}{\includegraphics[width=.8cm]{\olpath/fig/icons/ocaml}}
+ \hspace{.5mm} OCaml Edition
+ };
\end{tikzpicture}
\ No newline at end of file
diff --git a/src/cover/ribbon-reason.tex b/src/cover/ribbon-reason.tex
index 4d65368..276cad4 100644
--- a/src/cover/ribbon-reason.tex
+++ b/src/cover/ribbon-reason.tex
@@ -9,22 +9,22 @@
overlay,
remember picture,
ribbon/.style={anchor=center, rotate = 45,
- font={\fontsize{22}{1}\selectfont\bfseries}}
- ]
- \coordinate (A) at ($ (current page.south east) + (-\stripskip,0) $);% <-- changed coordinate from 'north' to south'
- \coordinate (A') at ($(A) + (-\stripwidth,0) $);
+ font={\fontsize{22}{1}\selectfont\bfseries}}
+ ]
+ \coordinate (A) at ($ (current page.south east) + (-\stripskip,0) $);% <-- changed coordinate from 'north' to south'
+ \coordinate (A') at ($(A) + (-\stripwidth,0) $);
- \coordinate (B) at ($ (current page.south east) + (0,\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \stripskip
- \coordinate (B') at ($(B) + (0,\stripwidth) $);% <-- changed sign for \stripskip
+ \coordinate (B) at ($ (current page.south east) + (0,\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \stripskip
+ \coordinate (B') at ($(B) + (0,\stripwidth) $);% <-- changed sign for \stripskip
- \fill [RedOrange!20] (A) -- (A') -- (B') -- (B) -- cycle;
+ \fill [RedOrange!20] (A) -- (A') -- (B') -- (B) -- cycle;
- \coordinate (tempA) at ($(A)!.5!(A')$);
- \coordinate (tempB) at ($(B)!.5!(B')$);
+ \coordinate (tempA) at ($(A)!.5!(A')$);
+ \coordinate (tempB) at ($(B)!.5!(B')$);
- \node [ribbon](text) at ($(tempA)!.5!(tempB)$) {
- \raisebox{-.15\height}{\includegraphics[width=.8cm]{\olpath/fig/icons/reason}}
- \hspace{.5mm} ReasonML Edition
- };
+ \node [ribbon](text) at ($(tempA)!.5!(tempB)$) {
+ \raisebox{-.15\height}{\includegraphics[width=.8cm]{\olpath/fig/icons/reason}}
+ \hspace{.5mm} ReasonML Edition
+ };
\end{tikzpicture}
\ No newline at end of file
diff --git a/src/cover/ribbon-scala.tex b/src/cover/ribbon-scala.tex
index feb566b..5a566fd 100644
--- a/src/cover/ribbon-scala.tex
+++ b/src/cover/ribbon-scala.tex
@@ -5,22 +5,22 @@
overlay,
remember picture,
ribbon/.style={anchor=center, rotate = 45,
- font={\fontsize{22}{1}\selectfont\bfseries}}
- ]
- \coordinate (A) at ($ (current page.south east) + (-\stripskip,0) $);% <-- changed coordinate from 'north' to south'
- \coordinate (A') at ($(A) + (-\stripwidth,0) $);
+ font={\fontsize{22}{1}\selectfont\bfseries}}
+ ]
+ \coordinate (A) at ($ (current page.south east) + (-\stripskip,0) $);% <-- changed coordinate from 'north' to south'
+ \coordinate (A') at ($(A) + (-\stripwidth,0) $);
- \coordinate (B) at ($ (current page.south east) + (0,\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \stripskip
- \coordinate (B') at ($(B) + (0,\stripwidth) $);% <-- changed sign for \stripskip
+ \coordinate (B) at ($ (current page.south east) + (0,\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \stripskip
+ \coordinate (B') at ($(B) + (0,\stripwidth) $);% <-- changed sign for \stripskip
- \fill [red!20] (A) -- (A') -- (B') -- (B) -- cycle;
+ \fill [red!20] (A) -- (A') -- (B') -- (B) -- cycle;
- \coordinate (tempA) at ($(A)!.5!(A')$);
- \coordinate (tempB) at ($(B)!.5!(B')$);
+ \coordinate (tempA) at ($(A)!.5!(A')$);
+ \coordinate (tempB) at ($(B)!.5!(B')$);
- \node [ribbon](text) at ($(tempA)!.5!(tempB)$) {
- \raisebox{-.30\height}{\includegraphics[width=.8cm]{\olpath/fig/icons/scala}}
- \hspace{.5mm} Scala Edition
- };
+ \node [ribbon](text) at ($(tempA)!.5!(tempB)$) {
+ \raisebox{-.30\height}{\includegraphics[width=.8cm]{\olpath/fig/icons/scala}}
+ \hspace{.5mm} Scala Edition
+ };
\end{tikzpicture}
\ No newline at end of file
diff --git a/src/fonts/Inconsolata-LGC-Bold.ttf b/src/fonts/Inconsolata-LGC-Bold.ttf
deleted file mode 100644
index bf71464..0000000
Binary files a/src/fonts/Inconsolata-LGC-Bold.ttf and /dev/null differ
diff --git a/src/fonts/Inconsolata-LGC-BoldItalic.ttf b/src/fonts/Inconsolata-LGC-BoldItalic.ttf
deleted file mode 100644
index e1d74fb..0000000
Binary files a/src/fonts/Inconsolata-LGC-BoldItalic.ttf and /dev/null differ
diff --git a/src/fonts/Inconsolata-LGC-Italic.ttf b/src/fonts/Inconsolata-LGC-Italic.ttf
deleted file mode 100644
index fa78ec9..0000000
Binary files a/src/fonts/Inconsolata-LGC-Italic.ttf and /dev/null differ
diff --git a/src/fonts/Inconsolata-LGC.ttf b/src/fonts/Inconsolata-LGC.ttf
deleted file mode 100644
index cdc366b..0000000
Binary files a/src/fonts/Inconsolata-LGC.ttf and /dev/null differ
diff --git a/src/fonts/LibertinusKeyboard-Regular.otf b/src/fonts/LibertinusKeyboard-Regular.otf
deleted file mode 100644
index d551e6a..0000000
Binary files a/src/fonts/LibertinusKeyboard-Regular.otf and /dev/null differ
diff --git a/src/fonts/LibertinusMath-Regular.otf b/src/fonts/LibertinusMath-Regular.otf
deleted file mode 100644
index 4e3c668..0000000
Binary files a/src/fonts/LibertinusMath-Regular.otf and /dev/null differ
diff --git a/src/fonts/LibertinusMono-Regular.otf b/src/fonts/LibertinusMono-Regular.otf
deleted file mode 100644
index 5cf805f..0000000
Binary files a/src/fonts/LibertinusMono-Regular.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSans-Bold.otf b/src/fonts/LibertinusSans-Bold.otf
deleted file mode 100644
index cae08b8..0000000
Binary files a/src/fonts/LibertinusSans-Bold.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSans-Italic.otf b/src/fonts/LibertinusSans-Italic.otf
deleted file mode 100644
index 5131cf2..0000000
Binary files a/src/fonts/LibertinusSans-Italic.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSans-Regular.otf b/src/fonts/LibertinusSans-Regular.otf
deleted file mode 100644
index d88c113..0000000
Binary files a/src/fonts/LibertinusSans-Regular.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerif-Bold.otf b/src/fonts/LibertinusSerif-Bold.otf
deleted file mode 100644
index 39a8ee5..0000000
Binary files a/src/fonts/LibertinusSerif-Bold.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerif-BoldItalic.otf b/src/fonts/LibertinusSerif-BoldItalic.otf
deleted file mode 100644
index d63f36e..0000000
Binary files a/src/fonts/LibertinusSerif-BoldItalic.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerif-Italic.otf b/src/fonts/LibertinusSerif-Italic.otf
deleted file mode 100644
index ddf1996..0000000
Binary files a/src/fonts/LibertinusSerif-Italic.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerif-Regular.otf b/src/fonts/LibertinusSerif-Regular.otf
deleted file mode 100644
index e42f25c..0000000
Binary files a/src/fonts/LibertinusSerif-Regular.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerif-Semibold.otf b/src/fonts/LibertinusSerif-Semibold.otf
deleted file mode 100644
index 4d3a026..0000000
Binary files a/src/fonts/LibertinusSerif-Semibold.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerif-SemiboldItalic.otf b/src/fonts/LibertinusSerif-SemiboldItalic.otf
deleted file mode 100644
index df0e632..0000000
Binary files a/src/fonts/LibertinusSerif-SemiboldItalic.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerifDisplay-Regular.otf b/src/fonts/LibertinusSerifDisplay-Regular.otf
deleted file mode 100644
index 9972f95..0000000
Binary files a/src/fonts/LibertinusSerifDisplay-Regular.otf and /dev/null differ
diff --git a/src/fonts/LibertinusSerifInitials-Regular.otf b/src/fonts/LibertinusSerifInitials-Regular.otf
deleted file mode 100644
index 7c1fc43..0000000
Binary files a/src/fonts/LibertinusSerifInitials-Regular.otf and /dev/null differ
diff --git a/src/half-title.tex b/src/half-title.tex
index f0f7abe..f5628c1 100644
--- a/src/half-title.tex
+++ b/src/half-title.tex
@@ -6,20 +6,20 @@
\vspace*{80pt}
\begin{raggedleft}
-\fontsize{24pt}{24pt}\selectfont
-\textbf{Category Theory \\ for Programmers}\\
-\ifdefined\OPTCustomLanguage{%
- \vspace*{1cm}
- \small\selectfont{
- \textbf{\OPTDisplayLanguageName{} Edition}\\
- \textit{Contains code snippets in Haskell and \OPTDisplayLanguageName}\\
+ \fontsize{24pt}{24pt}\selectfont
+ \textbf{Category Theory \\ for Programmers}\\
+ \ifdefined\OPTCustomLanguage{%
+ \vspace*{1cm}
+ \small\selectfont{
+ \textbf{\OPTDisplayLanguageName{} Edition}\\
+ \textit{Contains code snippets in Haskell and \OPTDisplayLanguageName}\\
+ }
}
-}
-\fi
-\vspace*{1cm}
-\fontsize{16pt}{18pt}\selectfont \textit{By } \textbf{Bartosz Milewski}\\
-\vspace{1cm}
-\fontsize{12pt}{14pt}\selectfont \textit{compiled and edited by}\\ \textbf{Igal Tabachnik}\\
+ \fi
+ \vspace*{1cm}
+ \fontsize{16pt}{18pt}\selectfont \textit{By } \textbf{Bartosz Milewski}\\
+ \vspace{1cm}
+ \fontsize{12pt}{14pt}\selectfont \textit{compiled and edited by}\\ \textbf{Igal Tabachnik}\\
\end{raggedleft}
@@ -30,37 +30,37 @@
\thispagestyle{empty}
\begin{small}
-\begin{center}
+ \begin{center}
-\textsc{Category Theory for Programmers}\\
+ \textsc{Category Theory for Programmers}\\
-\vspace{1.0em}
-\noindent
-Bartosz Milewski\\
+ \vspace{1.0em}
+ \noindent
+ Bartosz Milewski\\
-\vspace{1.26em}
-\noindent
-Version \texttt{\OPTversion}\\\today
+ \vspace{1.26em}
+ \noindent
+ Version \texttt{\OPTversion}\\\today
-\vspace{1.6em}
-\noindent
-\includegraphics[width=3mm]{fig/icons/cc.pdf}
-\includegraphics[width=3mm]{fig/icons/by.pdf}
-\includegraphics[width=3mm]{fig/icons/sa.pdf}
+ \vspace{1.6em}
+ \noindent
+ \includegraphics[width=3mm]{fig/icons/cc.pdf}
+ \includegraphics[width=3mm]{fig/icons/by.pdf}
+ \includegraphics[width=3mm]{fig/icons/sa.pdf}
-\vspace{0.4em}
-\noindent
-This work is licensed under a Creative Commons\\
-Attribution-ShareAlike 4.0 International License
-(\href{http://creativecommons.org/licenses/by-sa/4.0/}{\acronym{CC BY-SA 4.0}}).
+ \vspace{0.4em}
+ \noindent
+ This work is licensed under a Creative Commons\\
+ Attribution-ShareAlike 4.0 International License
+ (\href{http://creativecommons.org/licenses/by-sa/4.0/}{\acronym{CC BY-SA 4.0}}).
-\vspace{1.26em}
-\noindent
-Converted from a series of blog posts by \href{https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/}{Bartosz Milewski}.\\
-PDF and book compiled by \href{https://hmemcpy.com}{Igal Tabachnik}.\\
-\vspace{1.26em}
-\noindent
-\LaTeX{} source code is available on GitHub: \href{https://github.com/hmemcpy/milewski-ctfp-pdf}{https://github.com/hmemcpy/milewski-ctfp-pdf}
-\end{center}
+ \vspace{1.26em}
+ \noindent
+ Converted from a series of blog posts by \href{https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/}{Bartosz Milewski}.\\
+ PDF and book compiled by \href{https://hmemcpy.com}{Igal Tabachnik}.\\
+ \vspace{1.26em}
+ \noindent
+ \LaTeX{} source code is available on GitHub: \href{https://github.com/hmemcpy/milewski-ctfp-pdf}{https://github.com/hmemcpy/milewski-ctfp-pdf}
+ \end{center}
\end{small}
\ No newline at end of file
diff --git a/src/index.tex b/src/index.tex
index 7366e7f..e3bd0dd 100644
--- a/src/index.tex
+++ b/src/index.tex
@@ -1,9 +1,9 @@
\setindexprenote{\normalsize
-\begin{quote} Any inaccuracies in this index may be explained by the fact
-that it has been prepared with the help of a computer.
+ \begin{quote} Any inaccuracies in this index may be explained by the fact
+ that it has been prepared with the help of a computer.
----Donald E. Knuth, \textit{Fundamental Algorithms}\\
-(Volume 1 of \textit{The Art of Computer Programming})
-\end{quote}}
+ ---Donald E. Knuth, \textit{Fundamental Algorithms}\\
+ (Volume 1 of \textit{The Art of Computer Programming})
+ \end{quote}}
\printindex
\ No newline at end of file
diff --git a/src/preamble.tex b/src/preamble.tex
index 9056062..135cb3e 100644
--- a/src/preamble.tex
+++ b/src/preamble.tex
@@ -23,7 +23,7 @@
\defaultfontfeatures{% % is important for
Scale=MatchLowercase, % needed here ... % single quotes not
} % to turn out curly
-\setmonofont[Path=fonts/, BoldFont=Inconsolata-LGC-Bold.ttf]{Inconsolata-LGC-Bold.ttf} % ("typographic")
+\setmonofont[BoldFont=Inconsolata-LGC-Bold.ttf]{Inconsolata-LGC-Bold.ttf} % ("typographic")
% in verbatim blocks
\defaultfontfeatures{% % of Haskell code.
Scale=MatchLowercase, % ... and here again % Now the quote is
@@ -43,7 +43,7 @@
\expandafter\let\csname not<\endcsname\relax
\expandafter\let\csname not>\endcsname\relax
\usepackage{unicode-math}
-\setmathfont[Path=fonts/]{LibertinusMath-Regular.otf}
+\setmathfont{LibertinusMath-Regular.otf}
\usepackage[all]{nowidow}
\usepackage{emptypage}
@@ -170,6 +170,16 @@
{\end{Verbatim}\end{mdframed}
\vspace{-1ex}}
+% See the context about this workaround at
+% https://github.com/gpoore/minted/issues/354
+\makeatletter
+\ifwindows
+ \def\minted@opt@quote#1{\detokenize\expandafter{\expandafter"\expanded{#1}"}}
+\else
+ \def\minted@opt@quote#1{\detokenize\expandafter{\expandafter'\expanded{#1}'}}
+\fi
+\makeatother
+
\NewDocumentCommand\src{mO{}}{
\srcsnippet{\currfileabsdir/code/haskell/#1.hs}{blue}{haskell}{#2}
\ifdefined\OPTCustomLanguage{%
diff --git a/src/version.tex b/src/version.tex
new file mode 100644
index 0000000..d4d9223
--- /dev/null
+++ b/src/version.tex
@@ -0,0 +1 @@
+\newcommand\OPTversion{dev}
\ No newline at end of file