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 -Buy 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