├── .github ├── ISSUE_TEMPLATE │ └── 想法與相關內容.md └── workflows │ └── publish.yml ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── assets ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── fonts │ ├── KaTeX_AMS-Regular.ttf │ ├── KaTeX_AMS-Regular.woff │ ├── KaTeX_AMS-Regular.woff2 │ ├── KaTeX_Caligraphic-Bold.ttf │ ├── KaTeX_Caligraphic-Bold.woff │ ├── KaTeX_Caligraphic-Bold.woff2 │ ├── KaTeX_Caligraphic-Regular.ttf │ ├── KaTeX_Caligraphic-Regular.woff │ ├── KaTeX_Caligraphic-Regular.woff2 │ ├── KaTeX_Fraktur-Bold.ttf │ ├── KaTeX_Fraktur-Bold.woff │ ├── KaTeX_Fraktur-Bold.woff2 │ ├── KaTeX_Fraktur-Regular.ttf │ ├── KaTeX_Fraktur-Regular.woff │ ├── KaTeX_Fraktur-Regular.woff2 │ ├── KaTeX_Main-Bold.ttf │ ├── KaTeX_Main-Bold.woff │ ├── KaTeX_Main-Bold.woff2 │ ├── KaTeX_Main-BoldItalic.ttf │ ├── KaTeX_Main-BoldItalic.woff │ ├── KaTeX_Main-BoldItalic.woff2 │ ├── KaTeX_Main-Italic.ttf │ ├── KaTeX_Main-Italic.woff │ ├── KaTeX_Main-Italic.woff2 │ ├── KaTeX_Main-Regular.ttf │ ├── KaTeX_Main-Regular.woff │ ├── KaTeX_Main-Regular.woff2 │ ├── KaTeX_Math-BoldItalic.ttf │ ├── KaTeX_Math-BoldItalic.woff │ ├── KaTeX_Math-BoldItalic.woff2 │ ├── KaTeX_Math-Italic.ttf │ ├── KaTeX_Math-Italic.woff │ ├── KaTeX_Math-Italic.woff2 │ ├── KaTeX_SansSerif-Bold.ttf │ ├── KaTeX_SansSerif-Bold.woff │ ├── KaTeX_SansSerif-Bold.woff2 │ ├── KaTeX_SansSerif-Italic.ttf │ ├── KaTeX_SansSerif-Italic.woff │ ├── KaTeX_SansSerif-Italic.woff2 │ ├── KaTeX_SansSerif-Regular.ttf │ ├── KaTeX_SansSerif-Regular.woff │ ├── KaTeX_SansSerif-Regular.woff2 │ ├── KaTeX_Script-Regular.ttf │ ├── KaTeX_Script-Regular.woff │ ├── KaTeX_Script-Regular.woff2 │ ├── KaTeX_Size1-Regular.ttf │ ├── KaTeX_Size1-Regular.woff │ ├── KaTeX_Size1-Regular.woff2 │ ├── KaTeX_Size2-Regular.ttf │ ├── KaTeX_Size2-Regular.woff │ ├── KaTeX_Size2-Regular.woff2 │ ├── KaTeX_Size3-Regular.ttf │ ├── KaTeX_Size3-Regular.woff │ ├── KaTeX_Size3-Regular.woff2 │ ├── KaTeX_Size4-Regular.ttf │ ├── KaTeX_Size4-Regular.woff │ ├── KaTeX_Size4-Regular.woff2 │ ├── KaTeX_Typewriter-Regular.ttf │ ├── KaTeX_Typewriter-Regular.woff │ ├── KaTeX_Typewriter-Regular.woff2 │ ├── inria-sans-v14-latin_latin-ext-300.woff2 │ ├── inria-sans-v14-latin_latin-ext-300italic.woff2 │ ├── inria-sans-v14-latin_latin-ext-700.woff2 │ ├── inria-sans-v14-latin_latin-ext-700italic.woff2 │ ├── inria-sans-v14-latin_latin-ext-italic.woff2 │ └── inria-sans-v14-latin_latin-ext-regular.woff2 ├── forest.xsl ├── forester.sty ├── images │ ├── fp-000L │ │ └── injection.png │ ├── fp-000M │ │ └── surjection.png │ └── fp-000N │ │ └── bijection.png ├── katex.min.css ├── preamble.sty └── style.css ├── javascript └── forester.js ├── package-lock.json ├── package.json └── trees ├── alg-0001.tree ├── alg-0002.tree ├── alg-0003.tree ├── alg-0004.tree ├── alg-0005.tree ├── base-macros.tree ├── cat-0001.tree ├── cat-0002.tree ├── cat-0003.tree ├── cat-0004.tree ├── cat-0005.tree ├── cat-0006.tree ├── cat-0007.tree ├── cat-0008.tree ├── cat-0009.tree ├── cat-000A.tree ├── cs-0001.tree ├── fp-0001.tree ├── fp-0002.tree ├── fp-0003.tree ├── fp-0004.tree ├── fp-0005.tree ├── fp-0006.tree ├── fp-0007.tree ├── fp-0008.tree ├── fp-0009.tree ├── fp-000A.tree ├── fp-000B.tree ├── fp-000C.tree ├── fp-000D.tree ├── fp-000E.tree ├── fp-000F.tree ├── fp-000G.tree ├── fp-000H.tree ├── fp-000I.tree ├── fp-000J.tree ├── fp-000K.tree ├── fp-000L.tree ├── fp-000M.tree ├── fp-000N.tree ├── fp-000O.tree ├── fp-000P.tree ├── people ├── dannypsnl.tree └── fizzyelt.tree ├── roadmap.tree └── set-0001.tree /.github/ISSUE_TEMPLATE/想法與相關內容.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 想法與相關內容 3 | about: 紀錄自己的想法與理解 4 | title: "[主題] 標題" 5 | labels: documentation 6 | assignees: FizzyElt 7 | 8 | --- 9 | 10 | # [相關主題] 11 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: github pages 2 | on: 3 | push: 4 | branches: 5 | - main 6 | - forester 7 | paths: 8 | - trees/** 9 | - javascript/** 10 | - assets/** 11 | - Makefile 12 | - .github/workflows/publish.yml 13 | pull_request: 14 | branches: 15 | - main 16 | - forester 17 | 18 | jobs: 19 | deploy: 20 | runs-on: ubuntu-22.04 21 | steps: 22 | - uses: actions/checkout@v3 23 | with: 24 | fetch-depth: 1 25 | - name: "install emacs" 26 | run: sudo apt-get install -y emacs 27 | - name: Set-up OCaml 28 | uses: ocaml/setup-ocaml@v2 29 | with: 30 | ocaml-compiler: "5.1" 31 | 32 | - name: Install JS dependencies 33 | run: npm install 34 | 35 | - name: Install Forester 36 | run: | 37 | git clone https://git.sr.ht/~jonsterling/ocaml-forester 38 | cd ocaml-forester 39 | opam pin add -y . --locked 40 | 41 | - name: Setup TeX Live 42 | uses: teatimeguest/setup-texlive-action@v2 43 | with: 44 | packages: >- 45 | scheme-medium 46 | standalone 47 | mlmodern 48 | amsfonts 49 | amsmath 50 | zx-calculus 51 | tikz-cd 52 | l3packages 53 | dvisvgm 54 | pgf 55 | etoolbox 56 | mathtools 57 | stmaryrd 58 | newtx 59 | newpx 60 | xstring 61 | xpatch 62 | fontaxes 63 | kastrup 64 | spath3 65 | 66 | - name: Check `latex` version 67 | run: latex --version 68 | 69 | - name: "build forester" 70 | run: make release 71 | 72 | - name: "Deploy" 73 | uses: peaceiris/actions-gh-pages@v3 74 | with: 75 | github_token: ${{ secrets.GITHUB_TOKEN }} 76 | publish_dir: ./output 77 | publish_branch: gh-pages 78 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | latex/ 3 | output/ 4 | node_modules/ 5 | assets/forester.js 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 FizzyElt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | .PHONY: all 3 | 4 | serve: 5 | @$(if $(shell which forest), echo "forest-server installed", cargo install forest-server) 6 | @forest watch 1313 -- "build --dev --base-url https://fizzyelt.github.io/functional-programming --root fp-0001 trees/ " 7 | .PHONY: serve 8 | 9 | release: assets/forester.js theme 10 | @echo "Build forester" 11 | @opam exec -- forester build --base-url https://fizzyelt.github.io/functional-programming --root fp-0001 trees/ 12 | .PHONY: release 13 | 14 | build: assets/forester.js theme 15 | @echo "Build forester" 16 | @opam exec -- forester build --dev --base-url https://fizzyelt.github.io/functional-programming --root fp-0001 trees/ 17 | .PHONY: build 18 | 19 | theme: 20 | mkdir theme 21 | 22 | assets/forester.js: node_modules assets 23 | @echo "Build JS" 24 | @./node_modules/.bin/esbuild --minify --bundle javascript/forester.js --outfile=assets/forester.js 25 | 26 | node_modules: 27 | npm install 28 | 29 | deps: 30 | cargo install forest-server 31 | brew install watch texlive 32 | opam install forester 33 | .PHONY: deps 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Functional Programming 知識大補帖 2 | 3 | 這是一個關於 Functional Programming 名詞解釋及知識點整理的地方,會包含一些情境及範例解說,目的在於消除學習 FP 過程中因不懂緣由所產生的困惑。 4 | 5 | ## Roadmap 6 | 7 | 1. lambda calculus 8 | 2. 用 recursion 解釋可計算性 9 | 3. 加上 simply type 10 | 4. 解釋型別規則 11 | 5. 建立 STLC categorical semantic 12 | 6. 加上 polymorphism 13 | 7. 解釋型別規則 14 | 8. 建立 \(E \to B\) categorical semantic 15 | 9. 解釋 \(\lambda 2\) 的 polymorphic property 16 | 10. 解釋 recursive type 17 | 11. 連結 F-algebra 18 | 12. 變成 dependent type 19 | 13. 解釋型別規則 20 | 14. 解釋模型(The natural model) 21 | - topos 22 | - topos fundamental theorem 23 | - presheaf 24 | - representable natural transformation 25 | 15. 進入真正的應用 26 | 16. side effect 27 | 17. concurrency 28 | 18. 安全性 29 | - 記憶體安全與子結構類型 30 | - (?) proof nets 31 | - 整體安全性不是只關乎記憶體 32 | 19. domain language 33 | 34 | ### ⚠️ 部份完成小主題內容,整理後移除 35 | 36 | - [pure function](./trees/fp-000J.tree) 37 | - immutable 38 | - curry 39 | - Lazy semantic 40 | - [data first, data last](./trees/fp-0002.tree) 41 | - [Magma](./trees/alg-0001.tree) 42 | - [Semigroup](./trees/alg-0003.tree) 43 | - [Monoid](./trees/alg-0005.tree) 44 | - [Functor](./trees/cat-0003.tree) 45 | - Applicative 46 | - Monad 47 | 48 | ## Development 49 | 50 | - [forester](https://www.jonmsterling.com/jms-005P.xml) 51 | - https://en.wikipedia.org/wiki/MacTeX 52 | 53 | Build command 54 | 55 | ```shell 56 | make build 57 | ``` 58 | 59 | Locally watch server 60 | 61 | ```shell 62 | ./server.sh 63 | ``` 64 | 65 | ## Contribution 66 | 67 | 建立新的 tree,prefix 根據你的內容的主題更換 68 | 69 | 目前現有的主題 70 | 71 | - fp (functional programming) 72 | - alg (algebra) 73 | - cat (category) 74 | - set 75 | 76 | ```bash 77 | forester new prefix=fp 78 | ``` 79 | 80 | 基本內容,如果是修改現有的 tree 就新增 author 上去 81 | 82 | ```text 83 | \title{XXX} 84 | \author{name} 85 | ``` 86 | 87 | 如果你願意貢獻你的一些資訊可以在 `trees/person` 資料夾開一個 tree 88 | 89 | trees/person/xxxx.tree 90 | 91 | ```text 92 | \title{XXXXX} 93 | \taxon{person} 94 | \meta{position}{Front-End Developer} 95 | \meta{external}{xxxxx.com} 96 | ``` 97 | 98 | 將你的內容關聯到某個 tree 內 99 | 100 | xx-XXXX.tree 101 | 102 | ```text 103 | \transclude{xx-XXXX} 104 | ``` 105 | 106 | 提及 xx-XXXX.tree 107 | 108 | ```text 109 | [text](xx-XXXX) 110 | ``` 111 | -------------------------------------------------------------------------------- /assets/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/android-chrome-192x192.png -------------------------------------------------------------------------------- /assets/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/android-chrome-512x512.png -------------------------------------------------------------------------------- /assets/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/apple-touch-icon.png -------------------------------------------------------------------------------- /assets/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/favicon-16x16.png -------------------------------------------------------------------------------- /assets/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/favicon-32x32.png -------------------------------------------------------------------------------- /assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/favicon.ico -------------------------------------------------------------------------------- /assets/fonts/KaTeX_AMS-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_AMS-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_AMS-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_AMS-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_AMS-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_AMS-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Caligraphic-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Caligraphic-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Caligraphic-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Caligraphic-Bold.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Caligraphic-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Caligraphic-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Caligraphic-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Caligraphic-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Caligraphic-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Caligraphic-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Caligraphic-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Caligraphic-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Fraktur-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Fraktur-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Fraktur-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Fraktur-Bold.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Fraktur-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Fraktur-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Fraktur-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Fraktur-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Fraktur-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Fraktur-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Fraktur-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Fraktur-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Bold.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-BoldItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-BoldItalic.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-BoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Italic.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Main-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Main-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Math-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Math-BoldItalic.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Math-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Math-BoldItalic.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Math-BoldItalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Math-BoldItalic.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Math-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Math-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Math-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Math-Italic.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Math-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Math-Italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Bold.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Bold.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Bold.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Italic.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Italic.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_SansSerif-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_SansSerif-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Script-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Script-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Script-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Script-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Script-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Script-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size1-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size1-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size1-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size1-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size1-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size1-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size2-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size2-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size2-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size2-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size2-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size2-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size3-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size3-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size3-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size3-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size3-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size3-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size4-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size4-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size4-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size4-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Size4-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Size4-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Typewriter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Typewriter-Regular.ttf -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Typewriter-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Typewriter-Regular.woff -------------------------------------------------------------------------------- /assets/fonts/KaTeX_Typewriter-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/KaTeX_Typewriter-Regular.woff2 -------------------------------------------------------------------------------- /assets/fonts/inria-sans-v14-latin_latin-ext-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/inria-sans-v14-latin_latin-ext-300.woff2 -------------------------------------------------------------------------------- /assets/fonts/inria-sans-v14-latin_latin-ext-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/inria-sans-v14-latin_latin-ext-300italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inria-sans-v14-latin_latin-ext-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/inria-sans-v14-latin_latin-ext-700.woff2 -------------------------------------------------------------------------------- /assets/fonts/inria-sans-v14-latin_latin-ext-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/inria-sans-v14-latin_latin-ext-700italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inria-sans-v14-latin_latin-ext-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/inria-sans-v14-latin_latin-ext-italic.woff2 -------------------------------------------------------------------------------- /assets/fonts/inria-sans-v14-latin_latin-ext-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/fonts/inria-sans-v14-latin_latin-ext-regular.woff2 -------------------------------------------------------------------------------- /assets/forest.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 10 | 11 | 12 | 13 | [ 14 | 15 | ] 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | January 33 | 34 | 35 | February 36 | 37 | 38 | March 39 | 40 | 41 | April 42 | 43 | 44 | May 45 | 46 | 47 | June 48 | 49 | 50 | July 51 | 52 | 53 | August 54 | 55 | 56 | September 57 | 58 | 59 | October 60 | 61 | 62 | November 63 | 64 | 65 | December 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | , 77 | 78 | 79 | 80 | 81 | 82 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | \[ 111 | 112 | \] 113 | 114 | 115 | 116 | \( 117 | 118 | \) 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | « Home 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 161 | 162 | 163 | Table of Contents 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | #tree- 179 | 180 | 181 | 182 | 183 | 184 | 185 | . 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | , 213 | 214 | 215 | 216 | with contributions from 217 | 218 | 219 | 220 | , 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | [ 241 | 242 | ] 243 | 244 | 245 | 246 | 247 | 248 | [edit] 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | Slides 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | Video 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | . 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | . 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | . 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | References 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | Context 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | Contributions 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | Related 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | Backlinks 402 | 403 | 404 | 405 | 406 | 407 | 408 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | block hide-metadata 429 | 430 | 431 | block 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | open 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | -------------------------------------------------------------------------------- /assets/forester.sty: -------------------------------------------------------------------------------- 1 | \RequirePackage{xparse} 2 | \RequirePackage{graphicx} 3 | \RequirePackage[dvipsnames]{xcolor} 4 | \RequirePackage{hyperref} 5 | \RequirePackage{xspace} 6 | \RequirePackage{mparhack} 7 | \RequirePackage{newpxtext,newpxmath} 8 | 9 | \definecolor{Matterhorn}{RGB}{77,77,77} 10 | \definecolor{RegalBlue}{RGB}{3,69,117} 11 | \definecolor{DarkBlue}{RGB}{3,69,117} 12 | \definecolor{FunGreen}{RGB}{14,87,54} 13 | \definecolor{VerdunGreen}{RGB}{54,87,14} 14 | \definecolor{RedDevil}{RGB}{134,1,17} 15 | \definecolor{DarkRed}{RGB}{134,1,17} 16 | 17 | \hypersetup{ 18 | colorlinks = true, 19 | linkcolor = Matterhorn, 20 | } 21 | 22 | \setcounter{secnumdepth}{5} 23 | 24 | \newcounter{forest} 25 | 26 | \ExplSyntaxOn 27 | 28 | \tl_new:N \l__forester_current_counter 29 | \clist_new:N \l__forester_counters 30 | \clist_set:Nn \l__forester_counters {section,subsection,subsubsection,paragraph,subparagraph} 31 | 32 | \keys_define:nn { forester } { 33 | treeCommands .clist_set:N = \l__forester_counters, 34 | forestSite .tl_set:N = \l__forester_site, 35 | } 36 | 37 | \keys_define:nn { forester_tree } { 38 | title .tl_set:N = \l__forester_tree_title, 39 | taxon .tl_set:N = \l__forester_tree_taxon, 40 | slug .tl_set:N = \l__forester_tree_slug, 41 | } 42 | 43 | \cs_new:Npn \forester_format_slug:n #1 { 44 | \textcolor{gray}{\texttt{#1}} 45 | } 46 | 47 | \cs_new:Npn \forester_slug_url:n #1 { 48 | \l__forester_site / #1.xml 49 | } 50 | 51 | \cs_new:Npn \forester_format_slug_link:n #1 { 52 | \tl_if_empty:NTF \l__forester_site { 53 | \hyperref[#1]{\forester_format_slug:n {#1}} 54 | } { 55 | \href{\forester_slug_url:n {#1}}{ 56 | \forester_format_slug:n {#1} 57 | } 58 | } 59 | } 60 | 61 | \cs_new:Npn \forester_format_result: { 62 | \medskip\par\noindent 63 | \marginpar{\forester_format_slug_link:n {\l__forester_tree_slug}} 64 | \textbf{\text_titlecase_first:n{\l__forester_tree_taxon}~\use:c{the\l__forester_current_counter}} 65 | \tl_if_empty:NTF \l__forester_tree_title {} {~(\l__forester_tree_title)} 66 | .\xspace 67 | } 68 | 69 | \cs_new:Npn \forester_format_section: { 70 | \use:c{\l__forester_current_counter}[ 71 | \text_titlecase_first:n{\l__forester_tree_title} 72 | ]{ 73 | \text_titlecase_first:n{\l__forester_tree_title} 74 | \marginpar{\forester_format_slug_link:n {\l__forester_tree_slug}} 75 | } 76 | } 77 | 78 | \NewDocumentEnvironment{tree}{m}{ 79 | \group_begin: 80 | \keys_set:nn { forester_tree } {#1} 81 | \clist_pop:NN \l__forester_counters \l__forester_current_counter 82 | \tl_if_empty:NTF \l__forester_tree_taxon { 83 | \forester_format_section: 84 | } { 85 | \refstepcounter{\l__forester_current_counter} 86 | \addcontentsline{toc}{\l__forester_current_counter}{ 87 | \protect{\numberline{\use:c{the\l__forester_current_counter}}} 88 | \textbf{\text_titlecase_first:n{\l__forester_tree_taxon}} 89 | \tl_if_empty:NTF \l__forester_tree_title {} {~(\l__forester_tree_title)} 90 | } 91 | \forester_format_result: 92 | } 93 | \bool_if_exist:cTF {g__forester_slug_defined_\l__forester_tree_slug} {} { 94 | \label{\l__forester_tree_slug} 95 | \bool_gset_true:c {g__forester_slug_defined_\l__forester_tree_slug} 96 | } 97 | }{ 98 | \medskip 99 | \group_end: 100 | } 101 | 102 | \cs_new:Npn \forester_ref:nn #1 #2 { 103 | \cs_if_exist:cTF {r@#1} { 104 | \hyperref[#1]{#2} 105 | } { 106 | #2~\cite{#1} 107 | } 108 | } 109 | 110 | \NewDocumentCommand\ForesterSetup{+m}{ 111 | \keys_set:nn { forester } { #1 } 112 | } 113 | 114 | \NewDocumentCommand\ForesterRef{mm}{ 115 | \forester_ref:nn {#1} {#2} 116 | } 117 | 118 | \ExplSyntaxOff 119 | 120 | 121 | -------------------------------------------------------------------------------- /assets/images/fp-000L/injection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/images/fp-000L/injection.png -------------------------------------------------------------------------------- /assets/images/fp-000M/surjection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/images/fp-000M/surjection.png -------------------------------------------------------------------------------- /assets/images/fp-000N/bijection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FizzyElt/functional-programming/7cb0e08a9172c5df39cdd65735e4c63d9fe27ce9/assets/images/fp-000N/bijection.png -------------------------------------------------------------------------------- /assets/katex.min.css: -------------------------------------------------------------------------------- 1 | @font-face{font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(fonts/KaTeX_AMS-Regular.woff2) format("woff2"),url(fonts/KaTeX_AMS-Regular.woff) format("woff"),url(fonts/KaTeX_AMS-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Caligraphic-Bold.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Bold.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Caligraphic-Regular.woff2) format("woff2"),url(fonts/KaTeX_Caligraphic-Regular.woff) format("woff"),url(fonts/KaTeX_Caligraphic-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Fraktur-Bold.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Bold.woff) format("woff"),url(fonts/KaTeX_Fraktur-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Fraktur-Regular.woff2) format("woff2"),url(fonts/KaTeX_Fraktur-Regular.woff) format("woff"),url(fonts/KaTeX_Fraktur-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(fonts/KaTeX_Main-Bold.woff2) format("woff2"),url(fonts/KaTeX_Main-Bold.woff) format("woff"),url(fonts/KaTeX_Main-Bold.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Main-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Main-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Main-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Main-Italic.woff2) format("woff2"),url(fonts/KaTeX_Main-Italic.woff) format("woff"),url(fonts/KaTeX_Main-Italic.ttf) format("truetype")}@font-face{font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Main-Regular.woff2) format("woff2"),url(fonts/KaTeX_Main-Regular.woff) format("woff"),url(fonts/KaTeX_Main-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(fonts/KaTeX_Math-BoldItalic.woff2) format("woff2"),url(fonts/KaTeX_Math-BoldItalic.woff) format("woff"),url(fonts/KaTeX_Math-BoldItalic.ttf) format("truetype")}@font-face{font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(fonts/KaTeX_Math-Italic.woff2) format("woff2"),url(fonts/KaTeX_Math-Italic.woff) format("woff"),url(fonts/KaTeX_Math-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:700;src:url(fonts/KaTeX_SansSerif-Bold.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Bold.woff) format("woff"),url(fonts/KaTeX_SansSerif-Bold.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:italic;font-weight:400;src:url(fonts/KaTeX_SansSerif-Italic.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Italic.woff) format("woff"),url(fonts/KaTeX_SansSerif-Italic.ttf) format("truetype")}@font-face{font-family:"KaTeX_SansSerif";font-style:normal;font-weight:400;src:url(fonts/KaTeX_SansSerif-Regular.woff2) format("woff2"),url(fonts/KaTeX_SansSerif-Regular.woff) format("woff"),url(fonts/KaTeX_SansSerif-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Script-Regular.woff2) format("woff2"),url(fonts/KaTeX_Script-Regular.woff) format("woff"),url(fonts/KaTeX_Script-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size1-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size1-Regular.woff) format("woff"),url(fonts/KaTeX_Size1-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size2-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size2-Regular.woff) format("woff"),url(fonts/KaTeX_Size2-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size3-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size3-Regular.woff) format("woff"),url(fonts/KaTeX_Size3-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Size4-Regular.woff2) format("woff2"),url(fonts/KaTeX_Size4-Regular.woff) format("woff"),url(fonts/KaTeX_Size4-Regular.ttf) format("truetype")}@font-face{font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(fonts/KaTeX_Typewriter-Regular.woff2) format("woff2"),url(fonts/KaTeX_Typewriter-Regular.woff) format("woff"),url(fonts/KaTeX_Typewriter-Regular.ttf) format("truetype")}.katex{text-rendering:auto;font:normal 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;text-indent:0}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.16.8"}.katex .katex-mathml{clip:rect(1px,1px,1px,1px);border:0;height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} 2 | -------------------------------------------------------------------------------- /assets/preamble.sty: -------------------------------------------------------------------------------- 1 | \usepackage{tikz, tikz-cd, mathtools, amssymb, stmaryrd} 2 | \usetikzlibrary{matrix,arrows} 3 | \usetikzlibrary{fit,positioning,calc,shapes} 4 | \usetikzlibrary{decorations.pathreplacing} 5 | \usetikzlibrary{decorations.pathmorphing} 6 | \usetikzlibrary{decorations.markings} 7 | 8 | \tikzset{ 9 | desc/.style={sloped, fill=white,inner sep=2pt}, 10 | upright desc/.style={fill=white,inner sep=2pt}, 11 | pullback/.style = { 12 | append after command={ 13 | \pgfextra{ 14 | \draw ($(\tikzlastnode) + (.2cm,-.5cm)$) -- ++(0.3cm,0) -- ++(0,0.3cm); 15 | } 16 | } 17 | }, 18 | pullback 45/.style = { 19 | append after command={ 20 | \pgfextra{ 21 | \draw[rotate = 45] ($(\tikzlastnode) + (.2cm,-.5cm)$) -- ++(0.3cm,0) -- ++(0,0.3cm); 22 | } 23 | } 24 | }, 25 | ne pullback/.style = { 26 | append after command={ 27 | \pgfextra{ 28 | \draw ($(\tikzlastnode) + (-.2cm,-.5cm)$) -- ++(-0.3cm,0) -- ++(0,0.3cm); 29 | } 30 | } 31 | }, 32 | sw pullback/.style = { 33 | append after command={ 34 | \pgfextra{ 35 | \draw ($(\tikzlastnode) + (.2cm,.5cm)$) -- ++(0.3cm,0) -- ++(0,-0.3cm); 36 | } 37 | } 38 | }, 39 | dotted pullback/.style = { 40 | append after command={ 41 | \pgfextra{ 42 | \draw [densely dotted] ($(\tikzlastnode) + (.2cm,-.5cm)$) -- ++(0.3cm,0) -- ++(0,0.3cm); 43 | } 44 | } 45 | }, 46 | muted pullback/.style = { 47 | append after command={ 48 | \pgfextra{ 49 | \draw [gray] ($(\tikzlastnode) + (.2cm,-.5cm)$) -- ++(0.3cm,0) -- ++(0,0.3cm); 50 | } 51 | } 52 | }, 53 | pushout/.style = { 54 | append after command={ 55 | \pgfextra{ 56 | \draw ($(\tikzlastnode) + (-.2cm,.5cm)$) -- ++(-0.3cm,0) -- ++(0,-0.3cm); 57 | } 58 | } 59 | }, 60 | between/.style args={#1 and #2}{ 61 | at = ($(#1)!0.5!(#2)$) 62 | }, 63 | diagram/.style = { 64 | on grid, 65 | node distance=2cm, 66 | commutative diagrams/every diagram, 67 | line width = .5pt, 68 | every node/.append style = { 69 | commutative diagrams/every cell, 70 | } 71 | }, 72 | fibration/.style = { 73 | -{Triangle[open]} 74 | }, 75 | etale/.style = { 76 | -{Triangle[open]} 77 | }, 78 | etale cover/.style= { 79 | >={Triangle[open]},->.> 80 | }, 81 | opfibration/.style = { 82 | -{Triangle} 83 | }, 84 | lies over/.style = { 85 | |-{Triangle[open]} 86 | }, 87 | op lies over/.style = { 88 | |-{Triangle} 89 | }, 90 | embedding/.style = { 91 | {right hook}-> 92 | }, 93 | open immersion/.style = { 94 | {right hook}-{Triangle[open]} 95 | }, 96 | closed immersion/.style = { 97 | {right hook}-{Triangle} 98 | }, 99 | closed immersion*/.style = { 100 | {left hook}-{Triangle} 101 | }, 102 | embedding*/.style = { 103 | {left hook}-> 104 | }, 105 | open immersion*/.style = { 106 | {left hook}-{Triangle[open]} 107 | }, 108 | exists/.style = { 109 | densely dashed 110 | }, 111 | } 112 | 113 | \newlength{\dontworryaboutit} 114 | 115 | \tikzset{ 116 | inline diagram/.style = { 117 | commutative diagrams/every diagram, 118 | commutative diagrams/cramped, 119 | line width = .5pt, 120 | every node/.append style = { 121 | commutative diagrams/every cell, 122 | anchor = base, 123 | inner sep = 0pt 124 | }, 125 | every path/.append style = { 126 | outer xsep = 2pt 127 | } 128 | } 129 | } 130 | 131 | \tikzset{ 132 | square/nw/.style = {}, 133 | square/ne/.style = {}, 134 | square/se/.style = {}, 135 | square/sw/.style = {}, 136 | square/north/.style = {->}, 137 | square/south/.style = {->}, 138 | square/west/.style = {->}, 139 | square/east/.style = {->}, 140 | square/north/node/.style = {above}, 141 | square/south/node/.style = {below}, 142 | square/west/node/.style = {left}, 143 | square/east/node/.style = {right}, 144 | } 145 | 146 | \ExplSyntaxOn 147 | 148 | \bool_new:N \l_jon_glue_west 149 | 150 | \keys_define:nn { jon-tikz/diagram } { 151 | nw .tl_set:N = \l_jon_tikz_diagram_nw, 152 | sw .tl_set:N = \l_jon_tikz_diagram_sw, 153 | ne .tl_set:N = \l_jon_tikz_diagram_ne, 154 | se .tl_set:N = \l_jon_tikz_diagram_se, 155 | 156 | width .tl_set:N = \l_jon_tikz_diagram_width, 157 | height .tl_set:N = \l_jon_tikz_diagram_height, 158 | 159 | north .tl_set:N = \l_jon_tikz_diagram_north, 160 | south .tl_set:N = \l_jon_tikz_diagram_south, 161 | west .tl_set:N = \l_jon_tikz_diagram_west, 162 | east .tl_set:N = \l_jon_tikz_diagram_east, 163 | 164 | nw/style .code:n = {\tikzset{square/nw/.style = {#1}}}, 165 | sw/style .code:n = {\tikzset{square/sw/.style = {#1}}}, 166 | ne/style .code:n = {\tikzset{square/ne/.style = {#1}}}, 167 | se/style .code:n = {\tikzset{square/se/.style = {#1}}}, 168 | 169 | glue .choice:, 170 | glue / west .code:n = {\bool_set:Nn \l_jon_glue_west \c_true_bool}, 171 | 172 | glue~target .tl_set:N = \l_jon_tikz_glue_target, 173 | 174 | north/style .code:n = {\tikzset{square/north/.style = {#1}}}, 175 | north/node/style .code:n = {\tikzset{square/north/node/.style = {#1}}}, 176 | south/style .code:n = {\tikzset{square/south/.style = {#1}}}, 177 | south/node/style .code:n = {\tikzset{square/south/node/.style = {#1}}}, 178 | west/style .code:n = {\tikzset{square/west/.style = {#1}}}, 179 | west/node/style .code:n = {\tikzset{square/west/node/.style = {#1}}}, 180 | east/style .code:n = {\tikzset{square/east/.style = {#1}}}, 181 | east/node/style .code:n = {\tikzset{square/east/node/.style = {#1}}}, 182 | 183 | draft .meta:n = { 184 | nw = {\__jon_tikz_diagram_fmt_placeholder:n {nw}}, 185 | sw = {\__jon_tikz_diagram_fmt_placeholder:n {sw}}, 186 | se = {\__jon_tikz_diagram_fmt_placeholder:n {se}}, 187 | ne = {\__jon_tikz_diagram_fmt_placeholder:n {ne}}, 188 | north = {\__jon_tikz_diagram_fmt_placeholder:n {north}}, 189 | south = {\__jon_tikz_diagram_fmt_placeholder:n {south}}, 190 | west = {\__jon_tikz_diagram_fmt_placeholder:n {west}}, 191 | east = {\__jon_tikz_diagram_fmt_placeholder:n {east}}, 192 | } 193 | } 194 | 195 | \tl_set:Nn \l_jon_tikz_diagram_width { 2cm } 196 | \tl_set:Nn \l_jon_tikz_diagram_height { 2cm } 197 | 198 | 199 | \cs_new:Npn \__jon_tikz_diagram_fmt_placeholder:n #1 { 200 | \texttt{\textcolor{red}{#1}} 201 | } 202 | 203 | \keys_set:nn { jon-tikz/diagram } { 204 | glue~target = {}, 205 | } 206 | 207 | 208 | \cs_new:Nn \__jon_tikz_render_square:nn { 209 | \group_begin: 210 | \keys_set:nn {jon-tikz/diagram} {#2} 211 | \bool_if:nTF \l_jon_glue_west { 212 | \node (#1ne) [right = \l_jon_tikz_diagram_width~of~\l_jon_tikz_glue_target ne,square/ne] {$\l_jon_tikz_diagram_ne$}; 213 | \node (#1se) [below = \l_jon_tikz_diagram_height~of~#1ne,square/se] {$\l_jon_tikz_diagram_se$}; 214 | \draw[square/north] (\l_jon_tikz_glue_target ne) to node [square/north/node] {$\l_jon_tikz_diagram_north$} (#1ne); 215 | \draw[square/east] (#1ne) to node [square/east/node] {$\l_jon_tikz_diagram_east$} (#1se); 216 | \draw[square/south] (\l_jon_tikz_glue_target se) to node [square/south/node] {$\l_jon_tikz_diagram_south$} (#1se); 217 | } { 218 | \node (#1nw) [square/nw] {$\l_jon_tikz_diagram_nw$}; 219 | \node (#1sw) [below = \l_jon_tikz_diagram_height~of~#1nw,square/sw] {$\l_jon_tikz_diagram_sw$}; 220 | \draw[square/west] (#1nw) to node [square/west/node] {$\l_jon_tikz_diagram_west$} (#1sw); 221 | 222 | \node (#1ne) [right = \l_jon_tikz_diagram_width~of~#1nw,square/ne] {$\l_jon_tikz_diagram_ne$}; 223 | \node (#1se) [below = \l_jon_tikz_diagram_height~of~#1ne,square/se] {$\l_jon_tikz_diagram_se$}; 224 | \draw[square/north] (#1nw) to node [square/north/node] {$\l_jon_tikz_diagram_north$} (#1ne); 225 | \draw[square/east] (#1ne) to node [square/east/node] {$\l_jon_tikz_diagram_east$} (#1se); 226 | \draw[square/south] (#1sw) to node [square/south/node] {$\l_jon_tikz_diagram_south$} (#1se); 227 | } 228 | \group_end: 229 | } 230 | 231 | \NewDocumentCommand\SpliceDiagramSquare{D<>{}m}{ 232 | \__jon_tikz_render_square:nn {#1} {#2} 233 | } 234 | 235 | 236 | \NewDocumentCommand\DiagramSquare{D<>{}O{}m}{ 237 | \begin{tikzpicture}[diagram,#2,baseline=(#1sw.base)] 238 | \__jon_tikz_render_square:nn {#1} {#3} 239 | \end{tikzpicture} 240 | } 241 | 242 | \ExplSyntaxOff 243 | -------------------------------------------------------------------------------- /assets/style.css: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: CC0-1.0 */ 2 | 3 | /* inria-sans-300 - latin_latin-ext */ 4 | @font-face { 5 | font-display: swap; 6 | /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 7 | font-family: 'Inria Sans'; 8 | font-style: normal; 9 | font-weight: 300; 10 | src: url('fonts/inria-sans-v14-latin_latin-ext-300.woff2') format('woff2'); 11 | /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 12 | } 13 | 14 | /* inria-sans-300italic - latin_latin-ext */ 15 | @font-face { 16 | font-display: swap; 17 | /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 18 | font-family: 'Inria Sans'; 19 | font-style: italic; 20 | font-weight: 300; 21 | src: url('fonts/inria-sans-v14-latin_latin-ext-300italic.woff2') format('woff2'); 22 | /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 23 | } 24 | 25 | /* inria-sans-regular - latin_latin-ext */ 26 | @font-face { 27 | font-display: swap; 28 | /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 29 | font-family: 'Inria Sans'; 30 | font-style: normal; 31 | font-weight: 400; 32 | src: url('fonts/inria-sans-v14-latin_latin-ext-regular.woff2') format('woff2'); 33 | /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 34 | } 35 | 36 | /* inria-sans-italic - latin_latin-ext */ 37 | @font-face { 38 | font-display: swap; 39 | /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 40 | font-family: 'Inria Sans'; 41 | font-style: italic; 42 | font-weight: 400; 43 | src: url('fonts/inria-sans-v14-latin_latin-ext-italic.woff2') format('woff2'); 44 | /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 45 | } 46 | 47 | /* inria-sans-700 - latin_latin-ext */ 48 | @font-face { 49 | font-display: swap; 50 | /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 51 | font-family: 'Inria Sans'; 52 | font-style: normal; 53 | font-weight: 700; 54 | src: url('fonts/inria-sans-v14-latin_latin-ext-700.woff2') format('woff2'); 55 | /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 56 | } 57 | 58 | /* inria-sans-700italic - latin_latin-ext */ 59 | @font-face { 60 | font-display: swap; 61 | /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */ 62 | font-family: 'Inria Sans'; 63 | font-style: italic; 64 | font-weight: 700; 65 | src: url('fonts/inria-sans-v14-latin_latin-ext-700italic.woff2') format('woff2'); 66 | /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */ 67 | } 68 | 69 | :root { 70 | --content-gap: 15px; 71 | --radius: 5px; 72 | } 73 | 74 | h1, 75 | h2, 76 | h3, 77 | h4, 78 | h5, 79 | h6 { 80 | line-height: 1.2; 81 | margin-bottom: 0; 82 | } 83 | 84 | h5, 85 | h6, 86 | p { 87 | margin-top: 0; 88 | } 89 | 90 | h1, 91 | h2, 92 | h3, 93 | h4 { 94 | margin-top: .5em; 95 | } 96 | 97 | pre, 98 | img, 99 | .katex-display, 100 | section, 101 | center { 102 | overflow-y: hidden; 103 | } 104 | 105 | pre { 106 | border-radius: var(--radius); 107 | background-color: rgba(0, 100, 100, 0.04); 108 | padding: .5em; 109 | font-size: 11pt; 110 | margin-top: 0em; 111 | overflow-x: auto; 112 | white-space: pre-wrap; 113 | white-space: -moz-pre-wrap; 114 | white-space: -pre-wrap; 115 | white-space: -o-pre-wrap; 116 | word-wrap: break-word; 117 | } 118 | 119 | code { 120 | border-radius: var(--radius); 121 | background-color: rgba(0, 100, 100, 0.04); 122 | padding: 0.2em; 123 | font-size: 11pt; 124 | } 125 | 126 | body { 127 | font-family: "Inria Sans"; 128 | font-size: 12pt; 129 | line-height: 1.5em; 130 | } 131 | 132 | .logo { 133 | font-weight: 1000; 134 | font-size: 24px; 135 | } 136 | 137 | .logo a { 138 | color: #666; 139 | text-decoration: none; 140 | } 141 | 142 | .logo a:hover { 143 | color: #aaa; 144 | } 145 | 146 | .block.hide-metadata>details>summary>header>.metadata { 147 | display: none; 148 | } 149 | 150 | article>section>details>summary>header>h1>.taxon { 151 | display: block; 152 | font-size: .9em; 153 | color: #888; 154 | padding-bottom: 5pt; 155 | } 156 | 157 | section section[data-taxon="Reference"]>details>summary>header>h1>.taxon, 158 | section section[data-taxon="Person"]>details>summary>header>h1>.taxon { 159 | display: none; 160 | } 161 | 162 | footer>section { 163 | margin-bottom: 1em; 164 | } 165 | 166 | footer h2 { 167 | font-size: 14pt; 168 | } 169 | 170 | .metadata>address { 171 | display: inline; 172 | } 173 | 174 | @media only screen and (max-width: 1000px) { 175 | body { 176 | margin-top: 1em; 177 | margin-left: .5em; 178 | margin-right: .5em; 179 | transition: ease all .2s; 180 | } 181 | 182 | #grid-wrapper>nav { 183 | display: none; 184 | transition: ease all .2s; 185 | } 186 | } 187 | 188 | @media only screen and (min-width: 1000px) { 189 | body { 190 | margin-top: 2em; 191 | margin-left: 2em; 192 | transition: ease all .2s; 193 | } 194 | 195 | #grid-wrapper { 196 | display: grid; 197 | grid-template-columns: 90ex; 198 | } 199 | } 200 | 201 | body>header { 202 | margin-bottom: 2em; 203 | } 204 | 205 | #grid-wrapper>article { 206 | max-width: 90ex; 207 | margin-right: auto; 208 | grid-column: 1; 209 | } 210 | 211 | #grid-wrapper>nav { 212 | grid-column: 2; 213 | } 214 | 215 | details>summary>header { 216 | display: inline; 217 | } 218 | 219 | a.heading-link { 220 | box-shadow: none; 221 | } 222 | 223 | details h1 { 224 | font-size: 13pt; 225 | display: inline; 226 | } 227 | 228 | section .block[data-taxon]>details>summary>header>h1 { 229 | font-size: 12pt; 230 | } 231 | 232 | span.taxon { 233 | color: #444; 234 | } 235 | 236 | 237 | .link-list>section>details>summary>header h1 { 238 | font-size: 12pt; 239 | } 240 | 241 | 242 | article>section>details>summary>header>h1 { 243 | font-size: 1.5em; 244 | } 245 | 246 | details>summary { 247 | list-style-type: none; 248 | } 249 | 250 | details>summary::marker, 251 | details>summary::-webkit-details-marker { 252 | display: none; 253 | } 254 | 255 | article>section>details>summary>header { 256 | display: block; 257 | margin-bottom: .5em; 258 | } 259 | 260 | section.block>details { 261 | margin-bottom: 0.4em; 262 | } 263 | 264 | 265 | section.block>details[open] { 266 | margin-bottom: 1em; 267 | } 268 | 269 | 270 | .link-list>section.block>details { 271 | margin-bottom: .25em; 272 | } 273 | 274 | nav#toc { 275 | margin-left: 1em; 276 | } 277 | 278 | nav#toc h1 { 279 | margin-top: 0; 280 | font-size: 16pt; 281 | } 282 | 283 | nav#toc, 284 | nav#toc a { 285 | color: #555; 286 | } 287 | 288 | nav#toc h2 { 289 | font-size: 1.1em; 290 | } 291 | 292 | nav#toc ul { 293 | padding-left: 1.5em; 294 | list-style-type: square; 295 | } 296 | 297 | .toc-item-label { 298 | font-weight: bolder; 299 | } 300 | 301 | .katex { 302 | font-size: 1.2em; 303 | } 304 | 305 | .block { 306 | border-radius: var(--radius) 307 | } 308 | 309 | .block.splice { 310 | padding-top: 1em; 311 | } 312 | 313 | .block:hover { 314 | background-color: rgba(0, 100, 255, 0.04); 315 | } 316 | 317 | .block.highlighted { 318 | border-style: solid; 319 | border-width: 1pt; 320 | } 321 | 322 | .highlighted { 323 | background-color: rgba(255, 255, 140, .3); 324 | border-color: #ccc; 325 | } 326 | 327 | .highlighted:hover { 328 | background-color: rgba(255, 255, 140, .6); 329 | border-color: #aaa; 330 | } 331 | 332 | .block>.block-uid { 333 | visibility: hidden; 334 | display: flex; 335 | justify-content: flex-end; 336 | } 337 | 338 | .block:hover>.block-uid { 339 | visibility: visible; 340 | } 341 | 342 | .slug, 343 | .doi, 344 | .orcid { 345 | color: gray; 346 | font-weight: 200; 347 | } 348 | 349 | .edit-button { 350 | color: rgb(180, 180, 180); 351 | font-weight: 200; 352 | } 353 | 354 | .error { 355 | color: rgb(255, 50, 50, .8); 356 | } 357 | 358 | .block { 359 | padding-left: 5px; 360 | padding-right: 10px; 361 | padding-bottom: 2px; 362 | border-radius: 5px; 363 | } 364 | 365 | .block>.toggle-children-button { 366 | padding-right: 3pt; 367 | visibility: hidden; 368 | float: right; 369 | } 370 | 371 | .block:hover>.toggle-children-button { 372 | visibility: visible; 373 | } 374 | 375 | a.external { 376 | text-decoration: underline; 377 | color:#1d4ed8; 378 | } 379 | 380 | a.toc { 381 | box-shadow: none; 382 | text-decoration: none; 383 | } 384 | 385 | a.local{ 386 | color:#047857; 387 | } 388 | 389 | a.local, 390 | a.slug { 391 | box-shadow: none; 392 | text-decoration: underline; 393 | text-decoration-style: dotted; 394 | } 395 | 396 | ninja-keys::part(ninja-action) { 397 | white-space: nowrap; 398 | } 399 | 400 | body { 401 | hyphens: auto; 402 | } 403 | 404 | table { 405 | margin-bottom: 1em; 406 | } 407 | 408 | table.macros { 409 | overflow-x: visible; 410 | overflow-y: visible; 411 | font-size: 0.9em; 412 | } 413 | 414 | table.macros td { 415 | padding-left: 5pt; 416 | padding-right: 15pt; 417 | vertical-align: baseline; 418 | } 419 | 420 | th { 421 | text-align: left; 422 | } 423 | 424 | th, 425 | td { 426 | padding: 0 15px; 427 | vertical-align: top; 428 | } 429 | 430 | td.macro-name, 431 | td.macro-body { 432 | white-space: nowrap; 433 | } 434 | 435 | td.macro-doc { 436 | font-size: .9em; 437 | } 438 | 439 | .enclosing.macro-scope>.enclosing { 440 | border-radius: 2px; 441 | } 442 | 443 | .enclosing.macro-scope>.enclosing:hover { 444 | background-color: rgba(0, 100, 255, 0.1); 445 | } 446 | 447 | [aria-label][role~="tooltip"]::after { 448 | font-family: "Inria Sans"; 449 | } 450 | 451 | .tooltip { 452 | position: relative; 453 | } 454 | 455 | .inline.tooltip { 456 | display: inline-block; 457 | } 458 | 459 | .display.tooltip { 460 | display: block; 461 | } 462 | 463 | 464 | /* The tooltip class is applied to the span element that is the tooltip */ 465 | 466 | .tooltip .tooltiptext { 467 | visibility: hidden; 468 | white-space: nowrap; 469 | min-width: fit-content; 470 | background-color: black; 471 | color: #fff; 472 | padding-left: 5px; 473 | padding-top: 5px; 474 | padding-right: 10px; 475 | border-radius: 6px; 476 | position: absolute; 477 | z-index: 1; 478 | top: 100%; 479 | left: 50%; 480 | margin-left: -60px; 481 | opacity: 0; 482 | transition: opacity 0.3s; 483 | } 484 | 485 | .tooltip .tooltiptext::after { 486 | content: ""; 487 | position: absolute; 488 | top: 100%; 489 | left: 50%; 490 | margin-left: -5px; 491 | border-width: 5px; 492 | } 493 | 494 | 495 | /* Show the tooltip */ 496 | 497 | .tooltip:hover .tooltiptext { 498 | visibility: visible; 499 | opacity: 1; 500 | } 501 | 502 | .tooltiptext a { 503 | color: white 504 | } 505 | 506 | .macro-doc { 507 | font-style: italic; 508 | } 509 | 510 | .macro-name { 511 | white-space: nowrap; 512 | } 513 | 514 | .macro-is-private { 515 | color: var(--secondary); 516 | } 517 | 518 | blockquote { 519 | border-inline-start: 1px solid var(--secondary); 520 | } 521 | 522 | a:hover { 523 | background-color: rgba(0, 100, 255, .1); 524 | } 525 | 526 | a { 527 | color: black; 528 | } 529 | 530 | .nowrap { 531 | white-space: nowrap; 532 | } 533 | 534 | .nocite { 535 | display: none 536 | } 537 | 538 | blockquote { 539 | font-style: italic; 540 | } 541 | 542 | 543 | 544 | address { 545 | display: inline; 546 | } 547 | 548 | 549 | .metadata ul { 550 | padding-left: 0; 551 | display: inline; 552 | } 553 | 554 | .metadata li::after { 555 | content: " · "; 556 | } 557 | 558 | .metadata li:last-child::after { 559 | content: ""; 560 | } 561 | 562 | .metadata ul li { 563 | display: inline 564 | } 565 | 566 | img { 567 | object-fit: cover; 568 | max-width: 100%; 569 | } 570 | 571 | figcaption { 572 | font-style: italic; 573 | padding: 3px; 574 | text-align: center; 575 | } 576 | 577 | mark { 578 | background-color: rgb(255, 255, 151); 579 | } 580 | 581 | hr { 582 | margin-top: 10px; 583 | margin-bottom: 20px; 584 | background-color: gainsboro; 585 | border: 0 none; 586 | width: 100%; 587 | height: 2px; 588 | } 589 | -------------------------------------------------------------------------------- /javascript/forester.js: -------------------------------------------------------------------------------- 1 | import 'ninja-keys'; 2 | import 'katex'; 3 | 4 | import autoRenderMath from 'katex/contrib/auto-render'; 5 | 6 | function partition(array, isValid) { 7 | return array.reduce(([pass, fail], elem) => { 8 | return isValid(elem) ? [[...pass, elem], fail] : [pass, [...fail, elem]]; 9 | }, [[], []]); 10 | } 11 | 12 | window.addEventListener("load", (event) => { 13 | autoRenderMath(document.body) 14 | 15 | const openAllDetailsAbove = elt => { 16 | while (elt != null) { 17 | if (elt.nodeName == 'DETAILS') { 18 | elt.open = true 19 | } 20 | 21 | elt = elt.parentNode; 22 | } 23 | } 24 | 25 | const openDetailsIfAnchorHidden = evt => { 26 | const link = evt.target.closest('a') 27 | const selector = link.getAttribute('href') 28 | const target = document.querySelector(selector) 29 | openAllDetailsAbove(target) 30 | } 31 | 32 | 33 | [...document.querySelectorAll("[href^='#']")].forEach( 34 | el => el.addEventListener("click", openDetailsIfAnchorHidden) 35 | ); 36 | }); 37 | 38 | const ninja = document.querySelector('ninja-keys'); 39 | 40 | fetch("./forest.json") 41 | .then((res) => res.json()) 42 | .then((data) => { 43 | const items = [] 44 | 45 | const editIcon = '' 46 | const bookmarkIcon = '' 47 | 48 | if (window.sourcePath) { 49 | items.push({ 50 | id: 'edit', 51 | title: 'Edit current tree in Visual Studio Code', 52 | section: 'Commands', 53 | hotkey: 'cmd+e', 54 | icon: editIcon, 55 | handler: () => { 56 | window.location.href = `vscode://file/${window.sourcePath}` 57 | } 58 | }) 59 | } 60 | 61 | const isTopTree = (addr) => { 62 | const item = data[addr] 63 | return item.tags ? item.tags.includes('top') : false 64 | } 65 | 66 | const addItemToSection = (addr, section, icon) => { 67 | const item = data[addr] 68 | const title = 69 | item.taxon 70 | ? (item.title ? `${item.taxon} (${item.title})` : item.taxon) 71 | : (item.title ? item.title : "Untitled") 72 | const fullTitle = `${title} [${addr}]` 73 | items.push({ 74 | id: addr, 75 | title: fullTitle, 76 | section: section, 77 | icon: icon, 78 | handler: () => { 79 | window.location.href = item.route 80 | } 81 | }) 82 | } 83 | 84 | const [top, rest] = partition(Object.keys(data), isTopTree) 85 | top.forEach((addr) => addItemToSection(addr, "Top Trees", bookmarkIcon)) 86 | rest.forEach((addr) => addItemToSection(addr, "All Trees", null)) 87 | 88 | ninja.data = items 89 | }); 90 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functional-programming", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "esbuild": "^0.18.15", 9 | "katex": "^0.16.8", 10 | "ninja-keys": "^1.2.2" 11 | } 12 | }, 13 | "node_modules/@esbuild/android-arm": { 14 | "version": "0.18.20", 15 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", 16 | "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", 17 | "cpu": [ 18 | "arm" 19 | ], 20 | "optional": true, 21 | "os": [ 22 | "android" 23 | ], 24 | "engines": { 25 | "node": ">=12" 26 | } 27 | }, 28 | "node_modules/@esbuild/android-arm64": { 29 | "version": "0.18.20", 30 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", 31 | "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", 32 | "cpu": [ 33 | "arm64" 34 | ], 35 | "optional": true, 36 | "os": [ 37 | "android" 38 | ], 39 | "engines": { 40 | "node": ">=12" 41 | } 42 | }, 43 | "node_modules/@esbuild/android-x64": { 44 | "version": "0.18.20", 45 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", 46 | "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", 47 | "cpu": [ 48 | "x64" 49 | ], 50 | "optional": true, 51 | "os": [ 52 | "android" 53 | ], 54 | "engines": { 55 | "node": ">=12" 56 | } 57 | }, 58 | "node_modules/@esbuild/darwin-arm64": { 59 | "version": "0.18.20", 60 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", 61 | "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", 62 | "cpu": [ 63 | "arm64" 64 | ], 65 | "optional": true, 66 | "os": [ 67 | "darwin" 68 | ], 69 | "engines": { 70 | "node": ">=12" 71 | } 72 | }, 73 | "node_modules/@esbuild/darwin-x64": { 74 | "version": "0.18.20", 75 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", 76 | "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", 77 | "cpu": [ 78 | "x64" 79 | ], 80 | "optional": true, 81 | "os": [ 82 | "darwin" 83 | ], 84 | "engines": { 85 | "node": ">=12" 86 | } 87 | }, 88 | "node_modules/@esbuild/freebsd-arm64": { 89 | "version": "0.18.20", 90 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", 91 | "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", 92 | "cpu": [ 93 | "arm64" 94 | ], 95 | "optional": true, 96 | "os": [ 97 | "freebsd" 98 | ], 99 | "engines": { 100 | "node": ">=12" 101 | } 102 | }, 103 | "node_modules/@esbuild/freebsd-x64": { 104 | "version": "0.18.20", 105 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", 106 | "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", 107 | "cpu": [ 108 | "x64" 109 | ], 110 | "optional": true, 111 | "os": [ 112 | "freebsd" 113 | ], 114 | "engines": { 115 | "node": ">=12" 116 | } 117 | }, 118 | "node_modules/@esbuild/linux-arm": { 119 | "version": "0.18.20", 120 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", 121 | "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", 122 | "cpu": [ 123 | "arm" 124 | ], 125 | "optional": true, 126 | "os": [ 127 | "linux" 128 | ], 129 | "engines": { 130 | "node": ">=12" 131 | } 132 | }, 133 | "node_modules/@esbuild/linux-arm64": { 134 | "version": "0.18.20", 135 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", 136 | "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", 137 | "cpu": [ 138 | "arm64" 139 | ], 140 | "optional": true, 141 | "os": [ 142 | "linux" 143 | ], 144 | "engines": { 145 | "node": ">=12" 146 | } 147 | }, 148 | "node_modules/@esbuild/linux-ia32": { 149 | "version": "0.18.20", 150 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", 151 | "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", 152 | "cpu": [ 153 | "ia32" 154 | ], 155 | "optional": true, 156 | "os": [ 157 | "linux" 158 | ], 159 | "engines": { 160 | "node": ">=12" 161 | } 162 | }, 163 | "node_modules/@esbuild/linux-loong64": { 164 | "version": "0.18.20", 165 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", 166 | "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", 167 | "cpu": [ 168 | "loong64" 169 | ], 170 | "optional": true, 171 | "os": [ 172 | "linux" 173 | ], 174 | "engines": { 175 | "node": ">=12" 176 | } 177 | }, 178 | "node_modules/@esbuild/linux-mips64el": { 179 | "version": "0.18.20", 180 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", 181 | "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", 182 | "cpu": [ 183 | "mips64el" 184 | ], 185 | "optional": true, 186 | "os": [ 187 | "linux" 188 | ], 189 | "engines": { 190 | "node": ">=12" 191 | } 192 | }, 193 | "node_modules/@esbuild/linux-ppc64": { 194 | "version": "0.18.20", 195 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", 196 | "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", 197 | "cpu": [ 198 | "ppc64" 199 | ], 200 | "optional": true, 201 | "os": [ 202 | "linux" 203 | ], 204 | "engines": { 205 | "node": ">=12" 206 | } 207 | }, 208 | "node_modules/@esbuild/linux-riscv64": { 209 | "version": "0.18.20", 210 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", 211 | "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", 212 | "cpu": [ 213 | "riscv64" 214 | ], 215 | "optional": true, 216 | "os": [ 217 | "linux" 218 | ], 219 | "engines": { 220 | "node": ">=12" 221 | } 222 | }, 223 | "node_modules/@esbuild/linux-s390x": { 224 | "version": "0.18.20", 225 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", 226 | "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", 227 | "cpu": [ 228 | "s390x" 229 | ], 230 | "optional": true, 231 | "os": [ 232 | "linux" 233 | ], 234 | "engines": { 235 | "node": ">=12" 236 | } 237 | }, 238 | "node_modules/@esbuild/linux-x64": { 239 | "version": "0.18.20", 240 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", 241 | "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", 242 | "cpu": [ 243 | "x64" 244 | ], 245 | "optional": true, 246 | "os": [ 247 | "linux" 248 | ], 249 | "engines": { 250 | "node": ">=12" 251 | } 252 | }, 253 | "node_modules/@esbuild/netbsd-x64": { 254 | "version": "0.18.20", 255 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", 256 | "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", 257 | "cpu": [ 258 | "x64" 259 | ], 260 | "optional": true, 261 | "os": [ 262 | "netbsd" 263 | ], 264 | "engines": { 265 | "node": ">=12" 266 | } 267 | }, 268 | "node_modules/@esbuild/openbsd-x64": { 269 | "version": "0.18.20", 270 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", 271 | "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", 272 | "cpu": [ 273 | "x64" 274 | ], 275 | "optional": true, 276 | "os": [ 277 | "openbsd" 278 | ], 279 | "engines": { 280 | "node": ">=12" 281 | } 282 | }, 283 | "node_modules/@esbuild/sunos-x64": { 284 | "version": "0.18.20", 285 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", 286 | "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", 287 | "cpu": [ 288 | "x64" 289 | ], 290 | "optional": true, 291 | "os": [ 292 | "sunos" 293 | ], 294 | "engines": { 295 | "node": ">=12" 296 | } 297 | }, 298 | "node_modules/@esbuild/win32-arm64": { 299 | "version": "0.18.20", 300 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", 301 | "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", 302 | "cpu": [ 303 | "arm64" 304 | ], 305 | "optional": true, 306 | "os": [ 307 | "win32" 308 | ], 309 | "engines": { 310 | "node": ">=12" 311 | } 312 | }, 313 | "node_modules/@esbuild/win32-ia32": { 314 | "version": "0.18.20", 315 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", 316 | "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", 317 | "cpu": [ 318 | "ia32" 319 | ], 320 | "optional": true, 321 | "os": [ 322 | "win32" 323 | ], 324 | "engines": { 325 | "node": ">=12" 326 | } 327 | }, 328 | "node_modules/@esbuild/win32-x64": { 329 | "version": "0.18.20", 330 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", 331 | "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", 332 | "cpu": [ 333 | "x64" 334 | ], 335 | "optional": true, 336 | "os": [ 337 | "win32" 338 | ], 339 | "engines": { 340 | "node": ">=12" 341 | } 342 | }, 343 | "node_modules/@lit-labs/ssr-dom-shim": { 344 | "version": "1.1.1", 345 | "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz", 346 | "integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==" 347 | }, 348 | "node_modules/@lit/reactive-element": { 349 | "version": "1.6.3", 350 | "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz", 351 | "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==", 352 | "dependencies": { 353 | "@lit-labs/ssr-dom-shim": "^1.0.0" 354 | } 355 | }, 356 | "node_modules/@material/mwc-icon": { 357 | "version": "0.25.3", 358 | "resolved": "https://registry.npmjs.org/@material/mwc-icon/-/mwc-icon-0.25.3.tgz", 359 | "integrity": "sha512-36076AWZIRSr8qYOLjuDDkxej/HA0XAosrj7TS1ZeLlUBnLUtbDtvc1S7KSa0hqez7ouzOqGaWK24yoNnTa2OA==", 360 | "dependencies": { 361 | "lit": "^2.0.0", 362 | "tslib": "^2.0.1" 363 | } 364 | }, 365 | "node_modules/@types/trusted-types": { 366 | "version": "2.0.3", 367 | "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", 368 | "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" 369 | }, 370 | "node_modules/commander": { 371 | "version": "8.3.0", 372 | "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", 373 | "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", 374 | "engines": { 375 | "node": ">= 12" 376 | } 377 | }, 378 | "node_modules/esbuild": { 379 | "version": "0.18.20", 380 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", 381 | "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", 382 | "hasInstallScript": true, 383 | "bin": { 384 | "esbuild": "bin/esbuild" 385 | }, 386 | "engines": { 387 | "node": ">=12" 388 | }, 389 | "optionalDependencies": { 390 | "@esbuild/android-arm": "0.18.20", 391 | "@esbuild/android-arm64": "0.18.20", 392 | "@esbuild/android-x64": "0.18.20", 393 | "@esbuild/darwin-arm64": "0.18.20", 394 | "@esbuild/darwin-x64": "0.18.20", 395 | "@esbuild/freebsd-arm64": "0.18.20", 396 | "@esbuild/freebsd-x64": "0.18.20", 397 | "@esbuild/linux-arm": "0.18.20", 398 | "@esbuild/linux-arm64": "0.18.20", 399 | "@esbuild/linux-ia32": "0.18.20", 400 | "@esbuild/linux-loong64": "0.18.20", 401 | "@esbuild/linux-mips64el": "0.18.20", 402 | "@esbuild/linux-ppc64": "0.18.20", 403 | "@esbuild/linux-riscv64": "0.18.20", 404 | "@esbuild/linux-s390x": "0.18.20", 405 | "@esbuild/linux-x64": "0.18.20", 406 | "@esbuild/netbsd-x64": "0.18.20", 407 | "@esbuild/openbsd-x64": "0.18.20", 408 | "@esbuild/sunos-x64": "0.18.20", 409 | "@esbuild/win32-arm64": "0.18.20", 410 | "@esbuild/win32-ia32": "0.18.20", 411 | "@esbuild/win32-x64": "0.18.20" 412 | } 413 | }, 414 | "node_modules/hotkeys-js": { 415 | "version": "3.8.7", 416 | "resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.8.7.tgz", 417 | "integrity": "sha512-ckAx3EkUr5XjDwjEHDorHxRO2Kb7z6Z2Sxul4MbBkN8Nho7XDslQsgMJT+CiJ5Z4TgRxxvKHEpuLE3imzqy4Lg==" 418 | }, 419 | "node_modules/katex": { 420 | "version": "0.16.8", 421 | "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.8.tgz", 422 | "integrity": "sha512-ftuDnJbcbOckGY11OO+zg3OofESlbR5DRl2cmN8HeWeeFIV7wTXvAOx8kEjZjobhA+9wh2fbKeO6cdcA9Mnovg==", 423 | "funding": [ 424 | "https://opencollective.com/katex", 425 | "https://github.com/sponsors/katex" 426 | ], 427 | "dependencies": { 428 | "commander": "^8.3.0" 429 | }, 430 | "bin": { 431 | "katex": "cli.js" 432 | } 433 | }, 434 | "node_modules/lit": { 435 | "version": "2.2.6", 436 | "resolved": "https://registry.npmjs.org/lit/-/lit-2.2.6.tgz", 437 | "integrity": "sha512-K2vkeGABfSJSfkhqHy86ujchJs3NR9nW1bEEiV+bXDkbiQ60Tv5GUausYN2mXigZn8lC1qXuc46ArQRKYmumZw==", 438 | "dependencies": { 439 | "@lit/reactive-element": "^1.3.0", 440 | "lit-element": "^3.2.0", 441 | "lit-html": "^2.2.0" 442 | } 443 | }, 444 | "node_modules/lit-element": { 445 | "version": "3.3.3", 446 | "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz", 447 | "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==", 448 | "dependencies": { 449 | "@lit-labs/ssr-dom-shim": "^1.1.0", 450 | "@lit/reactive-element": "^1.3.0", 451 | "lit-html": "^2.8.0" 452 | } 453 | }, 454 | "node_modules/lit-html": { 455 | "version": "2.8.0", 456 | "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz", 457 | "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==", 458 | "dependencies": { 459 | "@types/trusted-types": "^2.0.2" 460 | } 461 | }, 462 | "node_modules/ninja-keys": { 463 | "version": "1.2.2", 464 | "resolved": "https://registry.npmjs.org/ninja-keys/-/ninja-keys-1.2.2.tgz", 465 | "integrity": "sha512-ylo8jzKowi3XBHkgHRjBJaKQkl32WRLr7kRiA0ajiku11vHRDJ2xANtTScR5C7XlDwKEOYvUPesCKacUeeLAYw==", 466 | "dependencies": { 467 | "@material/mwc-icon": "0.25.3", 468 | "hotkeys-js": "3.8.7", 469 | "lit": "2.2.6" 470 | } 471 | }, 472 | "node_modules/tslib": { 473 | "version": "2.6.2", 474 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", 475 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" 476 | } 477 | } 478 | } 479 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "esbuild": "^0.18.15", 4 | "katex": "^0.16.8", 5 | "ninja-keys": "^1.2.2" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /trees/alg-0001.tree: -------------------------------------------------------------------------------- 1 | \title{Magma} 2 | \taxon{definition} 3 | \date{2023-09-13} 4 | \author{fizzyelt} 5 | 6 | \p{[Magma](https://ncatlab.org/nlab/show/magma) 是代數結構的一種,由一個集合與運算子組成 #{(M,\ \bullet)}。定義為「對於在集合 #{M} 裡所有 #{a,\ b},#{a\ \bullet \ b} 的結果也是集合 #{M} 裡的元素」} 7 | 8 | ##{ 9 | a,\ b \in M \Longrightarrow a\ \bullet\ b \in M 10 | } 11 | 12 | \transclude{alg-0002} 13 | -------------------------------------------------------------------------------- /trees/alg-0002.tree: -------------------------------------------------------------------------------- 1 | \title{不是 semigroup 的 magma} 2 | \taxon{example} 3 | \author{dannypsnl} 4 | \date{2023-09-13} 5 | 6 | \p{我們很容易造出一堆其實是 semigroup(滿足結合律)的 magma,然後騙自己說這樣就是 magma,但這無助於我們思考結合律的意義。刻意構造一個 magma 會發現這其實沒那麼容易,這裡給出一個是 magma 但不是 semigroup 的案例。} 7 | 8 | \ol{ 9 | \li{ 10 | #{M} 是整數有序對構成的集合 11 | } 12 | \li{ 13 | #{\bullet} 在輸入兩對的相接序對有序時直接回傳,在無序時回傳全部元素的總和為唯一元素的有序對 14 | } 15 | } 16 | 17 | \p{第二條彎彎繞繞的意思就是 #{[1] \bullet [2] = [1, 2]},而 #{[2] \bullet [1] = [3]}。所以現在可以說結合律對運算 #{\bullet} 不成立,因為} 18 | 19 | \ul{ 20 | \li{#{[0] \bullet ([2] \bullet [1]) = [0,3]}} 21 | \li{#{([0] \bullet [2]) \bullet [1] = [3]}} 22 | } 23 | 24 | \p{也可以看到交換律不成立的例子。} 25 | -------------------------------------------------------------------------------- /trees/alg-0003.tree: -------------------------------------------------------------------------------- 1 | \title{Semigroup} 2 | \taxon{definition} 3 | \date{2023-09-13} 4 | \author{fizzyelt} 5 | 6 | \p{[Semigroup](https://ncatlab.org/nlab/show/semigroup) 是滿足結合律的 [Magma](alg-0001)。結合律是指對所有 semigroup 中的元素 #{x,y,z \in S},皆滿足} 7 | 8 | ##{ 9 | x \bullet (y \bullet z) = (x \bullet y) \bullet z 10 | } 11 | 12 | \transclude{alg-0004} 13 | -------------------------------------------------------------------------------- /trees/alg-0004.tree: -------------------------------------------------------------------------------- 1 | \title{不滿足交換律的 semigroup} 2 | \taxon{example} 3 | \author{dannypsnl} 4 | \date{2023-09-13} 5 | 6 | \p{沿襲 [Magma 案例](alg-0002)的傳統,這裡不舉滿足交換律的 semigroup。在程式語言裡面已經有一個我們很常看到的案例了,也就是字串相接,我們可以著手檢查:} 7 | 8 | \ul{ 9 | \li{字串與字串相接還是字串} 10 | \li{字串先接 #{x, y} 或 #{y, z} 不影響結果} 11 | } 12 | -------------------------------------------------------------------------------- /trees/alg-0005.tree: -------------------------------------------------------------------------------- 1 | \title{Monoid} 2 | \taxon{definition} 3 | \date{2023-09-13} 4 | \author{fizzyelt} 5 | 6 | \p{[Monoid](https://en.wikipedia.org/wiki/Monoid) 是有 identity element 的 [semigroup](alg-0003),其中 identity element #{e} 滿足} 7 | 8 | ##{ 9 | e \bullet a = a = a \bullet e 10 | } 11 | 12 | \p{如果把 id morphism 對應到 #{e},而剩餘的 morphism 對應到每個 monoid 的元素上,那麼只有一個 object 的 [small category](cat-0001) 正好是一個 monoid。} 13 | 14 | \transclude{fp-000O} 15 | \transclude{cs-0001} 16 | -------------------------------------------------------------------------------- /trees/base-macros.tree: -------------------------------------------------------------------------------- 1 | \def\br{\xml{br}{}} 2 | 3 | \def\img[src]{\xml{img}[src]{\src}{}} 4 | 5 | \def\proof[body]{ 6 | \scope{ 7 | \put\transclude/toc{false} 8 | \subtree{ 9 | \taxon{proof} 10 | \body 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /trees/cat-0001.tree: -------------------------------------------------------------------------------- 1 | \title{直覺 Category} 2 | \date{2023-09-09} 3 | \taxon{definition} 4 | \author{dannypsnl} 5 | 6 | \def\CCat{#{\mathcal{C}}} 7 | 8 | \p{ 9 | 說直覺是因為我們這裡未有完善定義何謂 [class](set-0001) 跟 [set](set-0001),但是作為入門或是簡要使用的定義「夠好」。 10 | 我們說 \CCat 是一個範疇的意思是: 11 | 12 | \ol{ 13 | \li{ 14 | 有 #{Ob(\CCat)} 物件 \strong{class},表示範疇中的物件。作為方便的記號,當 #{a} 為 #{\CCat} 中一物件,我們記成 #{a \in Ob(\CCat)} 15 | } 16 | \li{ 17 | 當有 #{a, b \in Ob(\CCat)},而 #{f} 為一 #{a} 到 #{b} 之態射(morphism) ,記為 #{f \in \CCat(a, b)} 或是 #{f : a \to b}。 18 | 態射可以組合,也就是說當有 #{f : a \to b} 且 #{g : b \to c},存在一個兩個的組合態射 #{f \circ g}。 19 | 與上面相同,#{\CCat(a, b)} 是一個態射 \strong{class} 20 | } 21 | \li{ 22 | #{id_a\ id_b} 對 #{f:a\to b} 滿足 #{f\circ id_a = f} 跟 #{id_b\circ f = f} 23 | } 24 | \li{ 25 | #{(f\circ g)\circ h=f\circ (g\circ h)} 26 | } 27 | } 28 | 29 | 要是對每個 #{a,b} 之間的全部 morphism #{\CCat(a, b)} 是一個集合,就說範疇 locally small;要是整個範疇中所有的 morphism 是一個集合,那範疇就是 small。 30 | 深入技術細節會讓你更了解為什麼需要定義這麼多東西,但在最開始的時候,只要簡單的相信範疇給定的定義即可。 31 | } 32 | -------------------------------------------------------------------------------- /trees/cat-0002.tree: -------------------------------------------------------------------------------- 1 | \title{Functor} 2 | \taxon{definition} 3 | \date{2023-09-11} 4 | \author{dannypsnl} 5 | 6 | \def\cat1{#{\mathcal{C}}} 7 | \def\cat2{#{\mathcal{D}}} 8 | 9 | \p{ 10 | Let #{\cat1 \to \cat2} be [categories](cat-0001). To specify a \em{functor} #{F} from \cat1 to \cat2, denoted #{F : \cat1 \to \cat2} 11 | 12 | \ol{ 13 | \li{for every object #{c \in Ob(\cat1)}, one specifies an object #{F(c) \in Ob(\cat2)};} 14 | \li{for every morphism #{f : c_1 \to c_2} in \cat1, one specifies a morphism #{F(f) : F(c_1) \to F(c_2)} in \cat2.} 15 | } 16 | 17 | And they must satisfy two properties: 18 | 19 | \ol{ 20 | \li{ 21 | for every object #{c \in Ob(\cat1)}, we have #{F(id_c) = id_{F(c)}}; 22 | } 23 | \li{ 24 | for every three objects #{c_1, c_2, c_3 \in Ob(\cat1)} and two morphisms #{f \in \cat1(c_1, c_2)} and #{g \in \cat1(c_2, c_3)}, the equation #{F(f \circ g) = F(f) \circ F(g)} holds in \cat2. 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /trees/cat-0003.tree: -------------------------------------------------------------------------------- 1 | \title{Functor} 2 | \author{fizzyelt} 3 | \date{2023-09-11} 4 | 5 | \transclude{cat-0002} 6 | \transclude{fp-000H} 7 | \transclude{fp-000G} 8 | \transclude{fp-000I} 9 | -------------------------------------------------------------------------------- /trees/cat-0004.tree: -------------------------------------------------------------------------------- 1 | \title{cartesian closed category} 2 | \taxon{definition} 3 | \author{dannypsnl} 4 | \date{2023-10-24} 5 | 6 | \p{ 7 | 一個[範疇](cat-0001) #{C} 被稱為 cartesian closed 表示 8 | \ol{ 9 | \li{任意有限多個 objects #{\{a_i \mid i \in \mathbb{N}\}} 的 product #{a_0 \times ... \times a_n} 亦是範疇的 object} 10 | \li{對所有 object #{a \in C} 而言,functor #{a \times - : C \to C} 是 #{(-)^a : C \to C} 的[右伴隨](https://en.wikipedia.org/wiki/Adjoint_functors)} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /trees/cat-0005.tree: -------------------------------------------------------------------------------- 1 | \title{#{F}-algebra} 2 | \taxon{definition} 3 | \author{dannypsnl} 4 | \author{fizzyelt} 5 | 6 | \p{要理解 #{F}-algebra,我們需要一些觀察,第一個是代數可以表示成一組簽名。例如,Monoid 有一組簽名:} 7 | 8 | ##{\begin{cases} 9 | 1:1\to m \\ 10 | \bullet: m \times m \to m 11 | \end{cases}} 12 | 13 | \p{或者你可以將 環(Ring)寫成:} 14 | 15 | ##{\begin{cases} 16 | 0: 1 \to m \\ 17 | 1:1 \to m \\ 18 | +: m \times m \to m \\ 19 | \times: m \times m \to m \\ 20 | - : m \to m 21 | \end{cases}} 22 | 23 | \p{我們令 #{m} 為範疇 #{C} 中的一個 object,要選一個足以表示簽名的範疇,以上面的例子來說需要 [cartesian closed category](cat-0004)。} 24 | 25 | \ul{ 26 | \li{對 #{m} 來說,Monoid 是 #{C} 中的一個態射 #{1 + m \times m \to m}} 27 | \li{對 #{m} 來說,環是 #{C} 中的一個態射 #{1 + 1 + m \times m + m \times m + m \to m}} 28 | } 29 | 30 | \p{根據這些,我們把代數的定義推廣為:固定 #{F} 函子後,每個 #{F(m) \to m} 都是一個代數。} 31 | 32 | \transclude{cat-0006} 33 | \transclude{cat-0007} 34 | 35 | \p{這些是跟範疇中初始對象 (initial object) 有關的一個定理} 36 | 37 | \transclude{cat-0008} 38 | \transclude{cat-0009} 39 | \transclude{cat-000A} 40 | -------------------------------------------------------------------------------- /trees/cat-0006.tree: -------------------------------------------------------------------------------- 1 | \title{#{F}-algebra (algebra for an endofunctor)} 2 | \taxon{definition} 3 | \author{dannypsnl} 4 | \author{fizzyelt} 5 | 6 | 7 | \p{在一個適當的範疇 #{C} 中,我們把簽名改成一個 functor #{F},這個函子投射出的 #{F(m) \to m} 是 #{F}-algebra,記為三元組:} 8 | 9 | ##{(F,x,\alpha)} 10 | 11 | \p{其中 #{\alpha : Fx \to x} 是一個 #{C} 中的態射。} 12 | -------------------------------------------------------------------------------- /trees/cat-0007.tree: -------------------------------------------------------------------------------- 1 | \title{Category of #{F}-algebra} 2 | \taxon{definition} 3 | \author{dannypsnl} 4 | \author{fizzyelt} 5 | 6 | \p{functor 與 natural transformation 構成 functor category} 7 | 8 | \p{對於在一個適當的範疇 #{C} 中固定的自函子 #{F} (以下省略 #{F} 符號)} 9 | 10 | \ol{ 11 | \li{object 是全部的 #{F}-algebra。} 12 | \li{態射皆為 #{(x,\alpha)\xrightarrow{Fm} (y,\beta)} 對象的同態,組合由函子定律給出。} 13 | } 14 | 15 | \p{同態是令下圖交換的態射 #{m}} 16 | 17 | \tex{\usepackage{preamble}}{ 18 | % https://q.uiver.app/#q=WzAsNCxbMCwwLCJGeCJdLFsyLDAsIkZ5Il0sWzAsMiwieCJdLFsyLDIsInkiXSxbMCwxLCJGbSJdLFsyLDMsIm0iLDJdLFswLDIsIlxcYWxwaGEiLDJdLFsxLDMsIlxcYmV0YSJdXQ== 19 | \begin{tikzcd} 20 | Fx && Fy \\ 21 | \\ 22 | x && y 23 | \arrow["Fm", from=1-1, to=1-3] 24 | \arrow["m"', from=3-1, to=3-3] 25 | \arrow["\alpha"', from=1-1, to=3-1] 26 | \arrow["\beta", from=1-3, to=3-3] 27 | \end{tikzcd} 28 | } 29 | 30 | \p{額外檢查我們可以發現 identity 也如預期運作} 31 | 32 | \tex{\usepackage{preamble}}{ 33 | % https://q.uiver.app/#q=WzAsNCxbMCwwLCJGeCJdLFsyLDAsIkZ4Il0sWzAsMiwieCJdLFsyLDIsIngiXSxbMCwxLCIxX3tGeH0iXSxbMiwzLCIxX3t4fSIsMl0sWzAsMiwiXFxhbHBoYSIsMl0sWzEsMywiXFxhbHBoYSJdXQ== 34 | \begin{tikzcd} 35 | Fx && Fx \\ 36 | \\ 37 | x && x 38 | \arrow["{1_{Fx}}", from=1-1, to=1-3] 39 | \arrow["{1_{x}}"', from=3-1, to=3-3] 40 | \arrow["\alpha"', from=1-1, to=3-1] 41 | \arrow["\alpha", from=1-3, to=3-3] 42 | \end{tikzcd} 43 | } 44 | 45 | -------------------------------------------------------------------------------- /trees/cat-0008.tree: -------------------------------------------------------------------------------- 1 | \title{Lambek's} 2 | \taxon{theorem} 3 | \author{dannypsnl} 4 | \author{fizzyelt} 5 | \import{base-macros} 6 | 7 | \p{初始代數是同構態射} 8 | 9 | \proof{ 10 | 讓 #{Fi} 成為 #{F}-algebra 範疇中的初始對象,對於 #{C} 中所有對象 #{a} 產生以下交換圖 11 | } 12 | 13 | \tex{\usepackage{preamble}}{ 14 | % https://q.uiver.app/#q=WzAsNCxbMCwwLCJGaSJdLFsyLDAsIkZhIl0sWzAsMiwiaSJdLFsyLDIsImEiXSxbMCwxLCJGbSJdLFsyLDMsIm0iLDJdLFswLDIsImoiLDJdLFsxLDMsImYiXV0= 15 | \begin{tikzcd} 16 | Fi && Fa \\ 17 | \\ 18 | i && a 19 | \arrow["Fm", from=1-1, to=1-3] 20 | \arrow["m"', from=3-1, to=3-3] 21 | \arrow["j"', from=1-1, to=3-1] 22 | \arrow["f", from=1-3, to=3-3] 23 | \end{tikzcd} 24 | } 25 | 26 | \p{現在我們將 #{a} 替換成 #{Fi}} 27 | 28 | \tex{\usepackage{preamble}}{ 29 | % https://q.uiver.app/#q=WzAsNCxbMCwwLCJGaSJdLFsyLDAsIkZcXCBGaSJdLFswLDIsImkiXSxbMiwyLCJGaSJdLFswLDEsIkZtIl0sWzIsMywibSIsMl0sWzAsMiwiaiIsMl0sWzEsMywiRmoiXV0= 30 | \begin{tikzcd} 31 | Fi && {F\ Fi} \\ 32 | \\ 33 | i && Fi 34 | \arrow["Fm", from=1-1, to=1-3] 35 | \arrow["m"', from=3-1, to=3-3] 36 | \arrow["j"', from=1-1, to=3-1] 37 | \arrow["Fj", from=1-3, to=3-3] 38 | \end{tikzcd} 39 | } 40 | 41 | \p{再來透過複製路徑 #{Fi \to i} 得出以下交換圖} 42 | 43 | \tex{\usepackage{preamble}}{ 44 | % https://q.uiver.app/#q=WzAsNSxbMCwwLCJGXFwgRmkiXSxbMiwwLCJGaSJdLFswLDIsIkZpIl0sWzIsMiwiaSJdLFswLDFdLFswLDEsIkZqIl0sWzIsMywiaiIsMl0sWzAsMiwiRmoiLDJdLFsxLDMsImoiXV0= 45 | \begin{tikzcd} 46 | {F\ Fi} && Fi \\ 47 | {} \\ 48 | Fi && i 49 | \arrow["Fj", from=1-1, to=1-3] 50 | \arrow["j"', from=3-1, to=3-3] 51 | \arrow["Fj"', from=1-1, to=3-1] 52 | \arrow["j", from=1-3, to=3-3] 53 | \end{tikzcd} 54 | } 55 | 56 | \p{將兩張交換圖合併} 57 | 58 | \tex{\usepackage{preamble}}{ 59 | % https://q.uiver.app/#q=WzAsNixbMiwwLCJGXFwgRmkiXSxbNCwwLCJGaSJdLFsyLDIsIkZpIl0sWzQsMiwiaSJdLFswLDAsIkZpIl0sWzAsMiwiaSJdLFswLDEsIkZqIl0sWzIsMywiaiIsMl0sWzAsMiwiRmoiLDJdLFsxLDMsImoiXSxbNCwwLCJGbSJdLFs1LDIsIm0iLDJdLFs0LDUsImoiLDJdXQ== 60 | \begin{tikzcd} 61 | Fi && {F\ Fi} && Fi \\ 62 | \\ 63 | i && Fi && i 64 | \arrow["Fj", from=1-3, to=1-5] 65 | \arrow["j"', from=3-3, to=3-5] 66 | \arrow["Fj"', from=1-3, to=3-3] 67 | \arrow["j", from=1-5, to=3-5] 68 | \arrow["Fm", from=1-1, to=1-3] 69 | \arrow["m"', from=3-1, to=3-3] 70 | \arrow["j"', from=1-1, to=3-1] 71 | \end{tikzcd} 72 | } 73 | 74 | \p{透過定義,我們現在知道 #{j \circ m} 是同態(homomorphism),並且因為 #{Fi} 為初始對象我們得到} 75 | 76 | ##{Fj \circ Fm = 1_{Fi}} 77 | 78 | \p{所以,我們也得出} 79 | 80 | ##{j \circ m = 1_{i}} 81 | 82 | \p{因此 #{m} 是 #{j} 的 inverse,證明 #{j} 是同構。} 83 | -------------------------------------------------------------------------------- /trees/cat-0009.tree: -------------------------------------------------------------------------------- 1 | \title{Catamorphism} 2 | \author{dannypsnl} 3 | \author{fizzyelt} 4 | 5 | \p{根據 Lambek's 理論可以畫出交換圖} 6 | 7 | \tex{\usepackage{preamble}}{ 8 | % https://q.uiver.app/#q=WzAsNCxbMiwwLCJGYSJdLFsyLDIsImEiXSxbMCwwLCJGaSJdLFswLDIsImkiXSxbMCwxLCJhbGciXSxbMiwwLCJGbSJdLFszLDEsIm0iLDJdLFsyLDMsImoiLDJdXQ== 9 | \begin{tikzcd} 10 | Fi && Fa \\ 11 | \\ 12 | i && a 13 | \arrow["alg", from=1-3, to=3-3] 14 | \arrow["Fm", from=1-1, to=1-3] 15 | \arrow["m"', from=3-1, to=3-3] 16 | \arrow["{j^{-1}}"', from=1-1, to=3-1] 17 | \end{tikzcd} 18 | } 19 | 20 | \p{在 Haskell 中,我們可以這樣定義初始代數} 21 | 22 | \subtree{ 23 | \pre{\startverb% 24 | newtype Fix f = Fix (f (Fix f)) 25 | 26 | unFix :: Fix f -> f (Fix f) 27 | unFix (Fix x) = x 28 | \stopverb}} 29 | 30 | \p{將 #{j} 視為 \code{Fix} 建構子,#{j^{-1}} 為 \code{unFix},再來我們可以定義 \code{m = alg . fmap m . unFix}。因為 \code{m :: Fix f -> a},我們有了 Catamorphism 的程式定義} 31 | 32 | \subtree{ 33 | \pre{\startverb% 34 | cata :: Functor f => (f a -> a) -> Fix f -> a 35 | cata alg = alg . fmap (cata alg) . unFix 36 | \stopverb}} 37 | 38 | \p{\code{foldr} 是一個常見的例子,它是 Catamorphism 的一種便利版本。} 39 | -------------------------------------------------------------------------------- /trees/cat-000A.tree: -------------------------------------------------------------------------------- 1 | \title{Anamorphism} 2 | \author{dannypsnl} 3 | \author{fizzyelt} 4 | 5 | \p{作為一個對偶概念,可以畫出一個 coalgebra 的圖,我們稱這種關係為 anamorphism。} 6 | 7 | \tex{\usepackage{preamble}}{ 8 | % https://q.uiver.app/#q=WzAsNCxbMiwwLCJGXFwgYSJdLFsyLDIsImEiXSxbMCwwLCJGXFwgdCJdLFswLDIsInQiXSxbMSwzLCJtIl0sWzEsMCwiZiIsMl0sWzAsMiwiRm0iLDJdLFszLDIsInUiXV0= 9 | \begin{tikzcd} 10 | {F\ t} && {F\ a} \\ 11 | \\ 12 | t && a 13 | \arrow["m", from=3-3, to=3-1] 14 | \arrow["f"', from=3-3, to=1-3] 15 | \arrow["Fm"', from=1-3, to=1-1] 16 | \arrow["u", from=3-1, to=1-1] 17 | \end{tikzcd} 18 | } 19 | -------------------------------------------------------------------------------- /trees/cs-0001.tree: -------------------------------------------------------------------------------- 1 | \title{半自動機} 2 | \taxon{example} 3 | \author{fizzyelt} 4 | \date{2023-09-13} 5 | 6 | \p{對給定的半自動機可以討論其 [characteristic monoid](https://planetmath.org/CharacteristicMonoid)。一個半自動機是個三元組 #{(Q, \Sigma, T)}} 7 | 8 | \ul{ 9 | \li{#{Q} 是一個非空的「狀態集合」} 10 | \li{#{\Sigma} 是一個「輸入字母表」的非空集合} 11 | \li{#{T} 是轉移函數} 12 | } 13 | 14 | \p{假設一個 #{M(Q, \Sigma, T)} 集合} 15 | 16 | ##{ 17 | M(Q,\ \Sigma,\ T) = \{ T_w\ |\ w\in \Sigma^* \} 18 | } 19 | 20 | \p{集合 #{M(Q,\ \Sigma,\ T)} 在\strong{函數複合}下閉合;就是說,對於所有 #{v,w \in \Sigma^*} ,有 #{T_w \circ T_v = T_{vw}} 。它還包含 #{T_\epsilon} ,而這個 #{T_\epsilon} 是個\strong{恆等函數(即 identity function)}。 } 21 | -------------------------------------------------------------------------------- /trees/fp-0001.tree: -------------------------------------------------------------------------------- 1 | \title{帶你入門 functional programming} 2 | \meta{author}{false} 3 | 4 | \p{什麼是函數式程式設計是一個大哉問,但作為一個入門導引,我們簡單的定義成受 lambda calculus 啟發,並且格外注重可組合性的語言。在其上有兩種變體} 5 | 6 | \ol{ 7 | \li{一種現在相當著重在對形式計算時機的控制,也就是 macro 上,也就是 Lisp 與其延伸語言} 8 | \li{一種則注重對數學概念的引進,乃自裡面有一種叫做代數類型的型別定義方法,其基本出發自 F-algebra,但其內涵相當深遠,並不止於此,例如定理證明器往往只使用其中的 inductives 這一類變體。} 9 | } 10 | 11 | \p{作為入門網站,這裡著重在第二類語言,因為 macro 與這類語言並沒有顯著衝突,並且也非入門概念,引進理論討論 macro 的運算控制也沒有問題,因此沒有理由特別用入門時的觀點分類。那麼,第二類語言裡面,同樣有許多著重不同的變體} 12 | 13 | \ol{ 14 | \li{OCaml 著重類型正確,卻不在意 side effect} 15 | \li{Haskell 注重類型也注重 side effect 控制,同時對 type level 有一定的操作能力} 16 | \li{Agda, Coq, Lean 等語言作為寫程式的工具可能有點失格,但主要是因為目標完全不同,分類作語言的子類別:定理證明器 比較合適} 17 | } 18 | 19 | \p{這個網站的準則,是教導抽象的數學概念,讓學習者最終對實際 functional programming 有一定的了解,並大致理解現代語義學研究,或許能夠應用其成果。那麼,我們開始回顧 lambda calculus 與可計算性的沿革,開始學習 functional programming 吧} 20 | 21 | \transclude{roadmap} 22 | -------------------------------------------------------------------------------- /trees/fp-0002.tree: -------------------------------------------------------------------------------- 1 | \title{Data first or Data last?} 2 | \author{fizzyelt} 3 | \date{2023-09-09} 4 | 5 | \p{ 6 | data first 跟 data last 區別在於主要被操作的資料是擺在最前面或最後面,而 functional programming 習慣 data last 的方式設計函數,目的是提高函數的可組合性。 7 | } 8 | \transclude{fp-0003} 9 | \transclude{fp-0004} 10 | \transclude{fp-0005} 11 | \transclude{fp-0006} 12 | \transclude{fp-0008} 13 | \transclude{fp-000B} 14 | -------------------------------------------------------------------------------- /trees/fp-0003.tree: -------------------------------------------------------------------------------- 1 | \title{一般函數的設計} 2 | 3 | \p{ 4 | 在一般情況下我們撰寫一個函數習慣將資料擺在最前面,其他參數擺後面。假設今天我們設計一個 Array \code{map} 函數: 5 | } 6 | 7 | \pre{\startverb% 8 | function map(data, callback){ 9 | let res = []; 10 | 11 | for(const item of data){ 12 | res.push(callback(item)) 13 | } 14 | 15 | return res 16 | } 17 | \stopverb} 18 | 19 | \p{我們可以利用 \code{map} 它再做出新的函數 \code{double}:} 20 | 21 | \pre{\startverb% 22 | function double(data) { 23 | return map(data, (num) => num * 2); 24 | } 25 | \stopverb} 26 | 27 | \p{但你慢慢就會發現你每利用 \code{map} 做一個新的函數出來,你都要重複做一次傳遞 \code{data} 的動作。} 28 | -------------------------------------------------------------------------------- /trees/fp-0004.tree: -------------------------------------------------------------------------------- 1 | \title{data last} 2 | 3 | \p{今天我們轉成 data last 形式來設計 \code{map}:} 4 | 5 | \pre{\startverb% 6 | function map(callback, data) { 7 | let res = []; 8 | 9 | for (const item of data) { 10 | res.push(callback(item)); 11 | } 12 | 13 | return res; 14 | } 15 | \stopverb} 16 | 17 | \p{我們再嘗試做一個 \code{double}:} 18 | 19 | \pre{\startverb% 20 | function double(data) { 21 | return map((num) => num * 2, data); 22 | } 23 | \stopverb} 24 | 25 | \p{你會發現你還是要一直傳遞 \code{data} ,這到底有什麼差,但我們忘了一件事情是 FP 通常會將函數做\strong{柯里化(curry)}。} 26 | -------------------------------------------------------------------------------- /trees/fp-0005.tree: -------------------------------------------------------------------------------- 1 | \title{data last 搭配柯里化} 2 | 3 | \p{ 4 | 我們將 \code{map} 函數做柯里化 5 | } 6 | 7 | \pre{\startverb% 8 | function map(callback) { 9 | return function (data) { 10 | let res = []; 11 | 12 | for (const item of data) { 13 | res.push(callback(item)); 14 | } 15 | 16 | return res; 17 | }; 18 | } 19 | \stopverb} 20 | 21 | \p{現在做一個 double 函數只需要傳 callback 即可} 22 | 23 | \pre{\startverb% 24 | map((num) => num * 2); 25 | \stopverb} 26 | -------------------------------------------------------------------------------- /trees/fp-0006.tree: -------------------------------------------------------------------------------- 1 | \title{利於函式組合} 2 | 3 | \p{一般我們做函式組合通常是 #{f} 函數的輸出對應到 #{g} 函數的輸入。} 4 | 5 | ##{ 6 | f = a \to b,\ g = b \to c 7 | } 8 | 9 | \p{ 10 | 但現實是並不是每個函數的輸入參數都只有一個,我們必須先給一些參數後才能再跟其他函數接在一起。 11 | 而一般情況下組合會是長這樣: 12 | } 13 | 14 | \pre{\startverb% 15 | function fn(data) { 16 | return map( 17 | map(data, (num) => num * 2), 18 | (num) => num + 1 19 | ); 20 | } 21 | \stopverb} 22 | 23 | \p{你每組一個新的函數出來你都得做一次傳遞資料的動作。} 24 | 25 | \transclude{fp-0007} 26 | -------------------------------------------------------------------------------- /trees/fp-0007.tree: -------------------------------------------------------------------------------- 1 | \title{利用 compose} 2 | 3 | \p{在函數 \strong{data last 搭配柯里化} 的情況下用 \code{compose} 來組合函式會乾淨許多。} 4 | 5 | \pre{\startverb% 6 | const fn = compose( 7 | map((num) => num + 1), 8 | map((num) => num * 2) 9 | ); 10 | \stopverb} 11 | -------------------------------------------------------------------------------- /trees/fp-0008.tree: -------------------------------------------------------------------------------- 1 | \title{data first 較優雅的作法} 2 | 3 | \p{如果不想像一開始那樣一直傳遞 data,但還是想走 data first 形式,有兩種} 4 | 5 | \transclude{fp-0009} 6 | \transclude{fp-000A} 7 | -------------------------------------------------------------------------------- /trees/fp-0009.tree: -------------------------------------------------------------------------------- 1 | \title{chaining} 2 | 3 | \p{一種是就是用我們一般 Array methods 的形式串接下去} 4 | 5 | \pre{\startverb% 6 | data.map((num) => num * 2).map((num) => num + 1); 7 | \stopverb} 8 | 9 | \p{可以從 [lodash](https://lodash.com/docs/#chain) 找到這種設計方式,但伴隨的缺點是跟其他函式庫沒辦法配合的這麼好。} 10 | -------------------------------------------------------------------------------- /trees/fp-000A.tree: -------------------------------------------------------------------------------- 1 | \title{略過參數的語法糖} 2 | 3 | \p{在 Scala 中可以利用 \code{_} 來暫時略過參數:} 4 | 5 | \pre{\startverb% 6 | List(1, 2, 3, 4).map(_ * 2) 7 | \stopverb} 8 | 9 | \pre{\startverb% 10 | def multiplier(a: Int, b: Int): Int = a * b 11 | 12 | val fourTimes = multiplier(_: Int, 4) 13 | 14 | fourTimes(2) // 8 15 | \stopverb} 16 | 17 | \p{ 18 | 我們在 \code{ramda} 中會看到一個叫做 [placeholder function](https://ramdajs.com/docs/#__) 來模擬類似 Scala 的效果,它可以保留位置來安插後續進來的參數。 19 | 20 | 假設我們利用 data first 方式設計 \code{map} 並做柯里化,使用 \code{__} 函數就會是以下這樣: 21 | } 22 | 23 | \pre{\startverb% 24 | const fn = compose( 25 | map(R.__, (num) => num + 1), 26 | map(R.__, (num) => num * 2) 27 | ); 28 | \stopverb} 29 | -------------------------------------------------------------------------------- /trees/fp-000B.tree: -------------------------------------------------------------------------------- 1 | \title{參數的順序會影響結果的函數} 2 | 3 | \p{有些函數的參數資料格式相同,並且擺放順序不同會影響執行結果。} 4 | 5 | \ul{ 6 | \li{\code{<} lessThan} 7 | \li{\code{<=} lessThanEqual} 8 | \li{\code{>} greaterThan} 9 | \li{\code{>=} greaterThanEqual} 10 | \li{\code{concat}} 11 | } 12 | 13 | \p{ 14 | 如果是一般的比大小,我們反轉一下邏輯就可以解決(\code{<} 改成 \code{>=}),但 \code{concat} 就不行 15 | 假設我們的需求是將主流程的資訊接在 \code{arr} 的前面,但一般作法似乎會有錯誤: 16 | } 17 | 18 | \pre{\startverb% 19 | flow( 20 | // ... 21 | concat(arr) // 前一個的結果會被接在 arr 後面 22 | ); 23 | \stopverb} 24 | 25 | \transclude{fp-000C} 26 | \transclude{fp-000D} 27 | \transclude{fp-000E} 28 | -------------------------------------------------------------------------------- /trees/fp-000C.tree: -------------------------------------------------------------------------------- 1 | \title{重新包裝} 2 | 3 | \p{一種辦法是我們再包裝一個函數,重新將 data 擺在正確位置} 4 | 5 | \pre{\startverb% 6 | flow( 7 | // ... 8 | (data) => concat(data, arr) // 多包一層來擺放正確位置 9 | ); 10 | \stopverb} 11 | -------------------------------------------------------------------------------- /trees/fp-000D.tree: -------------------------------------------------------------------------------- 1 | \title{flip} 2 | 3 | \p{flip 函數可以將你的函數的前兩個參數對調} 4 | 5 | \pre{\startverb% 6 | flow( 7 | // ... 8 | flip(concat)(arr) // 將參數對調 9 | ); 10 | \stopverb} 11 | 12 | [Ramda \code{flip}](https://ramdajs.com/docs/#flip) 13 | -------------------------------------------------------------------------------- /trees/fp-000E.tree: -------------------------------------------------------------------------------- 1 | \title{placeholder} 2 | 3 | \p{也可以利用 placeholder function 來消除不必要的包裝跟邏輯反轉。} 4 | 5 | \pre{\startverb% 6 | flow( 7 | // ... 8 | R.concat(R.__, arr) // 保留第一個位置給後續進來的資料 9 | ); 10 | \stopverb} 11 | -------------------------------------------------------------------------------- /trees/fp-000F.tree: -------------------------------------------------------------------------------- 1 | \title{透過單元測試難易度辨別函式純度} 2 | \author{fizzyelt} 3 | \date{2023-10-15} 4 | \import{base-macros} 5 | 6 | \p{身為一個初學者該如何知道自己的函數有多純?其實在進行單元測試時可以很容易觀察到,以下會有兩點可以注意:} 7 | 8 | \ul{ 9 | \li{是否依賴外部資源及變數導致你需要使用 mock data? 10 | \br你必須創造一些虛假的上下文才能使你的函數正常運作,代表這函數過度依賴環境,在遷移上相對困難許多。} 11 | 12 | \li{你的函數執行完是否會導致外部變數被修改? 13 | \br函數應該盡可能減少對外部影響,否則在追蹤錯誤時會變得越來越困難。} 14 | } 15 | 16 | \p{除了函數本身的行為必須正確之外,一個函數無論遷移到何種新環境時都不會改變其行為,也不會對該環境產生任何影響,這個函數才稱得上足夠純。然而,在現實程式中,很難實現所有函數都是純函數的理想情況。我們能做的是盡量減少非純函數,以降低維護成本。} 17 | 18 | \p{透過單元測試,不僅可以檢驗你的函數是否如預期執行,還可以讓你重新審視該函數的定位,並且培養撰寫純函數的直覺。} 19 | -------------------------------------------------------------------------------- /trees/fp-000G.tree: -------------------------------------------------------------------------------- 1 | \title{實際上的用途} 2 | \author{fizzyelt} 3 | \author{dannypsnl} 4 | 5 | \p{ 6 | 可以將一個 pure function 應用到容器型別之中。 7 | 單純從容器的角度來看,就像是隱藏了「取出 → 運算 → 放回去」的過程,而根據每個容器用途不同在過程中執行不同操作及判斷。 8 | } 9 | 10 | \tex{\usepackage{preamble}}{ 11 | % http://quiver.localhost/?q=WzAsNCxbMCwxLCJGXFw7YSJdLFszLDEsIkZcXDtiIl0sWzEsMCwiYSJdLFsyLDAsImIiXSxbMCwxXSxbMiwzXSxbNSw0LCJcXGJvbGR7bGlmdH0iLDAseyJzaG9ydGVuIjp7InNvdXJjZSI6MjAsInRhcmdldCI6MjB9fV1d 12 | \begin{tikzcd} 13 | & a & b \\ 14 | {F\;a} &&& {F\;b} 15 | \arrow[""{name=0, anchor=center, inner sep=0}, from=2-1, to=2-4] 16 | \arrow[""{name=1, anchor=center, inner sep=0}, from=1-2, to=1-3] 17 | \arrow["{\bold{lift}}", shorten <=4pt, shorten >=4pt, Rightarrow, from=1, to=0] 18 | \end{tikzcd} 19 | } 20 | 21 | \p{ 22 | 雖然 polymorphism 的容器解釋非常方便,卻是眾多誤解的根源之一。實際上不能做這麼簡單的解釋,舉例來說我可以定義 #{F(-) = (c \to -)},於是 #{F(a) \to F(b)} 視同 #{(c \to a) \to (c \to b)},令 #{g : c \to a, f : a \to b},#{\lambda c. \lambda g. f(g(c))} 正是一個 functor。 23 | } 24 | -------------------------------------------------------------------------------- /trees/fp-000H.tree: -------------------------------------------------------------------------------- 1 | \title{FP 的 Functor 與範疇論的 Functor 之間的關聯} 2 | \author{fizzyelt} 3 | \author{dannypsnl} 4 | 5 | \p{ 6 | 即便我們看了[範疇論](cat-0002)跟 FP 語言中的 Functor 定義,但在概念的銜接上仍然有困難,如果你看了 [Functor(functional programming) wiki](https://en.wikipedia.org/wiki/Functor_(functional_programming)) 會發現他是受範疇論啟發的 design pattern。而到底引用了哪些概念,以及與語言能做到什麼程度,並沒有很好的說明。 7 | } 8 | 9 | \p{ 10 | 如果以「Functor 是兩個範疇之間的映射」這個觀點來看程式中的 Functor 似乎有些奇怪,通常我們看到的範例都是舉兩個不同範疇 #{C,D},如果某一程式語言是一個範疇 #{C} 的話,那範疇 #{D} 就會是另一個語言,雖然我們常常這樣思考,但是我們定義程式裡面的 Functor 時不想弄得太複雜。所以這裡指的都是「 #{C} 與 #{C} 之間的映射」,也就是 \strong{Endofunctor} 。你可以在 [Haskell wiki](https://wiki.haskell.org/Typeclassopedia) 以及 fp-ts 作者所寫的 [Introduction to Functional Programming](https://github.com/enricopolanski/functional-programming#a-boundary-that-leads-to-functors) 中找到相關說明。 11 | } 12 | 13 | 14 | \blockquote{ 15 | \p{Technically, these laws make f and fmap together an endofunctor on Hask, the category of Haskell types (ignoring [⊥](https://wiki.haskell.org/Bottom), which is a party pooper). See [Wikibook: Category theory](https://en.wikibooks.org/wiki/Haskell/Category_theory).} 16 | } 17 | 18 | \blockquote{ 19 | \p{ 20 | Even though a map between two different programming languages is a fascinating idea, we're more interested in a map where C and D are the same (the TS category). In that case we're talking about \strong{endofunctors} (from the greek "endo" meaning "inside", "internal"). 21 | } 22 | } 23 | 24 | \p{ 25 | 範疇論跟程式語言定義的 Functor 不是完全一樣的概念,因為大部分的語言並不可能寫出[命題](https://ncatlab.org/nlab/show/type+of+propositions),所以範疇論的限制語言裡不一定有加上,這之間的一些漏洞就會產生對使用者來說可能很奇怪的結果,我們能做的就是將兩者之間重疊的部份做連結。而 Haskell 是透過 [Typeclass](https://wiki.haskell.org/Typeclassopedia) 來做約束,所以在程式語言的語境下所說的 Functor 是指 type class 的定義。另外,我們常說「Maybe 是一個 Functor」 指的是 Maybe 是 Functor class 的一個實例 (Maybe 可替換任何其他 Functor class 實例)。 26 | } 27 | 28 | \p{ 29 | 其他 FP 語言雖然不一定都使用 Typeclass 這個詞,但大多 Functor 的定義都差不多。 30 | } 31 | 32 | \subtree{ 33 | \title{haskell} 34 | \pre{\startverb% 35 | class Functor f where 36 | fmap :: (a -> b) -> f a -> f b 37 | \stopverb} 38 | } 39 | 40 | \subtree{ 41 | \title{haskell} 42 | \pre{\startverb% 43 | trait Functor[F[_]] { 44 | def map[A,B](a: F[A])(f: A => B): F[B] 45 | } 46 | \stopverb} 47 | } 48 | 49 | \subtree{ 50 | \title{lean} 51 | \pre{\startverb% 52 | class Functor (f : Type u → Type v) : Type (max (u+1) v) where 53 | map : {α β : Type u} → (α → β) → f α → f β 54 | \stopverb} 55 | } 56 | 57 | \transclude{fp-000P} 58 | -------------------------------------------------------------------------------- /trees/fp-000I.tree: -------------------------------------------------------------------------------- 1 | \title{常見的 Functor Type} 2 | \author{fizzyelt} 3 | 4 | \ul{ 5 | \li{ 6 | Maybe / Option 7 | \ul{ 8 | \li{Haskell (Maybe)} 9 | \li{Lean (Option)} 10 | \li{Rust (Option)} 11 | } 12 | } 13 | \li{ 14 | Either / Result / Except 15 | \ul{ 16 | \li{Haskell (Either)} 17 | \li{Result (Rust)} 18 | \li{Lean (Except)} 19 | } 20 | } 21 | \li{ 22 | IO 23 | \ul{ 24 | \li{Haskell (IO)} 25 | \li{Lean (IO)} 26 | } 27 | } 28 | 29 | \li{ 30 | Reader 31 | 待補 32 | } 33 | \li{ 34 | Writer 35 | 待補 36 | } 37 | \li{ 38 | State 39 | 待補 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /trees/fp-000J.tree: -------------------------------------------------------------------------------- 1 | \title{純函數 (Pure function)} 2 | \taxon{definition} 3 | \author{fizzyelt} 4 | \author{dannypsnl} 5 | 6 | \p{純函數的意義是我們想讓編譯器可以做公共子常式提取跟幾種循環等最佳化而試圖去探尋的某一類函數,進而是一種有效減輕開發上的心智負擔,是能夠被靈活組合的一類函數。在程式中你可以利用函數做許多事情,不只是單純的運算,還包含了各種值的修改及各種非同步操作,雖然方便但也造成了閱讀及維護上的困難。} 7 | 8 | \p{由於上述的最佳化都涉及到複製或是共用函數呼叫,因此可以導出這些函數在系統下的任何情形中對相同輸入都能給出相同的輸出。這個部分讓我們推導出一些性質,比如這類函數絕對不跟其他函數共用任何儲存機制,而是只用參數跟回傳處理讀寫的概念。再來函數不應該有副作用,否則增加或是減少函數呼叫都會導致不同的副作用結果。} 9 | 10 | \p{因為程式語言裡面必須面對無法判定任意計算是否停機的關係,所以建模型的時候都會留下一個對應到 \strong{undefined} (#{\bot}) 的位置,這樣的概念叫做 partial function,跟數學上的[全函數](fp-000K)有所差異。} 11 | 12 | \transclude{fp-000F} 13 | -------------------------------------------------------------------------------- /trees/fp-000K.tree: -------------------------------------------------------------------------------- 1 | \title{函數} 2 | \taxon{definition} 3 | \author{fizzyelt} 4 | \author{dannypsnl} 5 | 6 | \p{在數學中,函數是一個集合 (稱為\strong{定義域 domain}) 到另一個集合 (稱為\strong{值域 codomain}) 的映射,假設我們有個函數 #{f:A \to B},則 #{A} (domain) 中每個元素都必須對應到 #{B}(codomain) 中的一個元素,能達成 #{A \to B} 條件的函數總共有 #{|B|^{|A|}} 種,我們能實現的是有限的語法能實現的一小部分,而不是所有都實現。} 7 | 8 | \p{Typescript} 9 | 10 | \pre{ 11 | // isEven : number -> boolean 12 | function isEven(num: number): boolean { 13 | return num \% 2 === 0 14 | } 15 | } 16 | 17 | \p{Haskell} 18 | 19 | \pre{\startverb% 20 | is_even :: Int -> Bool 21 | is_even n = n `mod` 2 == 0 22 | \stopverb} 23 | 24 | \p{函數分三種類型,包含 \strong{單射 (injection)}、\strong{滿射 (surjection)}、\strong{對射 (bijection)}。} 25 | 26 | \transclude{fp-000L} 27 | \transclude{fp-000M} 28 | \transclude{fp-000N} 29 | -------------------------------------------------------------------------------- /trees/fp-000L.tree: -------------------------------------------------------------------------------- 1 | \title{單射 (injection)} 2 | 3 | \p{假設我們稱一個函數 #{f:A \to B} 是單射,則 #{A} 與 #{B} 的元素關係都是一對一的,即} 4 | 5 | ##{\forall a,b\in A,\ a\neq b \Longrightarrow f(a)\neq f(b)} 6 | 7 | \xml{figure}{ 8 | \xml{img}[src]{images/fp-000L/injection.png}{} 9 | \xml{figcaption}{injection} 10 | } 11 | 12 | \p{我們可以從中得知另一個訊息是 #{A} 中的元素數量會小於等於 #{B} 元素數量,即 #{|A|\le |B|}} 13 | -------------------------------------------------------------------------------- /trees/fp-000M.tree: -------------------------------------------------------------------------------- 1 | \title{滿射 (surjection)} 2 | 3 | \p{我們稱一個函數 #{f : A \to B} 是滿射,則對於 #{B} 中所有的元素,都存在至少一個 #{A} 元素與其對應,即} 4 | 5 | ##{\forall b \in B,\ \exist a \in A,\ f(a) = b} 6 | 7 | \xml{figure}{ 8 | \xml{img}[src]{images/fp-000M/surjection.png}{} 9 | \xml{figcaption}{surjection} 10 | } 11 | 12 | \p{我們可以從中得知另一個訊息是 #{A} 中的元素數量會大於等於 #{B} 元素數量,即 #{|A| \ge |B|}} 13 | -------------------------------------------------------------------------------- /trees/fp-000N.tree: -------------------------------------------------------------------------------- 1 | \title{對射 (bijection)} 2 | 3 | \p{我們稱一個函數 #{f : A \to B} 是對射,則該函數同時達成單射與滿射條件,因為同時滿足 #{|A|\le |B|} 跟 #{|A|\ge |B|} 則 #{|A| = |B|}} 4 | 5 | \xml{figure}{ 6 | \xml{img}[src]{images/fp-000N/bijection.png}{} 7 | \xml{figcaption}{bijection} 8 | } 9 | -------------------------------------------------------------------------------- /trees/fp-000O.tree: -------------------------------------------------------------------------------- 1 | \title{函數組合} 2 | \taxon{example} 3 | \author{fizzyelt} 4 | \author{dannypsnl} 5 | \date{2023-09-13} 6 | 7 | \p{在禁止 free variable 的 lambda calculus 中,可以將 monoid 用作模型} 8 | 9 | \ul{ 10 | \li{#{e} 就是 #{\lambda x. x}} 11 | \li{函數 #{f, g} 的組合 #{f \circ g} 是 #{\lambda x. f (g \; x)}} 12 | } 13 | 14 | \p{identity law 的檢查比較容易,這裡我們就來看結合律如何運作:} 15 | 16 | ##{\begin{aligned} 17 | &f \circ (g \circ h) 18 | \\ 19 | &= \lambda x. f ((g \circ h) \; x) 20 | \\ 21 | &= \lambda x. f ((\lambda x. g (h \; x)) \; x) 22 | \\ 23 | &= \lambda x. f (g (h \; x)) 24 | \\ 25 | &(f \circ g) \circ h 26 | \\ 27 | &= \lambda x. (f \circ g)(h \; x) 28 | \\ 29 | &= \lambda x. (\lambda x. f (g \; x)) (h \; x) 30 | \\ 31 | &= \lambda x. f (g (h \; x)) 32 | \end{aligned}} 33 | 34 | \p{確實滿足要求。} 35 | -------------------------------------------------------------------------------- /trees/fp-000P.tree: -------------------------------------------------------------------------------- 1 | \title{Functor Laws} 2 | \author{fizzyelt} 3 | 4 | \p{ 5 | Functor class 的實例不能視為範疇論中的 Functor,必須檢查 Functor 的約束才會是真正的 Functor。 6 | } 7 | 8 | ##{ 9 | fmap\ id = id 10 | \\ 11 | fmap\ (g\circ f) = fmap\ g \circ fmap\ f 12 | } 13 | -------------------------------------------------------------------------------- /trees/people/dannypsnl.tree: -------------------------------------------------------------------------------- 1 | \title{Lîm Tsú-thuàn} 2 | \taxon{person} 3 | \meta{position}{Compiler Developer} 4 | \meta{external}{https://dannypsnl.me} 5 | -------------------------------------------------------------------------------- /trees/people/fizzyelt.tree: -------------------------------------------------------------------------------- 1 | \title{FizzyElt} 2 | \taxon{person} 3 | \meta{position}{Front-End Developer} 4 | \meta{external}{https://fizzyelt.github.io} 5 | -------------------------------------------------------------------------------- /trees/roadmap.tree: -------------------------------------------------------------------------------- 1 | \title{地圖} 2 | \meta{author}{false} 3 | 4 | \p{此地圖為一大方向,每個主體內會有延伸,包含實例、名詞解釋等等,類似於心智圖,而未來也有可能異動} 5 | 6 | \ol{ 7 | \li{lambda calculus} 8 | \li{用 recursion 解釋可計算性} 9 | \li{加上 simply type} 10 | \li{解釋型別規則} 11 | \li{建立 STLC categorical semantic} 12 | \li{加上 polymorphism} 13 | \li{解釋型別規則} 14 | \li{建立 #{E \to B} categorical semantic} 15 | \li{解釋 #{\lambda 2} 的 polymorphic property} 16 | \li{解釋 recursive type} 17 | \li{連結 F-algebra} 18 | \li{變成 dependent type} 19 | \li{解釋型別規則} 20 | \li{解釋模型(The natural model) 21 | \ul{ 22 | \li{topos} 23 | \li{topos fundamental theorem} 24 | \li{presheaf} 25 | \li{representable natural transformation} 26 | } 27 | } 28 | \li{進入真正的應用} 29 | \li{side effect} 30 | \li{concurrency} 31 | \li{安全性 32 | 33 | \ul{ 34 | \li{記憶體安全與子結構類型} 35 | \ul{ 36 | \li{(?) proof nets} 37 | } 38 | \li{整體安全性不是只關乎記憶體} 39 | } 40 | } 41 | \li{domain language} 42 | } 43 | -------------------------------------------------------------------------------- /trees/set-0001.tree: -------------------------------------------------------------------------------- 1 | \date{2023-09-09} 2 | \title{本性類與良性類} 3 | \author{dannypsnl} 4 | 5 | \p{ 6 | 類區分為兩種:一種是可以順利進行類運算的「良性類」,我們把這種「良性類」稱為集合;另一種是要限制運算的「本性類」,對於本性類,類運算並不是都能進行的。 7 | 更多資料可以參照數學導論 8 | } --------------------------------------------------------------------------------