[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_size = 4\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[Makefile]\nindent_style = tab\n\n[*.{tex,cls,lua,nix}]\nindent_style = space\nindent_size = 2\nmax_line_length = 80\n\n[*.md]\ntrim_trailing_whitespace = false\nindent_size = 2\nmax_line_length = 80\n"
  },
  {
    "path": ".envrc",
    "content": "use flake .\nuse flake github:loophp/nix-prettier\n"
  },
  {
    "path": ".github/settings.yml",
    "content": "# https://github.com/probot/settings\n\nbranches:\n    - name: master\n      protection:\n          enforce_admins: false\n          required_pull_request_reviews:\n              dismiss_stale_reviews: true\n              require_code_owner_reviews: true\n              required_approving_review_count: 1\n          restrictions: null\n          required_linear_history: true\n          required_status_checks:\n              strict: true\n\nlabels:\n    - name: typo\n      color: ee0701\n\n    - name: dependencies\n      color: 0366d6\n\n    - name: enhancement\n      color: 0e8a16\n\n    - name: question\n      color: cc317c\n\n    - name: security\n      color: ee0701\n\n    - name: stale\n      color: eeeeee\n\nrepository:\n    allow_merge_commit: true\n    allow_rebase_merge: true\n    allow_squash_merge: true\n    default_branch: master\n    description:\n        \"Bartosz Milewski's 'Category Theory for Programmers' unofficial PDF and\n        LaTeX sources\"\n    homepage: https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/\n    topics: pdf,haskell,scala,latex,cpp,functional-programming,ocaml,category-theory\n    has_downloads: true\n    has_issues: true\n    has_pages: false\n    has_projects: false\n    has_wiki: false\n    name: milewski-ctfp-pdf\n    private: false\n"
  },
  {
    "path": ".github/workflows/nix-flake-check.yaml",
    "content": "name: Check and build\n\non:\n    pull_request:\n    push:\n        branches:\n            - master\njobs:\n    dependencies:\n        name: Build dependencies\n        runs-on: ubuntu-latest\n        outputs:\n            version: ${{ steps.version.outputs.version }}\n\n        steps:\n            - name: Set up Git repository\n              uses: actions/checkout@v3\n\n            - name: Create global variables\n              id: version\n              run:\n                  echo \"version=$(git rev-parse --short HEAD)\" >> $GITHUB_OUTPUT\n\n    determine-matrix:\n        name: Figure out the packages we need to build\n        runs-on: ubuntu-latest\n        needs: [dependencies]\n\n        outputs:\n            matrix: ${{ steps.set-matrix.outputs.matrix }}\n\n        steps:\n            - name: Set up Git repository\n              uses: actions/checkout@v3\n\n            - name: Install the Nix package manager\n              uses: cachix/install-nix-action@v20\n\n            - id: set-matrix\n              run: |\n                  echo \"matrix=$(\n                    nix eval --json .#packages.x86_64-linux --apply builtins.attrNames\n                  )\" >> $GITHUB_OUTPUT\n\n    build:\n        name: Build\n        needs: determine-matrix\n        runs-on: ubuntu-latest\n        strategy:\n            matrix:\n                packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}\n\n        steps:\n            - name: Set up Git repository\n              uses: actions/checkout@v3\n\n            - name: Install Nix\n              uses: cachix/install-nix-action@v20\n\n            - name: Nix flake check\n              run: nix flake check\n\n            - name: Build ${{ matrix.packages }}.pdf\n              run: nix build .#${{ matrix.packages }}\n"
  },
  {
    "path": ".github/workflows/nix-fmt-checks.yaml",
    "content": "name: Nix formatter checks\n\non:\n    pull_request:\n\njobs:\n    format-check:\n        runs-on: ubuntu-latest\n        steps:\n            - name: Checkout repository\n              uses: actions/checkout@v3\n\n            - name: Install Nix\n              uses: cachix/install-nix-action@v18\n\n            - name: Run nix formatter tool\n              run: nix fmt . -- --check\n"
  },
  {
    "path": ".github/workflows/prettier-checks.yaml",
    "content": "name: Prettier checks\n\non:\n    pull_request:\n\njobs:\n    prettier:\n        runs-on: ubuntu-latest\n\n        steps:\n            - name: Checkout\n              uses: actions/checkout@v3\n\n            - name: Install the Nix package manager\n              uses: cachix/install-nix-action@v18\n\n            - name: Checks\n              run: nix run nixpkgs#nodePackages.prettier -- --check .\n"
  },
  {
    "path": ".github/workflows/release.yaml",
    "content": "name: Release PDFs\n\non:\n    push:\n        tags:\n            - \"**\"\n\njobs:\n    determine-matrix:\n        name: Figure out the assets we need to build\n        runs-on: ubuntu-latest\n\n        outputs:\n            matrix: ${{ steps.set-matrix.outputs.matrix }}\n\n        steps:\n            - name: Set up Git repository\n              uses: actions/checkout@v3\n\n            - name: Install the Nix package manager\n              uses: cachix/install-nix-action@v20\n\n            - id: set-matrix\n              run: |\n                  echo \"matrix=$(\n                    nix eval --json .#packages.x86_64-linux --apply builtins.attrNames\n                  )\" >> $GITHUB_OUTPUT\n\n    build:\n        name: Build documents\n        needs: determine-matrix\n        runs-on: ubuntu-latest\n        strategy:\n            matrix:\n                packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}\n\n        steps:\n            - name: Set up Git repository\n              uses: actions/checkout@v3\n\n            - name: Install Nix\n              uses: cachix/install-nix-action@v20\n\n            - name: Build ${{ matrix.packages }}.pdf\n              run: |\n                  nix build .#${{ matrix.packages }}\n                  mkdir -p out\n                  cp -ar ./result/* out/\n\n            - name: Upload build assets (${{ matrix.packages }}.pdf)\n              uses: actions/upload-artifact@v2\n              with:\n                  name: ctfp\n                  path: out/*\n\n    release:\n        name: \"Create Github pre-release\"\n        runs-on: ubuntu-latest\n        needs: [build]\n        outputs:\n            upload_url: ${{ steps.create_release.outputs.upload_url }}\n        steps:\n            - name: Create Github pre-release (${{ github.ref }})\n              id: create_release\n              uses: actions/create-release@v1\n              env:\n                  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n              with:\n                  tag_name: ${{ github.ref }}\n                  release_name: ${{ github.ref }}\n                  draft: true\n\n    assets:\n        name: Upload release assets\n        runs-on: ubuntu-latest\n        needs: [determine-matrix, release]\n        strategy:\n            matrix:\n                packages: ${{fromJson(needs.determine-matrix.outputs.matrix)}}\n\n        steps:\n            - name: Download build assets (${{ matrix.packages }}.pdf)\n              uses: actions/download-artifact@v4.1.7\n              with:\n                  name: ctfp\n                  path: ctfp\n\n            - name:\n                  Upload release assets (${{ matrix.packages }}--${{ github.ref\n                  }}.pdf)\n              uses: actions/upload-release-asset@v1\n              env:\n                  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n              with:\n                  upload_url: ${{ needs.release.outputs.upload_url }}\n                  asset_path: ctfp/${{ matrix.packages }}.pdf\n                  asset_name: ${{ matrix.packages }}--${{ github.ref }}.pdf\n                  asset_content_type: application/pdf\n"
  },
  {
    "path": ".gitignore",
    "content": "/.vscode/\n/.direnv/\n/build/\n/result\n.DS_Store\nsrc/.dotty-ide-disabled\nsrc/.metals\nout/\n_minted*\n*.fls\nout/*\n*.fdb_latexmk\n*.bak*\n*.log\n*.pdf\n*.xdv\n*.gz\n*.pyg\n*.synctex(busy)\n*.aux\n*.idx\n*.ilg\n*.lig\n*.ind\n*.out\n*.toc\n"
  },
  {
    "path": ".latexindent.yaml",
    "content": "defaultIndent: \"  \"\nverbatimEnvironments:\n    verbatim: 1\n    lstlisting: 1\n    minted: 1\n    snip: 1\n    snipv: 1\n"
  },
  {
    "path": ".prettierignore",
    "content": "/.direnv/\n/.idea/\n/vendor/\n/docs/\n/build/\nCHANGELOG.md\nflake.lock\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n    \"proseWrap\": \"always\"\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "\n    LICENSING TERMS\n \n 1. Output PDF, *.tex, all files in content/* and fig/* are licensed\n    under Creative Commons Attribution-ShareAlike 4.0 International License\n    (http://creativecommons.org/licenses/by-sa/4.0/).\n \n 2. The script files scraper.py and additional scripts are under GNU GPL v.3:\n\n\n                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "Makefile",
    "content": "OUTPUT ?= $(shell basename \"$(shell dirname \"$(INPUT)\")\")\nOUTPUT_DIRECTORY = $(shell pwd)/build\nLATEXMK_ARGS ?= -f -file-line-error -shell-escape -logfilewarninglist -interaction=nonstopmode -halt-on-error -norc -pdflatex=\"xelatex %O %S\" -pdfxe\nTEXINPUTS = \"\"\nTEXLIVE_RUN = TEXINPUTS=$(TEXINPUTS)\nLATEXMK_COMMAND = $(TEXLIVE_RUN) latexmk $(LATEXMK_ARGS)\n\n# Make does not offer a recursive wildcard function, so here's one:\nrwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))\n\nctfp:\n\tcd src; $(LATEXMK_COMMAND) -jobname=ctfp ctfp-reader.tex\n\nctfp-ocaml:\n\tcd src; $(LATEXMK_COMMAND) -jobname=ctfp-ocaml ctfp-reader-ocaml.tex\n\nctfp-scala:\n\tcd src; $(LATEXMK_COMMAND) -jobname=ctfp-scala ctfp-reader-scala.tex\n\nctfp-print:\n\tcd src; $(LATEXMK_COMMAND) -jobname=ctfp-print ctfp-print.tex\n\nctfp-print-ocaml:\n\tcd src; $(LATEXMK_COMMAND) -jobname=ctfp-print-ocaml ctfp-print-ocaml.tex\n\nctfp-print-scala:\n\tcd src; $(LATEXMK_COMMAND) -jobname=ctfp-print-scala ctfp-print-scala.tex\n\nlint:\n\t$(foreach file, $(call rwildcard,$(shell dirname \"$(INPUT)\"),*.tex), latexindent -l -w $(file);)\n\n"
  },
  {
    "path": "README.md",
    "content": "![GitHub stars][github stars]\n[![GitHub Workflow Status][github workflow status]][github actions link]\n[![Download][download badge]][github latest release]\n[![License][license badge]][github latest release]\n\n# Category Theory For Programmers\n\nAn _unofficial_ PDF version of \"**C**ategory **T**heory **F**or **P**rogrammers\"\nby [Bartosz Milewski][bartosz github], converted from his [blogpost\nseries][blogpost series] (_with permission!_).\n\n![Category Theory for Programmers][ctfp image]\n\n## Buy the book\n\n- **[Standard edition in full-color hardcover\n  print][buy regular edition on blurb]**\n  - Publish date: 12 August, 2019.\n  - Based off release tag [v1.3.0][v1.3.0 github release link]. See\n    [errata-1.3.0](errata-1.3.0.md) for changes and fixes since print.\n- **[Scala Edition in paperback][buy scala edition on blurb]**\n  - Publish date: 12 August, 2019.\n  - Based off release tag [v1.3.0][v1.3.0 github release link]. See\n    [errata-scala](errata-scala.md) for changes and fixes since print.\n\n## Build the book\n\nThe building workflow requires [Nix][nix website]. After [installing\nNix][nix download website], you need to enable the upcoming \"flake\" feature\nwhich must be [enabled manually][nixos wiki flake] the time being. This is\nneeded to expose the new Nix commands and flakes support that are hidden behind\nfeature-flags.\n\nAfterwards, type `nix flake show` in the root directory of the project to see\nall the available versions of this book. Then type `nix build .#<edition>` to\nbuild the edition you want (Scala, OCaml, Reason and their printed versions).\nFor example, to build the Scala edition you'll have to type\n`nix build .#ctfp-scala`. For Haskell (the original version) that is just\n`nix build .#ctfp`.\n\nUpon successful compilation, the PDF file will be placed in the `result`\ndirectory.\n\nThe command `nix develop` will provide a shell containing all the required\ndependencies to build the book manually using the provided `Makefile`. To build\nthe `ctfp-scala` edition, just run `make ctfp-scala`.\n\n## Contribute\n\nContributors are welcome to contribute to this book by sending pull-requests.\nOnce reviewed, the changes are merged in the main branch and will be\nincorporated in the next release.\n\n**Note from [Bartosz][bartosz github]**: I really appreciate all your\ncontributions. You made this book much better than I could have imagined. Thank\nyou!\n\nFind the [list of contributors on Github][contributors].\n\n## Acknowledgements\n\nPDF LaTeX source and the tools to create it are based on the work by [Andres\nRaba][andres raba github]. The book content is taken, with permission, from\n[Bartosz Milewski][bartosz github]'s blogpost series, and adapted to the LaTeX\nformat.\n\nThe original blog post acknowledgments by Bartosz are consolidated in the\n_Acknowledgments_ page at the end of the book.\n\n## License\n\nThe PDF book, `.tex` files, and associated images and figures in directories\n`src/fig` and `src/content` are licensed under [Creative Commons\nAttribution-ShareAlike 4.0 International License][license cc by sa].\n\nThe script files `scraper.py` and others are licensed under [GNU General Public\nLicense version 3][license gnu gpl].\n\n[download badge]:\n  https://img.shields.io/badge/Download-latest-green.svg?style=flat-square\n[github actions link]: https://github.com/hmemcpy/milewski-ctfp-pdf/actions\n[github stars]:\n  https://img.shields.io/github/stars/hmemcpy/milewski-ctfp-pdf.svg?style=flat-square\n[github workflow status]:\n  https://img.shields.io/github/actions/workflow/status/hmemcpy/milewski-ctfp-pdf/nix-flake-check.yaml?branch=master&style=flat-square\n[github latest release]:\n  https://github.com/hmemcpy/milewski-ctfp-pdf/releases/latest\n[license badge]:\n  https://img.shields.io/badge/License-CC_By_SA-green.svg?style=flat-square\n[ctfp image]:\n  https://user-images.githubusercontent.com/601206/47271389-8eea0900-d581-11e8-8e81-5b932e336336.png\n[bartosz github]: https://github.com/BartoszMilewski\n[nixos wiki flake]: https://wiki.nixos.org/wiki/Flakes\n[andres raba github]: https://github.com/sarabander\n[contributors]: https://github.com/hmemcpy/milewski-ctfp-pdf/graphs/contributors\n[license cc by sa]: https://spdx.org/licenses/CC-BY-SA-4.0.html\n[license gnu gpl]: https://spdx.org/licenses/GPL-3.0.html\n[blogpost series]:\n  https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/\n[buy regular edition on blurb]:\n  https://www.blurb.com/b/9621951-category-theory-for-programmers-new-edition-hardco\n[buy scala edition on blurb]:\n  https://www.blurb.com/b/9603882-category-theory-for-programmers-scala-edition-pape\n[v1.3.0 github release link]:\n  https://github.com/hmemcpy/milewski-ctfp-pdf/releases/tag/v1.3.0\n[nix website]: https://nixos.org/nix/\n[nix download website]: https://nixos.org/download.html\n"
  },
  {
    "path": "errata-1.0.0.md",
    "content": "## A list of typos/mistakes that were fixed after the initial printed book release.\n\n### Preface\n\n- [#155](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/155) - Typo\n  (physicist -> physicists)\n\n### 6. Simple Algebraic Data Types\n\n- [#176](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/176) - Typo\n  (statements -> statement)\n\n### 8. Functoriality\n\n- [9a3a5a3](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/9a3a5a386e98ef8f926bccd08f572cc19b1a6367) -\n  added clarifications on bifunctoriality vs. separate functoriality (fix by\n  Bartosz)\n\n### 9. Function Types\n\n- [#182](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/182) - Fix typo\n  (chose -> choose)\n\n### 10. Natural Transformations\n\n- [#157](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/157) - Adding\n  paragraph indent\n\n### 12. Limits and Colimits\n\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical error\n\n### 14. Representable Functors\n\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical error\n\n### 18. Adjunctions\n\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling\n  of \"counit\"\n\n### 19. Free/Forgetful Adjunctions\n\n- [#156](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/156) - an instance of\n  the category name **Mon** is appearing as **arg**\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling\n  of \"isomorphism\"\n\n### 20. Monads - Programmer's Definition\n\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix\n  grammatical error\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical error\n\n### 22. Monads Categorically\n\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical error\n\n### 23. Comonads\n\n- [#158](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/158) - fixed\n  incorrect typesetting of `set`\n- [23f522e](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/23f522ec083c2c98f28f15935ff2893ccd1fa76c) -\n  adjusted `Prod`/`Product` names (fix by Bartosz)\n\n### 25. Algebras for Monads\n\n- [#158](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/158) - fixed\n  incorrect typesetting of `set`\n- [#159](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/159) - fixed\n  incorrect typesetting of category terms\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling\n  of \"counit\" and \"morphisms\", fix subscript spacing\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical errors\n\n### 26. Ends and Coends\n\n- [#159](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/159) - fixed\n  incorrect typesetting of category terms\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling\n  of \"coequalizer\", fix subscript spacing\n\n### 27. Kan Extensions\n\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix subscript\n  spacing\n- [31821e5](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/31821e5ded0dacf059e1fcb985be406e8a495107) -\n  postcomposition -> precomposition (fix by Bartosz)\n\n### 28. Enriched Categories\n\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix subscript\n  spacing\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical error\n\n### 29. Topoi\n\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical error\n\n### 30. Lawvere Theories\n\n- [#160](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/160) - Fix spelling\n  of \"coequalizer\"\n- [#162](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/162) - Fix\n  grammatical errors and a typesetting error\n"
  },
  {
    "path": "errata-1.3.0.md",
    "content": "## A list of typos/mistakes that were fixed after the release of the new edition (1.3.0) (12 August, 2019).\n\n(see errata for the original edition until 1.3.0\n[here](https://github.com/hmemcpy/milewski-ctfp-pdf/blob/master/errata-1.0.0.md))\n\n### Preface\n\n- [#278](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/278) - Fixed\n  reference to Saunders Mac Lane's _Categories for the Working Mathematician_.\n  Was previously misreferenced as \"_Category Theory_ for the Working\n  Mathematician.\"\n\n### 12. Limits and Colimits\n\n- [#278](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/278) - Fixed\n  formatting of quotation marks around \"selecting.\" Were previously pointing the\n  wrong direction.\n\n### 18. Adjunctions\n\n- [#228](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/228) - Typo\n  (adjuncion -> adjunction)\n\n### 30. Lawvere Theories\n\n- [#226](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/226) - fix type in\n  diagram of monads as coends\n"
  },
  {
    "path": "errata-scala.md",
    "content": "## A list of typos/mistakes that were fixed after the initial printed book release (12 August, 2019).\n\n### 7. Functors\n\n- [3d29cd9](https://github.com/hmemcpy/milewski-ctfp-pdf/commit/3d29cd99f34ce1205ed9a68aeae038d9d47c7145) -\n  Added `LazyList` example, supported since Scala 2.13\n\n- [#210](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/210) - Section 6.4 -\n  `prodToSum` snippet. Explicitly Tupling return type to avoid adapted args\n  warning, which is deprecated behavior\n\n- [#243](https://github.com/hmemcpy/milewski-ctfp-pdf/pull/243) - Section 8.7 -\n  Change bimap to dimap in Profunctor definition\n"
  },
  {
    "path": "flake.nix",
    "content": "{\n  description = \"Category Theory for Programmers\";\n\n  inputs.nixpkgs.url = \"github:NixOS/nixpkgs/nixpkgs-unstable\";\n  inputs.systems.url = \"github:nix-systems/default\";\n\n  outputs = inputs@{ self, flake-parts, nixpkgs, ... }:\n    flake-parts.lib.mkFlake { inherit inputs; } {\n      systems = import inputs.systems;\n\n      perSystem = { config, pkgs, system, lib, ... }:\n        let\n          pkgs = nixpkgs.legacyPackages.${system};\n\n          ########################################################################\n          # LaTeX Font\n          inconsolata-lgc-latex = pkgs.stdenvNoCC.mkDerivation {\n            name = \"inconsolata-lgc-latex\";\n            pname = \"inconsolata-lgc-latex\";\n\n            src = pkgs.inconsolata-lgc;\n\n            dontConfigure = true;\n            sourceRoot = \".\";\n\n            installPhase = ''\n              runHook preInstall\n\n              find $src -name '*.ttf' -exec install -m644 -Dt $out/fonts/truetype/public/inconsolata-lgc/ {} \\;\n              find $src -name '*.otf' -exec install -m644 -Dt $out/fonts/opentype/public/inconsolata-lgc/ {} \\;\n\n              runHook postInstall\n            '';\n\n            tlType = \"run\";\n          };\n\n          ########################################################################\n          # LaTeX Environment\n          texliveEnv = pkgs.texlive.combine {\n            inherit\n              (pkgs.texlive)\n              adjustbox\n              alegreya\n              babel\n              bookcover\n              catchfile\n              chngcntr\n              collectbox\n              currfile\n              emptypage\n              enumitem\n              environ\n              fgruler\n              fontaxes\n              framed\n              fvextra\n              idxlayout\n              ifmtarg\n              ifnextok\n              ifplatform\n              imakeidx\n              import\n              inconsolata\n              l3packages\n              lettrine\n              libertine\n              libertinus-fonts\n              listings\n              mdframed\n              microtype\n              minifp\n              minted\n              mweights\n              needspace\n              newtx\n              noindentafter\n              nowidow\n              scheme-medium\n              subfigure\n              subfiles\n              textpos\n              tcolorbox\n              tikz-cd\n              titlecaps\n              titlesec\n              todonotes\n              trimspaces\n              upquote\n              wrapfig\n              xifthen\n              xpatch\n              xstring\n              zref\n              ;\n\n            inconsolata-lgc-latex = {\n              pkgs = [ inconsolata-lgc-latex ];\n            };\n          };\n\n          commonAttrs = {\n            nativeBuildInputs = [\n              texliveEnv\n              (\n                pkgs.python3.withPackages (p: [ p.pygments p.pygments-style-github ])\n              )\n              pkgs.which\n            ];\n          };\n\n          mkLatex = variant: edition:\n            let\n              maybeVariant = lib.optionalString (variant != null) \"-${variant}\";\n              maybeEdition = lib.optionalString (edition != null) \"-${edition}\";\n              variantStr =\n                if variant == null\n                then \"reader\"\n                else variant;\n              basename = \"ctfp-${variantStr}${maybeEdition}\";\n              version = self.shortRev or self.lastModifiedDate;\n              suffix = maybeVariant + maybeEdition;\n              fullname = \"ctfp${suffix}\";\n            in\n            pkgs.stdenvNoCC.mkDerivation (commonAttrs\n              // {\n              inherit basename version;\n              name = basename;\n\n              src = \"${self}/src\";\n\n              configurePhase = ''\n                runHook preConfigure\n\n                substituteInPlace \"version.tex\" --replace \"dev\" \"${version}\"\n\n                runHook postConfigure\n              '';\n\n              buildPhase = ''\n                runHook preBuild\n\n                latexmk -file-line-error -shell-escape -logfilewarninglist \\\n                        -interaction=nonstopmode -halt-on-error -norc \\\n                        -jobname=ctfp -pdflatex=\"xelatex %O %S\" -pdfxe \\\n                        \"$basename.tex\"\n\n                runHook postBuild\n              '';\n\n              installPhase = \"\n                runHook preInstall\n\n                install -m 0644 -vD ctfp.pdf \\\"$out/${fullname}.pdf\\\"\n\n                runHook postInstall\n              \";\n\n              passthru.packageName = fullname;\n            });\n\n          editions = [ null \"scala\" \"ocaml\" \"reason\" ];\n          variants = [ null \"print\" ];\n        in\n        {\n          formatter = pkgs.nixpkgs-fmt;\n\n          packages = lib.listToAttrs (lib.concatMap\n            (variant:\n              map\n                (edition: rec {\n                  value = mkLatex variant edition;\n                  name = value.packageName;\n                })\n                editions)\n            variants);\n\n          # nix develop .\n          devShells.default = pkgs.mkShellNoCC (commonAttrs\n            // {\n            nativeBuildInputs =\n              commonAttrs.nativeBuildInputs\n                ++ [\n                pkgs.git\n                pkgs.gnumake\n              ];\n          });\n        };\n    };\n}\n"
  },
  {
    "path": "src/acknowledgments.tex",
    "content": "\\noindent\nI’d like to thank Edward Kmett and Gershom Bazerman for checking my math\nand logic. I'm grateful to many volunteers who corrected my mistakes and improved the book.\n\n\\vspace{1.0em}\n\\noindent\nI’d like to thank Andrew Sutton for rewriting my C++ monoid concept\ncode according to his and Bjarne Stroustrup’s latest proposal.\n\n\\vspace{1.0em}\n\\noindent\nI'm grateful to Eric Niebler for reading the draft and providing the\nclever implementation of \\code{compose} that uses advanced features of\nC++14 to drive type inference. I was able to cut the whole section of\nold fashioned template magic that did the same thing using type traits.\nGood riddance!"
  },
  {
    "path": "src/category.tex",
    "content": "\\newcommand{\\cat}{%\n  \\symbf%\n}\n\\newcommand{\\idarrow}[1][]{%\n  \\mathbf{id}_{#1}%\n}\n\\newcommand{\\Lim}[1][]{%\n  \\mathbf{Lim}{#1}%\n}\n\\newcommand{\\Set}{\\cat{Set}}\n\\newcommand{\\Rel}{\\cat{Rel}}\n\\newcommand{\\Cat}{\\cat{Cat}}\n\\newcommand{\\id}{\\mathbf{id}}\n\\newcommand{\\Ran}{\\mathbf{Ran}}\n\\newcommand{\\Lan}{\\mathbf{Lan}}\n\\newcommand{\\Hask}{\\mathbf{Hask}}\n\\newcommand{\\Fop}{\\cat{F}^\\mathit{op}}\n"
  },
  {
    "path": "src/colophon.tex",
    "content": "\\lettrine[lraise=-0.03,loversize=0.08]{T}{his book} was compiled by \\urlref{https://hmemcpy.com}{Igal Tabachnik}, by converting the original text by Bartosz Milewski into \\LaTeX{} format, by\nfirst scraping the original WordPress blog posts using \\urlref{https://mercury.postlight.com/web-parser/}{Mercury Web Parser}\nto get a clean HTML content, modifying and tweaking with \\urlref{https://www.crummy.com/software/BeautifulSoup/}{Beautiful Soup},\nfinally, converting to \\LaTeX{} with \\urlref{https://pandoc.org/}{Pandoc}.\n\nThe typefaces are Linux Libertine for body text and Linux Biolinum for headings, both by Philipp H. Poll. Typewriter face is Inconsolata\ncreated by Raph Levien and supplemented by Dimosthenis Kaponis and Takashi Tanigawa in the form of Inconsolata \\acronym{LGC}. The cover page\ntypeface is Alegreya, designed by Juan Pablo del Peral.\n\nOriginal book layout design and typography are done by Andres Raba. Syntax highlighting is using ``GitHub'' style for Pygments by\n\\urlref{https://github.com/hugomaiavieira/pygments-style-github}{Hugo Maia Vieira}.\n\\ifdefined\\OPTCustomLanguage{%\n    \\input{content/\\OPTCustomLanguage/colophon}\n  }\n\\fi"
  },
  {
    "path": "src/content/0.0/preface.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\begin{quote}\n  For some time now I've been floating the idea of writing a book about\n  category theory that would be targeted at programmers. Mind you, not\n  computer scientists but programmers --- engineers rather than\n  scientists. I know this sounds crazy and I am properly scared. I can't\n  deny that there is a huge gap between science and engineering because I\n  have worked on both sides of the divide. But I've always felt a very\n  strong compulsion to explain things. I have tremendous admiration for\n  Richard Feynman who was the master of simple explanations. I know I'm no\n  Feynman, but I will try my best. I'm starting by publishing this preface\n  --- which is supposed to motivate the reader to learn category theory\n  --- in hopes of starting a discussion and soliciting feedback.\\footnote{\n    You may also watch me teach this material to a live audience, at\n    \\href{https://goo.gl/GT2UWU}{https://goo.gl/GT2UWU} (or search\n    ``bartosz milewski category theory'' on YouTube.)}\n\\end{quote}\n\n\\lettrine[lhang=0.17]{I}{will attempt}, in the space of a few paragraphs,\nto convince you that this book is written for you, and whatever\nobjections you might have to learning one of the most abstract branches\nof mathematics in your ``copious spare time'' are totally unfounded.\n\nMy optimism is based on several observations. First, category theory is\na treasure trove of extremely useful programming ideas. Haskell\nprogrammers have been tapping this resource for a long time, and the\nideas are slowly percolating into other languages, but this process is\ntoo slow. We need to speed it up.\n\nSecond, there are many different kinds of math, and they appeal to\ndifferent audiences. You might be allergic to calculus or algebra, but\nit doesn't mean you won't enjoy category theory. I would go as far as\nto argue that category theory is the kind of math that is particularly\nwell suited for the minds of programmers. That's because category theory\n--- rather than dealing with particulars --- deals with structure. It\ndeals with the kind of structure that makes programs composable.\n\nComposition is at the very root of category theory --- it's part of the\ndefinition of the category itself. And I will argue strongly that\ncomposition is the essence of programming. We've been composing things\nforever, long before some great engineer came up with the idea of a\nsubroutine. Some time ago the principles of structured programming\nrevolutionized programming because they made blocks of code composable.\nThen came object oriented programming, which is all about composing\nobjects. Functional programming is not only about composing functions\nand algebraic data structures --- it makes concurrency composable ---\nsomething that's virtually impossible with other programming paradigms.\n\nThird, I have a secret weapon, a butcher's knife, with which I will\nbutcher math to make it more palatable to programmers. When you're a\nprofessional mathematician, you have to be very careful to get all your\nassumptions straight, qualify every statement properly, and construct\nall your proofs rigorously. This makes mathematical papers and books\nextremely hard to read for an outsider. I'm a physicist by training, and\nin physics we made amazing advances using informal reasoning.\nMathematicians laughed at the Dirac delta function, which was made up on\nthe spot by the great physicist P. A. M. Dirac to solve some\ndifferential equations. They stopped laughing when they discovered a\ncompletely new branch of calculus called distribution theory that\nformalized Dirac's insights.\n\nOf course when using hand-waving arguments you run the risk of saying\nsomething blatantly wrong, so I will try to make sure that there is\nsolid mathematical theory behind informal arguments in this book. I do\nhave a worn-out copy of Saunders Mac Lane's \\emph{Categories for\n  the Working Mathematician} on my nightstand.\n\nSince this is category theory \\emph{for programmers} I will illustrate\nall major concepts using computer code. You are probably aware that\nfunctional languages are closer to math than the more popular imperative\nlanguages. They also offer more abstracting power. So a natural\ntemptation would be to say: You must learn Haskell before the bounty of\ncategory theory becomes available to you. But that would imply that\ncategory theory has no application outside of functional programming and\nthat's simply not true. So I will provide a lot of C++ examples.\nGranted, you'll have to overcome some ugly syntax, the patterns might\nnot stand out from the background of verbosity, and you might be forced\nto do some copy and paste in lieu of higher abstraction, but that's just\nthe lot of a C++ programmer.\n\nBut you're not off the hook as far as Haskell is concerned. You don't\nhave to become a Haskell programmer, but you need it as a language for\nsketching and documenting ideas to be implemented in C++. That's exactly\nhow I got started with Haskell. I found its terse syntax and powerful\ntype system a great help in understanding and implementing C++\ntemplates, data structures, and algorithms. But since I can't expect the\nreaders to already know Haskell, I will introduce it slowly and explain\neverything as I go.\n\nIf you're an experienced programmer, you might be asking yourself: I've\nbeen coding for so long without worrying about category theory or\nfunctional methods, so what's changed? Surely you can't help but notice\nthat there's been a steady stream of new functional features invading\nimperative languages. Even Java, the bastion of object-oriented\nprogramming, let the lambdas in. C++ has recently been evolving at a\nfrantic pace --- a new standard every few years --- trying to catch up\nwith the changing world. All this activity is in preparation for a\ndisruptive change or, as we physicists call it, a phase transition. If\nyou keep heating water, it will eventually start boiling. We are now in\nthe position of a frog that must decide if it should continue swimming\nin increasingly hot water, or start looking for some alternatives.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/img_1299.jpg}\n\\end{figure}\n\n\\noindent\nOne of the forces that are driving the big change is the multicore\nrevolution. The prevailing programming paradigm, object oriented\nprogramming, doesn't buy you anything in the realm of concurrency and\nparallelism, and instead encourages dangerous and buggy design. Data\nhiding, the basic premise of object orientation, when combined with\nsharing and mutation, becomes a recipe for data races. The idea of\ncombining a mutex with the data it protects is nice but, unfortunately,\nlocks don't compose, and lock hiding makes deadlocks more likely and\nharder to debug.\n\nBut even in the absence of concurrency, the growing complexity of\nsoftware systems is testing the limits of scalability of the imperative\nparadigm. To put it simply, side effects are getting out of hand.\nGranted, functions that have side effects are often convenient and easy\nto write. Their effects can in principle be encoded in their names and\nin the comments. A function called SetPassword or WriteFile is obviously\nmutating some state and generating side effects, and we are used to\ndealing with that. It's only when we start composing functions that have\nside effects on top of other functions that have side effects, and so\non, that things start getting hairy. It's not that side effects are\ninherently bad --- it's the fact that they are hidden from view that\nmakes them impossible to manage at larger scales. Side effects don't\nscale, and imperative programming is all about side effects.\n\nChanges in hardware and the growing complexity of software are forcing\nus to rethink the foundations of programming. Just like the builders of\nEurope's great gothic cathedrals we've been honing our craft to the\nlimits of material and structure. There is an unfinished gothic\n\\urlref{http://en.wikipedia.org/wiki/Beauvais_Cathedral}{cathedral in\n  Beauvais}, France, that stands witness to this deeply human struggle\nwith limitations. It was intended to beat all previous records of height\nand lightness, but it suffered a series of collapses. Ad hoc measures\nlike iron rods and wooden supports keep it from disintegrating, but\nobviously a lot of things went wrong. From a modern perspective, it's a\nmiracle that so many gothic structures had been successfully completed\nwithout the help of modern material science, computer modelling, finite\nelement analysis, and general math and physics. I hope future\ngenerations will be as admiring of the programming skills we've been\ndisplaying in building complex operating systems, web servers, and the\ninternet infrastructure. And, frankly, they should, because we've done\nall this based on very flimsy theoretical foundations. We have to fix\nthose foundations if we want to move forward.\n\n\\begin{figure}\n  \\centering\n  \\includegraphics[totalheight=0.5\\textheight]{images/beauvais_interior_supports.jpg}\n  \\caption{Ad hoc measures preventing the Beauvais cathedral from collapsing.}\n\\end{figure}\n"
  },
  {
    "path": "src/content/1.1/category-the-essence-of-composition.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{A}{category} is an embarrassingly simple concept.\nA category consists of \\newterm{objects} and \\newterm{arrows} that go between them. That's\nwhy categories are so easy to represent pictorially. An object can be\ndrawn as a circle or a point, and an arrow\\ldots{} is an arrow. (Just\nfor variety, I will occasionally draw objects as piggies and arrows as\nfireworks.) But the essence of a category is \\emph{composition}. Or, if you\nprefer, the essence of composition is a category. Arrows compose, so\nif you have an arrow from object $A$ to object $B$, and another arrow from\nobject $B$ to object $C$, then there must be an arrow --- their composition\n--- that goes from $A$ to $C$.\n\n\\begin{figure}\n  \\centering\n  \\includegraphics[width=0.8\\textwidth]{images/img_1330.jpg}\n  \\caption{In a category, if there is an arrow going from $A$ to $B$ and an arrow going from $B$ to $C$\n    then there must also be a direct arrow from $A$ to $C$ that is their composition. This diagram is not a full\n    category because it’s missing identity morphisms (see later).}\n\\end{figure}\n\n\\section{Arrows as Functions}\n\nIs this already too much abstract nonsense? Do not despair. Let's talk\nconcretes. Think of arrows, which are also called \\newterm{morphisms}, as\nfunctions. You have a function $f$ that takes an argument of type $A$ and\nreturns a $B$. You have another function $g$ that takes a $B$ and returns a $C$.\nYou can compose them by passing the result of $f$ to $g$. You have just\ndefined a new function that takes an $A$ and returns a $C$.\n\nIn math, such composition is denoted by a small circle between\nfunctions: $g \\circ f$. Notice the right to left order of composition. For some\npeople this is confusing. You may be familiar with the pipe notation in\nUnix, as in:\n\n\\begin{snip}{text}\nlsof | grep Chrome\n\\end{snip}\nor the chevron \\code{>>} in F\\#, which both\ngo from left to right. But in mathematics and in Haskell functions\ncompose right to left. It helps if you read $g \\circ f$ as ``g \\emph{after} f.''\n\nLet's make this even more explicit by writing some C code. We have one\nfunction \\code{f} that takes an argument of type \\code{A} and\nreturns a value of type \\code{B}:\n\n\\begin{snip}{text}\nB f(A a);\n\\end{snip}\nand another:\n\n\\begin{snip}{text}\nC g(B b);\n\\end{snip}\nTheir composition is:\n\n\\begin{snip}{text}\nC g_after_f(A a)\n{\n    return g(f(a));\n}\n\\end{snip}\nHere, again, you see right-to-left composition: \\code{g(f(a))}; this\ntime in C.\n\nI wish I could tell you that there is a template in the C++ Standard\nLibrary that takes two functions and returns their composition, but\nthere isn't one. So let's try some Haskell for a change. Here's the\ndeclaration of a function from A to B:\n\n\\src{snippet01}\nSimilarly:\n\n\\src{snippet02}\nTheir composition is:\n\n\\src{snippet03}\nOnce you see how simple things are in Haskell, the inability to express\nstraightforward functional concepts in C++ is a little embarrassing. In\nfact, Haskell will let you use Unicode characters so you can write\ncomposition as:\n% don't 'mathify' this block\n\\begin{snip}{text}\ng ◦ f\n\\end{snip}\n\nYou can even use Unicode double colons and arrows:\n% don't 'mathify' this block\n\\begin{snipv}\nf \\ensuremath{\\Colon} A → B\n\\end{snipv}\nSo here's the first Haskell lesson: Double colon means ``has the type\nof\\ldots{}'' A function type is created by inserting an arrow between\ntwo types. You compose two functions by inserting a period between them\n(or a Unicode circle).\n\n\\section{Properties of Composition}\n\nThere are two extremely important properties that the composition in any\ncategory must satisfy.\n\n\\begin{enumerate}\n  \\item\n        Composition is associative. If you have three morphisms, $f$, $g$, and $h$,\n        that can be composed (that is, their objects match end-to-end), you\n        don't need parentheses to compose them. In math notation this is\n        expressed as:\n        \\[h \\circ (g \\circ f) = (h \\circ g) \\circ f = h \\circ g \\circ f\\]\n        In (pseudo) Haskell:\n\n        \\src{snippet04}[b]\n        (I said ``pseudo,'' because equality is not defined for functions.)\n\n        Associativity is pretty obvious when dealing with functions, but it may\n        be not as obvious in other categories.\n\n  \\item\n        For every object $A$ there is an arrow which is a unit of composition.\n        This arrow loops from the object to itself. Being a unit of composition\n        means that, when composed with any arrow that either starts at $A$ or ends\n        at $A$, respectively, it gives back the same arrow. The unit arrow for\n        object A is called $\\idarrow[A]$ (\\newterm{identity} on $A$). In math\n        notation, if $f$ goes from $A$ to $B$ then\n        \\[f \\circ \\idarrow[A] = f\\]\n        and\n        \\[\\idarrow[B] \\circ f = f\\]\n\\end{enumerate}\nWhen dealing with functions, the identity arrow is implemented as the\nidentity function that just returns back its argument. The\nimplementation is the same for every type, which means this function is\nuniversally polymorphic. In C++ we could define it as a template:\n\n\\begin{snip}{cpp}\ntemplate<typename T> T id(T x) { return x; }\n\\end{snip}\nOf course, in C++ nothing is that simple, because you have to take into\naccount not only what you're passing but also how (that is, by value, by\nreference, by const reference, by move, and so on).\n\nIn Haskell, the identity function is part of the standard library\n(called Prelude). Here's its declaration and definition:\n\n\\src{snippet05}\nAs you can see, polymorphic functions in Haskell are a piece of cake. In\nthe declaration, you just replace the type with a type variable. Here's\nthe trick: names of concrete types always start with a capital letter,\nnames of type variables start with a lowercase letter. So here\n\\code{a} stands for all types.\n\nHaskell function definitions consist of the name of the function\nfollowed by formal parameters --- here just one, \\code{x}. The body of\nthe function follows the equal sign. This terseness is often shocking to\nnewcomers but you will quickly see that it makes perfect sense. Function\ndefinition and function call are the bread and butter of functional\nprogramming so their syntax is reduced to the bare minimum. Not only are\nthere no parentheses around the argument list but there are no commas\nbetween arguments (you'll see that later, when we define functions of\nmultiple arguments).\n\nThe body of a function is always an expression --- there are no\nstatements in functions. The result of a function is this expression ---\nhere, just \\code{x}.\n\nThis concludes our second Haskell lesson.\n\nThe identity conditions can be written (again, in pseudo-Haskell) as:\n\n\\src{snippet06}\nYou might be asking yourself the question: Why would anyone bother with\nthe identity function --- a function that does nothing? Then again, why\ndo we bother with the number zero? Zero is a symbol for nothing. Ancient\nRomans had a number system without a zero and they were able to build\nexcellent roads and aqueducts, some of which survive to this day.\n\nNeutral values like zero or $\\id$ are extremely useful when\nworking with symbolic variables. That's why Romans were not very good at\nalgebra, whereas the Arabs and the Persians, who were familiar with the\nconcept of zero, were. So the identity function becomes very handy as an\nargument to, or a return from, a higher-order function. Higher order\nfunctions are what make symbolic manipulation of functions possible.\nThey are the algebra of functions.\n\nTo summarize: A category consists of objects and arrows (morphisms).\nArrows can be composed, and the composition is associative. Every object\nhas an identity arrow that serves as a unit under composition.\n\n\\section{Composition is the Essence of Programming}\n\nFunctional programmers have a peculiar way of approaching problems. They\nstart by asking very Zen-like questions. For instance, when designing an\ninteractive program, they would ask: What is interaction? When\nimplementing Conway's Game of Life, they would probably ponder about the\nmeaning of life. In this spirit, I'm going to ask: What is programming?\nAt the most basic level, programming is about telling the computer what\nto do. ``Take the contents of memory address x and add it to the\ncontents of the register EAX.'' But even when we program in assembly,\nthe instructions we give the computer are an expression of something\nmore meaningful. We are solving a non-trivial problem (if it were\ntrivial, we wouldn't need the help of the computer). And how do we solve\nproblems? We decompose bigger problems into smaller problems. If the\nsmaller problems are still too big, we decompose them further, and so\non. Finally, we write code that solves all the small problems. And then\ncomes the essence of programming: we compose those pieces of code to\ncreate solutions to larger problems. Decomposition wouldn't make sense\nif we weren't able to put the pieces back together.\n\nThis process of hierarchical decomposition and recomposition is not\nimposed on us by computers. It reflects the limitations of the human\nmind. Our brains can only deal with a small number of concepts at a\ntime. One of the most cited papers in psychology,\n\\urlref{http://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two}{The\n  Magical Number Seven, Plus or Minus Two}, postulated that we can only\nkeep $7 \\pm 2$ ``chunks'' of information in our minds. The details of our\nunderstanding of the human short-term memory might be changing, but we\nknow for sure that it's limited. The bottom line is that we are unable\nto deal with the soup of objects or the spaghetti of code. We need\nstructure not because well-structured programs are pleasant to look at,\nbut because otherwise our brains can't process them efficiently. We\noften describe some piece of code as elegant or beautiful, but what we\nreally mean is that it's easy to process by our limited human minds.\nElegant code creates chunks that are just the right size and come in\njust the right number for our mental digestive system to assimilate\nthem.\n\nSo what are the right chunks for the composition of programs? Their\nsurface area has to increase slower than their volume. (I like this\nanalogy because of the intuition that the surface area of a geometric\nobject grows with the square of its size --- slower than the volume,\nwhich grows with the cube of its size.) The surface area is the\ninformation we need in order to compose chunks. The volume is the\ninformation we need in order to implement them. The idea is that, once a\nchunk is implemented, we can forget about the details of its\nimplementation and concentrate on how it interacts with other chunks. In\nobject-oriented programming, the surface is the class declaration of the\nobject, or its abstract interface. In functional programming, it's the\ndeclaration of a function. (I'm simplifying things a bit, but that's the\ngist of it.)\n\nCategory theory is extreme in the sense that it actively discourages us\nfrom looking inside the objects. An object in category theory is an\nabstract nebulous entity. All you can ever know about it is how it\nrelates to other objects --- how it connects with them using arrows. This\nis how internet search engines rank web sites by analyzing incoming and\noutgoing links (except when they cheat). In object-oriented programming,\nan idealized object is only visible through its abstract interface (pure\nsurface, no volume), with methods playing the role of arrows. The moment\nyou have to dig into the implementation of the object in order to\nunderstand how to compose it with other objects, you've lost the\nadvantages of your programming paradigm.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Implement, as best as you can, the identity function in your favorite\n        language (or the second favorite, if your favorite language happens to\n        be Haskell).\n  \\item\n        Implement the composition function in your favorite language. It takes\n        two functions as arguments and returns a function that is their\n        composition.\n  \\item\n        Write a program that tries to test that your composition function\n        respects identity.\n  \\item\n        Is the world-wide web a category in any sense? Are links morphisms?\n  \\item\n        Is Facebook a category, with people as objects and friendships as\n        morphisms?\n  \\item\n        When is a directed graph a category?\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.1/code/haskell/snippet01.hs",
    "content": "f :: A -> B"
  },
  {
    "path": "src/content/1.1/code/haskell/snippet02.hs",
    "content": "g :: B -> C"
  },
  {
    "path": "src/content/1.1/code/haskell/snippet03.hs",
    "content": "g . f"
  },
  {
    "path": "src/content/1.1/code/haskell/snippet04.hs",
    "content": "f :: A -> B\ng :: B -> C\nh :: C -> D\nh . (g . f) == (h . g) . f == h . g . f"
  },
  {
    "path": "src/content/1.1/code/haskell/snippet05.hs",
    "content": "id :: a -> a\nid x = x"
  },
  {
    "path": "src/content/1.1/code/haskell/snippet06.hs",
    "content": "f . id == f\nid . f == f"
  },
  {
    "path": "src/content/1.1/code/ocaml/snippet01.ml",
    "content": "module type Polymorphic_Function_F = sig\n  type a\n  type b\n\n  val f : a -> b\nend\n"
  },
  {
    "path": "src/content/1.1/code/ocaml/snippet02.ml",
    "content": "module type Polymorphic_Function_G = sig\n  type b\n  type c\n\n  val g : b -> c\nend\n"
  },
  {
    "path": "src/content/1.1/code/ocaml/snippet03.ml",
    "content": "module Compose_Example\n    (F : Polymorphic_Function_F)\n    (G : Polymorphic_Function_G with type b = F.b) =\nstruct\n  (** OCaml doesn't have a compose operator. So, creating one. **)\n  let ( >> ) g f x = g (f x)\n\n  let compose : 'a -> 'c = G.g >> F.f\nend\n"
  },
  {
    "path": "src/content/1.1/code/ocaml/snippet04.ml",
    "content": "module Compose_Three_GF = functor(F:Polymorphic_Function_F)(G:Polymorphic_Function_G with type b = F.b)(H:Polymorphic_Function_H with type c = G.c) -> struct\n  let compose : 'a -> 'd = H.h >> (G.g >> F.f)\nend\n\nmodule Compose_Three_HG = functor(F:Polymorphic_Function_F)(G:Polymorphic_Function_G with type b = F.b)(H:Polymorphic_Function_H with type c = G.c) -> struct\n  let compose : 'a -> 'd = (H.h >> G.g) >> F.f\nend\n\nCompose_Three_GF.compose = Compose_Three_HG.compose\n"
  },
  {
    "path": "src/content/1.1/code/ocaml/snippet05.ml",
    "content": "let id x = x\n"
  },
  {
    "path": "src/content/1.1/code/ocaml/snippet06.ml",
    "content": "f >> id\nid >> f\n"
  },
  {
    "path": "src/content/1.1/code/reason/snippet01.re",
    "content": "module type Polymorphic_Function_F = {\n  type a;\n  type b;\n  \n  let f: a => b;\n};\n"
  },
  {
    "path": "src/content/1.1/code/reason/snippet02.re",
    "content": "module type Polymorphic_Function_G = {\n  type b;\n  type c;\n  \n  let g: b => c;\n};\n"
  },
  {
    "path": "src/content/1.1/code/reason/snippet03.re",
    "content": "module Compose_Example =\n       (\n         F: Polymorphic_Function_F,\n         G: Polymorphic_Function_G with type b = F.b,\n       ) => {\n  /** ReasonML doesn't have a compose operator. So, creating one. **/\n  let (>>) = (g, f, x) => g(f(x));\n\n  let compose: 'a => 'c = (G.g >> F.f: 'a => 'c);\n};\n"
  },
  {
    "path": "src/content/1.1/code/reason/snippet04.re",
    "content": "module Compose_Three_GF =\n       (\n         F: Polymorphic_Function_F,\n         G: Polymorphic_Function_G with type b = F.b,\n         H: Polymorphic_Function_H with type c = G.c,\n       ) => {\n  let compose: 'a => 'd = H.h >> (G.g >> F.f);\n};\n\nmodule Compose_Three_HG =\n       (\n         F: Polymorphic_Function_F,\n         G: Polymorphic_Function_G with type b = F.b,\n         H: Polymorphic_Function_H with type c = G.c,\n       ) => {\n  let compose: 'a => 'd = H.h >> G.g >> F.f;\n};\n\nCompose_Three_GF.compose == Compose_Three_HG.compose"
  },
  {
    "path": "src/content/1.1/code/reason/snippet05.re",
    "content": "let id = x => x;\n"
  },
  {
    "path": "src/content/1.1/code/reason/snippet06.re",
    "content": "f >> id;\nid >> f;\n"
  },
  {
    "path": "src/content/1.1/code/scala/snippet01.scala",
    "content": "val f: A => B"
  },
  {
    "path": "src/content/1.1/code/scala/snippet02.scala",
    "content": "val g: B => C"
  },
  {
    "path": "src/content/1.1/code/scala/snippet03.scala",
    "content": "g compose f"
  },
  {
    "path": "src/content/1.1/code/scala/snippet04.scala",
    "content": "val f: A => B\nval g: B => C\nval h: C => D\n\nh compose (g compose f) === (h compose g) compose f === h compose g compose f"
  },
  {
    "path": "src/content/1.1/code/scala/snippet05.scala",
    "content": "def identity[A](a: A): A = a"
  },
  {
    "path": "src/content/1.1/code/scala/snippet06.scala",
    "content": "f compose identity[A] == f\nidentity[B] _ compose f == f"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet01.hs",
    "content": "alpha :: forall a . F a -> G a"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet02.hs",
    "content": "alpha :: F a -> G a"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet03.hs",
    "content": "alpha :: F a -> G a"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet04.hs",
    "content": "safeHead :: [a] -> Maybe a\nsafeHead [] = Nothing\nsafeHead (x:xs) = Just x"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet05.hs",
    "content": "fmap f . safeHead = safeHead . fmap f"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet06.hs",
    "content": "fmap f (safeHead []) = fmap f Nothing = Nothing"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet07.hs",
    "content": "safeHead (fmap f []) = safeHead [] = Nothing"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet08.hs",
    "content": "fmap f (safeHead (x:xs)) = fmap f (Just x) = Just (f x)"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet09.hs",
    "content": "safeHead (fmap f (x:xs)) = safeHead (f x : fmap f xs) = Just (f x)"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet10.hs",
    "content": "fmap f [] = []\nfmap f (x:xs) = f x : fmap f xs"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet11.hs",
    "content": "fmap f Nothing = Nothing\nfmap f (Just x) = Just (f x)"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet12.hs",
    "content": "length :: [a] -> Const Int a\nlength [] = Const 0\nlength (x:xs) = Const (1 + unConst (length xs))"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet13.hs",
    "content": "unConst :: Const c a -> c\nunConst (Const x) = x"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet14.hs",
    "content": "length :: [a] -> Int"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet15.hs",
    "content": "scam :: Const Int a -> Maybe a\nscam (Const x) = Nothing"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet16.hs",
    "content": "newtype Reader e a = Reader (e -> a)"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet17.hs",
    "content": "instance Functor (Reader e) where\n    fmap f (Reader g) = Reader (\\x -> f (g x))"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet18.hs",
    "content": "alpha :: Reader () a -> Maybe a"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet19.hs",
    "content": "dumb (Reader _) = Nothing"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet20.hs",
    "content": "obvious (Reader g) = Just (g ())"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet21.hs",
    "content": "newtype Op r a = Op (a -> r)"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet22.hs",
    "content": "instance Contravariant (Op r) where\n    contramap f (Op g) = Op (g . f)"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet23.hs",
    "content": "predToStr (Op f) = Op (\\x -> if f x then \"T\" else \"F\")"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet24.hs",
    "content": "contramap f . predToStr = predToStr . contramap f"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet25.hs",
    "content": "contramap :: (b -> a) -> (Op Bool a -> Op Bool b)"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet26.hs",
    "content": "a -> a"
  },
  {
    "path": "src/content/1.10/code/haskell/snippet27.hs",
    "content": "(a -> a) -> f a"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet01.ml",
    "content": "val alpha : 'a . 'a f -> 'a g\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet02.ml",
    "content": "val alpha : 'a f -> 'a g\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet03.ml",
    "content": "val alpha : 'a f -> 'a g\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet04.ml",
    "content": "let safe_head = function\n  | [] -> None\n  | x :: xs -> Some x\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet05.ml",
    "content": "compose (fmap f) safe_head = compose safe_head (fmap f)\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet06.ml",
    "content": "(* Starting with empty list *)\nlet fmap f (safe_head []) = fmap f None = None\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet07.ml",
    "content": "let safe_head (fmap f []) = safe_head [] = None\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet08.ml",
    "content": "let fmap f (safe_head (x :: xs)) = fmap f (Some x)= Some (f x)\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet09.ml",
    "content": "let safe_head (fmap f (x :: xs)) = safe_head (f x :: f xs) = Some (f x)\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet10.ml",
    "content": "let rec fmap f = function\n  | [] -> []\n  | x :: xs -> f x :: fmap f xs\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet11.ml",
    "content": "let rec fmap f = function\n  | None -> None\n  | Some x -> Some (f x)\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet12.ml",
    "content": "(** OCaml requires mutually recursive functions to be defined together *)\nlet rec length : 'a list -> (int, 'a) const = function\n  | [] -> Const 0\n  | _ :: xs -> Const (1 + un_const (length xs))\n\nand un_const : 'c 'a. ('c, 'a) const -> 'c = function\n  | Const c -> c\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet13.ml",
    "content": "let un_const : 'c 'a. ('c, 'a) const -> 'c = function\n  | Const c -> c\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet14.ml",
    "content": "val length : 'a list -> int\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet15.ml",
    "content": "let scam : 'a. ('int, 'a) const -> 'a option = function\n  | Const a -> None\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet16.ml",
    "content": "type ('e, 'a) reader = Reader of ('e -> 'a)\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet17.ml",
    "content": "module Reader_Functor (T : sig\n  type e\nend) : Functor = struct\n  type 'a t = (T.e, 'a) reader\n\n  let fmap : 'a 'b. ('a -> 'b) -> 'a t -> 'b t =\n   fun f -> function\n    | Reader r -> Reader (compose f r)\n ;;\nend\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet18.ml",
    "content": "val alpha : (unit, 'a) reader -> 'a option\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet19.ml",
    "content": "let dumb : 'a. (unit, 'a) reader -> 'a option = function\n  | Reader _ -> None\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet20.ml",
    "content": "let obvious : 'a. (unit, 'a) reader -> 'a option = function\n  | Reader f -> Some (f ())\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet21.ml",
    "content": "type ('r, 'a) op = Op of ('a -> 'r)\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet22.ml",
    "content": "module Op_Contravariant (T : sig\n  type r\nend) : Contravariant = struct\n  type 'a t = (T.r, 'a) op\n\n  let contramap : ('b -> 'a) -> 'a t -> 'b t =\n   fun f -> function\n    | Op g -> Op (compose g f)\n ;;\nend\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet23.ml",
    "content": "let pred_to_str = function\n  | Op f -> Op (fun x -> if f x then \"T\" else \"F\")\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet24.ml",
    "content": "compose (contramap f) pred_to_str = compose pred_to_str (contramap f)\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet25.ml",
    "content": "module Op_Bool = Op_Contravariant (struct\n  type r = bool\nend)\n\nlet op_bool_contramap : ('b -> 'a) -> 'a Op_Bool.t -> 'b Op_Bool.t =\n  Op_Bool.contramap\n;;\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet26.ml",
    "content": "'a -> 'a\n"
  },
  {
    "path": "src/content/1.10/code/ocaml/snippet27.ml",
    "content": "('a -> 'a) -> 'a f\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet01.re",
    "content": "let alpha: 'a . f('a) => g('a);"
  },
  {
    "path": "src/content/1.10/code/reason/snippet02.re",
    "content": "let alpha: f('a) => g('a);\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet03.re",
    "content": "let alpha: f('a) => g('a);\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet04.re",
    "content": "let safe_head =\n  fun\n  | [] => None\n  | [x, ...xs] => Some(x);\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet05.re",
    "content": "compose(fmap(f), safe_head) == compose(safe_head, fmap(f));\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet06.re",
    "content": "/* Starting with empty list */\nlet fmap = (f, safe_head([])) == fmap(f, None) == None;"
  },
  {
    "path": "src/content/1.10/code/reason/snippet07.re",
    "content": "let safe_head = (fmap, f, []) == safe_head([]) == None;"
  },
  {
    "path": "src/content/1.10/code/reason/snippet08.re",
    "content": "let fmap = (f, safe_head([x, ... xs])) == fmap(f(Some(x))) == Some(f(x));"
  },
  {
    "path": "src/content/1.10/code/reason/snippet09.re",
    "content": "let safe_head = \n  (fmap([x, ...xs])) == safe_head(f([x, ... xs])) == Some(f(x));"
  },
  {
    "path": "src/content/1.10/code/reason/snippet10.re",
    "content": "let rec fmap = f =>\n  fun\n  | [] => []\n  | [x, ...xs] => [f(x), ...fmap(f, xs)];\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet11.re",
    "content": "let rec fmap = f =>\n  fun\n  | None => None\n  | Some(x) => Some(f(x));\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet12.re",
    "content": "/* ReasonML requires mutually recursive functions \n* to be defined together */\nlet rec length: list('a) => const(int, 'a) = (\n  fun\n  | [] => Const(0)\n  | [_, ...xs] => Const(1 + un_const(length(xs))):\n    list('a) => const(int, 'a)\n)\nand un_const: 'c 'a. const('c, 'a) => 'c =\n  fun\n  | Const(c) => c;\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet13.re",
    "content": "let un_const: 'c 'a. const('c, 'a) => 'c =\n  fun\n  | Const(c) => c;\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet14.re",
    "content": "let length: list('a) => int;\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet15.re",
    "content": "let scam: 'a. const('int, 'a) => option('a) =\n  fun\n  | Const(a) => None;\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet16.re",
    "content": "type reader('e, 'a) =\n  | Reader('e => 'a);\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet17.re",
    "content": "module Reader_Functor = (T: {type e;}) : Functor => {\n  type t('a) = reader(T.e, 'a);\n  \n  let fmap: 'a 'b. ('a => 'b, t('a)) => t('b) =\n    f =>\n      fun\n      | Reader(r) => Reader(compose(f, r));\n};\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet18.re",
    "content": "let alpha: reader(unit, 'a) => option('a);\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet19.re",
    "content": "let dumb: 'a. reader(unit, 'a) => option('a) =\n  fun\n  | Reader(_) => None;\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet20.re",
    "content": "let obvious: 'a. reader(unit, 'a) => option('a) =\n  fun\n  | Reader(f) => Some(f());\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet21.re",
    "content": "type op('r, 'a) =\n  | Op('a => 'r);\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet22.re",
    "content": "module Op_Contravariant = (T: {type r;}) : Contravariant => {\n  type t('a) = op(T.r, 'a);\n\n  let contramap: ('b => 'a, t('a)) => t('b) =\n    f =>\n      fun\n      | Op(g) => Op(compose(g, f));\n};\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet23.re",
    "content": "let pred_to_str =\n  fun\n  | Op(f) => Op(x => (f(x)) ? \"T\" : \"F\");\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet24.re",
    "content": "compose(contramap(f), pred_to_str) == compose(pred_to_str, contramap(f));\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet25.re",
    "content": "module Op_Bool = Op_Contravariant({type r = bool;});\n\nlet op_bool_contramap: ('b => 'a, Op_Bool.t('a)) => Op_Bool.t('b) = (\n  Op_Bool.contramap: ('b => 'a, Op_Bool.t('a)) => Op_Bool.t('b)\n);\n"
  },
  {
    "path": "src/content/1.10/code/reason/snippet26.re",
    "content": "'a => 'a"
  },
  {
    "path": "src/content/1.10/code/reason/snippet27.re",
    "content": "('a => 'a) => f('a)\n"
  },
  {
    "path": "src/content/1.10/code/scala/snippet01.scala",
    "content": "def alpha[A]: F[A] => G[A]"
  },
  {
    "path": "src/content/1.10/code/scala/snippet02.scala",
    "content": "val alpha: F[A] => G[A]"
  },
  {
    "path": "src/content/1.10/code/scala/snippet03.scala",
    "content": "val alpha: F[A] => G[A]"
  },
  {
    "path": "src/content/1.10/code/scala/snippet04.scala",
    "content": "def safeHead[A]: List[A] => Option[A] = {\n  case Nil => None\n  case x :: xs => Some(x)\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet05.scala",
    "content": "(fmap(f) compose safeHead) == (safeHead compose fmap(f))"
  },
  {
    "path": "src/content/1.10/code/scala/snippet06.scala",
    "content": "fmap(f)(safeHead(List.empty)) == fmap(f)(None) == None"
  },
  {
    "path": "src/content/1.10/code/scala/snippet07.scala",
    "content": "safeHead(fmap(f)(List.empty)) == safeHead(List.empty) == None"
  },
  {
    "path": "src/content/1.10/code/scala/snippet08.scala",
    "content": "fmap(f)(safeHead(x :: xs)) == fmap(f)(Some(x)) == Some(f(x))"
  },
  {
    "path": "src/content/1.10/code/scala/snippet09.scala",
    "content": "safeHead(fmap(f)(x :: xs)) == safeHead(f(1) :: fmap(f)(xs)) == Some(f(x))"
  },
  {
    "path": "src/content/1.10/code/scala/snippet10.scala",
    "content": "def fmap[A, B](f: A => B): List[A] => List[B] = {\n  case Nil => Nil\n  case x :: xs => f(x) :: fmap(f)(xs)\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet11.scala",
    "content": "def fmap[A, B](f: A => B): Option[A] => Option[B] = {\n  case None => None\n  case Some(x) => Some(f(x))\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet12.scala",
    "content": "def length[A]: List[A] => Const[Int, A] = {\n  case Nil => Const(0)\n  case x :: xs => Const(1 + unConst(length(xs)))\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet13.scala",
    "content": "def unConst[C, A]: Const[C, A] => C = {\n  case Const(x) => x\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet14.scala",
    "content": "def length[A]: List[A] => Int"
  },
  {
    "path": "src/content/1.10/code/scala/snippet15.scala",
    "content": "def scam[A]: Const[Int, A] => Option[A] = {\n  case Const(x) => None\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet16.scala",
    "content": "case class Reader[E, A](run: E => A)"
  },
  {
    "path": "src/content/1.10/code/scala/snippet17.scala",
    "content": "implicit def readerFunctor[E] = new Functor[Reader[E, ?]] {\n  def fmap[A, B](f: A => B)(g: Reader[E, A]): Reader[E, B] =\n    Reader(x => f(g.run(x)))\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet18.scala",
    "content": "def alpha[A]: Reader[Unit, A] => Option[A]"
  },
  {
    "path": "src/content/1.10/code/scala/snippet19.scala",
    "content": "def dumb[A]: Reader[Unit, A] => Option[A] = {\n  case Reader(_) => None\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet20.scala",
    "content": "def obvious[A]: Reader[Unit, A] => Option[A] = {\n  case Reader(g) => Some(g())\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet21.scala",
    "content": "case class Op[R, A](f: A => R)"
  },
  {
    "path": "src/content/1.10/code/scala/snippet22.scala",
    "content": "implicit def opContravariant[R] = new Contravariant[Op[R, ?]] {\n  def contramap[A, B](f: B => A): Op[R, A] => Op[R, B] = {\n    case Op(g) => Op(g compose f)\n  }\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet23.scala",
    "content": "def predToStr[A]: Op[Boolean, A] => Op[String, A] = {\n  case Op(f) => Op(x => if (f(x)) \"T\" else \"F\")\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet24.scala",
    "content": "(op.contramap(func) compose predToStr) == (predToStr compose op.contramap(func))"
  },
  {
    "path": "src/content/1.10/code/scala/snippet25.scala",
    "content": "def contramap[A, B](f: B => A): Op[Boolean, A] => Op[Boolean, B] = {\n  case Op(g) => Op(g compose f)\n}"
  },
  {
    "path": "src/content/1.10/code/scala/snippet26.scala",
    "content": "A => A"
  },
  {
    "path": "src/content/1.10/code/scala/snippet27.scala",
    "content": "(A => A) => F[A]"
  },
  {
    "path": "src/content/1.10/natural-transformations.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{W}{e talked about} functors as mappings between categories that preserve\ntheir structure.\n\nA functor ``embeds'' one category in another. It may\ncollapse multiple things into one, but it never breaks connections. One\nway of thinking about it is that with a functor we are modeling one\ncategory inside another. The source category serves as a model, a\nblueprint, for some structure that's part of the target category.\n\n\\begin{figure}[H]\n  \\centering\\includegraphics[width=0.4\\textwidth]{images/1_functors.jpg}\n\\end{figure}\n\n\\noindent\nThere may be many ways of embedding one category in another. Sometimes\nthey are equivalent, sometimes very different. One may collapse the\nwhole source category into one object, another may map every object to a\ndifferent object and every morphism to a different morphism. The same\nblueprint may be realized in many different ways. Natural\ntransformations help us compare these realizations. They are mappings of\nfunctors --- special mappings that preserve their functorial nature.\n\nConsider two functors $F$ and $G$ between categories\n$\\cat{C}$ and $\\cat{D}$. If you focus on just one object $a$ in\n$\\cat{C}$, it is mapped to two objects: $F a$ and $G a$.\nA mapping of functors should therefore map $F a$ to\n$G a$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/2_natcomp.jpg}\n\\end{figure}\n\n\\noindent\nNotice that $F a$ and $G a$ are objects in the same\ncategory $\\cat{D}$. Mappings between objects in the same category should\nnot go against the grain of the category. We don't want to make\nartificial connections between objects. So it's \\emph{natural} to use\nexisting connections, namely morphisms. A natural transformation is a\nselection of morphisms: for every object $a$, it picks one\nmorphism from $F a$ to $G a$. If we call the natural\ntransformation $\\alpha$, this morphism is called the \\newterm{component}\nof $\\alpha$ at $a$, or $\\alpha_a$.\n\n\\[\\alpha_a \\Colon F a \\to G a\\]\nKeep in mind that $a$ is an object in $\\cat{C}$ while $\\alpha_a$\nis a morphism in $\\cat{D}$.\n\nIf, for some $a$, there is no morphism between $F a$ and\n$G a$ in $\\cat{D}$, there can be no natural transformation\nbetween $F$ and $G$.\n\nOf course that's only half of the story, because functors not only map\nobjects, they map morphisms as well. So what does a natural\ntransformation do with those mappings? It turns out that the mapping of\nmorphisms is fixed --- under any natural transformation between $F$ and $G$,\n$F f$ must be transformed into $G f$. What's more, the\nmapping of morphisms by the two functors drastically restricts the\nchoices we have in defining a natural transformation that's compatible\nwith it. Consider a morphism $f$ between two objects $a$\nand $b$ in $\\cat{C}$. It's mapped to two morphisms, $F f$\nand $G f$ in $\\cat{D}$:\n\n\\begin{gather*}\n  F f \\Colon F a \\to F b \\\\\n  G f \\Colon G a \\to G b\n\\end{gather*}\nThe natural transformation $\\alpha$ provides two additional morphisms\nthat complete the diagram in $\\cat{D}$:\n\n\\begin{gather*}\n  \\alpha_a \\Colon F a \\to G a \\\\\n  \\alpha_b \\Colon F b \\to G b\n\\end{gather*}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/3_naturality.jpg}\n\\end{figure}\n\n\\noindent\nNow we have two ways of getting from $F a$ to $G b$. To\nmake sure that they are equal, we must impose the \\newterm{naturality\n  condition} that holds for any $f$:\n\n\\[G f \\circ \\alpha_a = \\alpha_b \\circ F f\\]\nThe naturality condition is a pretty stringent requirement. For\ninstance, if the morphism $F f$ is invertible, naturality\ndetermines $\\alpha_b$ in terms of $\\alpha_a$. It \\emph{transports}\n$\\alpha_a$ along $f$:\n\n\\[\\alpha_b = (G f) \\circ \\alpha_a \\circ (F f)^{-1}\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/4_transport.jpg}\n\\end{figure}\n\n\\noindent\nIf there is more than one invertible morphism between two objects, all\nthese transports have to agree. In general, though, morphisms are not\ninvertible; but you can see that the existence of natural\ntransformations between two functors is far from guaranteed. So the\nscarcity or the abundance of functors that are related by natural\ntransformations may tell you a lot about the structure of categories\nbetween which they operate. We'll see some examples of that when we talk\nabout limits and the Yoneda lemma.\n\nLooking at a natural transformation component-wise, one may say that it\nmaps objects to morphisms. Because of the naturality condition, one may\nalso say that it maps morphisms to commuting squares --- there is one\ncommuting naturality square in $\\cat{D}$ for every morphism in $\\cat{C}$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/naturality.jpg}\n\\end{figure}\n\n\\noindent\nThis property of natural transformations comes in very handy in a lot of\ncategorical constructions, which often include commuting diagrams. With\na judicious choice of functors, a lot of these commutativity conditions\nmay be transformed into naturality conditions. We'll see examples of\nthat when we get to limits, colimits, and adjunctions.\n\nFinally, natural transformations may be used to define isomorphisms of\nfunctors. Saying that two functors are naturally isomorphic is almost\nlike saying they are the same. \\newterm{Natural isomorphism} is defined as\na natural transformation whose components are all isomorphisms\n(invertible morphisms).\n\n\\section{Polymorphic Functions}\n\nWe talked about the role of functors (or, more specifically,\nendofunctors) in programming. They correspond to type constructors that\nmap types to types. They also map functions to functions, and this\nmapping is implemented by a higher order function \\code{fmap} (or\n\\code{transform}, \\code{then}, and the like in C++).\n\nTo construct a natural transformation we start with an object, here a\ntype, \\code{a}. One functor, \\code{F}, maps it to the type\n$F a$. Another functor, \\code{G}, maps it to $G a$.\nThe component of a natural transformation \\code{alpha} at \\code{a}\nis a function from $F a$ to $G a$. In pseudo-Haskell:\n\n\\begin{snipv}\nalpha\\textsubscript{a} :: F a -> G a\n\\end{snipv}\nA natural transformation is a polymorphic function that is defined for\nall types \\code{a}:\n\n\\src{snippet01}\nThe \\code{forall a} is optional in Haskell (and in fact requires\nturning on the language extension \\code{ExplicitForAll}). Normally,\nyou would write it like this:\n\n\\src{snippet02}\nKeep in mind that it's really a family of functions parameterized by\n\\code{a}. This is another example of the terseness of the Haskell\nsyntax. A similar construct in C++ would be slightly more verbose:\n\n\\begin{snip}{cpp}\ntemplate<typename A> G<A> alpha(F<A>);\n\\end{snip}\nThere is a more profound difference between Haskell's polymorphic\nfunctions and C++ generic functions, and it's reflected in the way these\nfunctions are implemented and type-checked. In Haskell, a polymorphic\nfunction must be defined uniformly for all types. One formula must work\nacross all types. This is called \\newterm{parametric polymorphism}.\n\nC++, on the other hand, supports by default \\newterm{ad hoc polymorphism},\nwhich means that a template doesn't have to be well-defined for all\ntypes. Whether a template will work for a given type is decided at\ninstantiation time, where a concrete type is substituted for the type\nparameter. Type checking is deferred, which unfortunately often leads to\nincomprehensible error messages.\n\nIn C++, there is also a mechanism for function overloading and template\nspecialization, which allows different definitions of the same function\nfor different types. In Haskell this functionality is provided by type\nclasses and type families.\n\nHaskell's parametric polymorphism has an unexpected consequence: any\npolymorphic function of the type:\n\n\\src{snippet03}\nwhere \\code{F} and \\code{G} are functors, automatically satisfies\nthe naturality condition. Here it is in categorical notation ($f$\nis a function $f \\Colon a \\to b$):\n\n\\[G f \\circ \\alpha_a = \\alpha_b \\circ F f\\]\nIn Haskell, the action of a functor \\code{G} on a morphism \\code{f}\nis implemented using \\code{fmap}. I'll first write it in\npseudo-Haskell, with explicit type annotations:\n\n\\begin{snipv}\nfmap\\textsubscript{G} f . alpha\\textsubscript{a} = alpha\\textsubscript{b} . fmap\\textsubscript{F} f\n\\end{snipv}\nBecause of type inference, these annotations are not necessary, and the\nfollowing equation holds:\n\n\\begin{snip}{text}\nfmap f . alpha = alpha . fmap f\n\\end{snip}\nThis is still not real Haskell --- function equality is not expressible\nin code --- but it's an identity that can be used by the programmer in\nequational reasoning; or by the compiler, to implement optimizations.\n\nThe reason why the naturality condition is automatic in Haskell has to\ndo with ``theorems for free.'' Parametric polymorphism, which is used to\ndefine natural transformations in Haskell, imposes very strong\nlimitations on the implementation --- one formula for all types. These\nlimitations translate into equational theorems about such functions. In\nthe case of functions that transform functors, free theorems are the\nnaturality conditions.\\footnote{\n  You may read more about free theorems in my\n  blog \\href{https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free/}{``Parametricity:\n    Money for Nothing and Theorems for Free}.''}\n\nOne way of thinking about functors in Haskell that I mentioned earlier\nis to consider them generalized containers. We can continue this analogy\nand consider natural transformations to be recipes for repackaging the\ncontents of one container into another container. We are not touching\nthe items themselves: we don't modify them, and we don't create new\nones. We are just copying (some of) them, sometimes multiple times, into\na new container.\n\nThe naturality condition becomes the statement that it doesn't matter\nwhether we modify the items first, through the application of\n\\code{fmap}, and repackage later; or repackage first, and then modify\nthe items in the new container, with its own implementation of\n\\code{fmap}. These two actions, repackaging and \\code{fmap}ping, are\northogonal. ``One moves the eggs, the other boils them.''\n\nLet's see a few examples of natural transformations in Haskell. The\nfirst is between the list functor, and the \\code{Maybe} functor. It\nreturns the head of the list, but only if the list is non-empty:\n\n\\src{snippet04}\nIt's a function polymorphic in \\code{a}. It works for any type\n\\code{a}, with no limitations, so it is an example of parametric\npolymorphism. Therefore it is a natural transformation between the two\nfunctors. But just to convince ourselves, let's verify the naturality\ncondition.\n\n\\src{snippet05}\nWe have two cases to consider; an empty list:\n\n\\src{snippet06}\n\n\\src{snippet07}\nand a non-empty list:\n\n\\src{snippet08}\n\n\\src{snippet09}\nI used the implementation of \\code{fmap} for lists:\n\n\\src{snippet10}\nand for \\code{Maybe}:\n\n\\src{snippet11}\nAn interesting case is when one of the functors is the trivial\n\\code{Const} functor. A natural transformation from or to a\n\\code{Const} functor looks just like a function that's either\npolymorphic in its return type or in its argument type.\n\nFor instance, \\code{length} can be thought of as a natural\ntransformation from the list functor to the \\code{Const Int} functor:\n\n\\src{snippet12}\nHere, \\code{unConst} is used to peel off the \\code{Const}\nconstructor:\n\n\\src{snippet13}\nOf course, in practice \\code{length} is defined as:\n\n\\src{snippet14}\nwhich effectively hides the fact that it's a natural transformation.\n\nFinding a parametrically polymorphic function \\emph{from} a\n\\code{Const} functor is a little harder, since it would require the\ncreation of a value from nothing. The best we can do is:\n\n\\src{snippet15}\nAnother common functor that we've seen already, and which will play an\nimportant role in the Yoneda lemma, is the \\code{Reader} functor. I\nwill rewrite its definition as a \\code{newtype}:\n\n\\src{snippet16}\nIt is parameterized by two types, but is (covariantly) functorial only\nin the second one:\n\n\\src{snippet17}\nFor every type \\code{e}, you can define a family of natural\ntransformations from \\code{Reader e} to any other functor \\code{f}.\nWe'll see later that the members of this family are always in one to one\ncorrespondence with the elements of \\code{f e} (the\n\\hyperref[the-yoneda-lemma]{Yoneda lemma}).\n\nFor instance, consider the somewhat trivial unit type \\code{()} with\none element \\code{()}. The functor \\code{Reader ()} takes any type\n\\code{a} and maps it into a function type \\code{() -> a}.\nThese are just all the functions that pick a single element from the set\n\\code{a}. There are as many of these as there are elements in\n\\code{a}. Now let's consider natural transformations from this functor\nto the \\code{Maybe} functor:\n\n\\src{snippet18}\nThere are only two of these, \\code{dumb} and \\code{obvious}:\n\n\\src{snippet19}\nand\n\n\\src{snippet20}\n(The only thing you can do with \\code{g} is to apply it to the unit\nvalue \\code{()}.)\n\nAnd, indeed, as predicted by the Yoneda lemma, these correspond to the\ntwo elements of the \\code{Maybe ()} type, which are \\code{Nothing}\nand \\code{Just ()}. We'll come back to the Yoneda lemma later ---\nthis was just a little teaser.\n\n\\section{Beyond Naturality}\n\nA parametrically polymorphic function between two functors (including\nthe edge case of the \\code{Const} functor) is always a natural\ntransformation. Since all standard algebraic data types are functors,\nany polymorphic function between such types is a natural transformation.\n\nWe also have function types at our disposal, and those are functorial in\ntheir return type. We can use them to build functors (like the\n\\code{Reader} functor) and define natural transformations that are\nhigher-order functions.\n\nHowever, function types are not covariant in the argument type. They are\n\\newterm{contravariant}. Of course contravariant functors are equivalent to\ncovariant functors from the opposite category. Polymorphic functions\nbetween two contravariant functors are still natural transformations in\nthe categorical sense, except that they work on functors from the\nopposite category to Haskell types.\n\nYou might remember the example of a contravariant functor we've looked\nat before:\n\n\\src{snippet21}\nThis functor is contravariant in \\code{a}:\n\n\\src{snippet22}\nWe can write a polymorphic function from, say, \\code{Op Bool} to\n\\code{Op String}:\n\n\\src{snippet23}\nBut since the two functors are not covariant, this is not a natural\ntransformation in $\\Hask$. However, because they are both\ncontravariant, they satisfy the ``opposite'' naturality condition:\n\n\\src{snippet24}[b]\nNotice that the function \\code{f} must go in the opposite direction\nthan what you'd use with \\code{fmap}, because of the signature of\n\\code{contramap}:\n\n\\src{snippet25}\nAre there any type constructors that are not functors, whether covariant\nor contravariant? Here's one example:\n\n\\src{snippet26}\nThis is not a functor because the same type \\code{a} is used both in\nthe negative (contravariant) and positive (covariant) position. You\ncan't implement \\code{fmap} or \\code{contramap} for this type.\nTherefore a function of the signature:\n\n\\src{snippet27}\nwhere \\code{f} is an arbitrary functor, cannot be a natural\ntransformation. Interestingly, there is a generalization of natural\ntransformations, called dinatural transformations, that deals with such\ncases. We'll get to them when we discuss ends.\n\n\\section{Functor Category}\n\nNow that we have mappings between functors --- natural transformations\n--- it's only natural to ask the question whether functors form a\ncategory. And indeed they do! There is one category of functors for each\npair of categories, $\\cat{C}$ and $\\cat{D}$. Objects in this category are functors from\n$\\cat{C}$ to $\\cat{D}$, and morphisms are natural transformations between those\nfunctors.\n\nWe have to define composition of two natural transformations, but that's\nquite easy. The components of natural transformations are morphisms, and\nwe know how to compose morphisms.\n\nIndeed, let's take a natural transformation $\\alpha$ from functor $F$ to $G$. Its\ncomponent at object $a$ is some morphism:\n\\[\\alpha_a \\Colon F a \\to G a\\]\nWe'd like to compose $\\alpha$ with $\\beta$, which is a natural transformation from\nfunctor $G$ to $H$. The component of $\\beta$ at $a$ is a morphism:\n\\[\\beta_a \\Colon G a \\to H a\\]\nThese morphisms are composable and their composition is another\nmorphism:\n\\[\\beta_a \\circ \\alpha_a \\Colon F a \\to H a\\]\nWe will use this morphism as the component of the natural transformation\n$\\beta \\cdot \\alpha$ --- the composition of two natural transformations $\\beta$ after $\\alpha$:\n\\[(\\beta \\cdot \\alpha)_a = \\beta_a \\circ \\alpha_a\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/5_vertical.jpg}\n\\end{figure}\n\n\\noindent\nOne (long) look at a diagram convinces us that the result of this\ncomposition is indeed a natural transformation from F to H:\n\\[H f \\circ (\\beta \\cdot \\alpha)_a = (\\beta \\cdot \\alpha)_b \\circ F f\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/6_verticalnaturality.jpg}\n\\end{figure}\n\n\\noindent\nComposition of natural transformations is associative, because their\ncomponents, which are regular morphisms, are associative with respect to\ntheir composition.\n\nFinally, for each functor $F$ there is an identity natural transformation\n$1_F$ whose components are the identity morphisms:\n\\[\\id_{F a} \\Colon F a \\to F a\\]\nSo, indeed, functors form a category.\n\nA word about notation. Following Saunders Mac Lane I use the dot for the\nkind of natural transformation composition I have just described. The\nproblem is that there are two ways of composing natural transformations.\nThis one is called the vertical composition, because the functors are\nusually stacked up vertically in the diagrams that describe it. Vertical\ncomposition is important in defining the functor category. I'll explain\nhorizontal composition shortly.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/6a_vertical.jpg}\n\\end{figure}\n\n\\noindent\nThe functor category between categories $\\cat{C}$ and $\\cat{D}$ is written as\n$\\cat{Fun(C, D)}$, or $\\cat{{[}C, D{]}}$, or sometimes as\n$\\cat{D^C}$. This last notation suggests that a functor category itself\nmight be considered a function object (an exponential) in some other\ncategory. Is this indeed the case?\n\nLet's have a look at the hierarchy of abstractions that we've been\nbuilding so far. We started with a category, which is a collection of\nobjects and morphisms. Categories themselves (or, strictly speaking\n\\emph{small} categories, whose objects form sets) are themselves objects\nin a higher-level category $\\Cat$. Morphisms in that category are\nfunctors. A Hom-set in $\\Cat$ is a set of functors. For instance\n$\\cat{Cat(C, D)}$ is a set of functors between two categories $\\cat{C}$ and $\\cat{D}$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/7_cathomset.jpg}\n\\end{figure}\n\n\\noindent\nA functor category $\\cat{{[}C, D{]}}$ is also a set of functors between two\ncategories (plus natural transformations as morphisms). Its objects are\nthe same as the members of $\\cat{Cat(C, D)}$. Moreover, a functor category,\nbeing a category, must itself be an object of $\\Cat$ (it so\nhappens that the functor category between two small categories is itself\nsmall). We have a relationship between a Hom-set in a category and an\nobject in the same category. The situation is exactly like the\nexponential object that we've seen in the last section. Let's see how we\ncan construct the latter in $\\Cat$.\n\nAs you may remember, in order to construct an exponential, we need to\nfirst define a product. In $\\Cat$, this turns out to be relatively\neasy, because small categories are \\emph{sets} of objects, and we know\nhow to define Cartesian products of sets. So an object in a product\ncategory $\\cat{C\\times D}$ is just a pair of objects, $(c, d)$, one from $\\cat{C}$\nand one from $\\cat{D}$. Similarly, a morphism between two such pairs,\n$(c, d)$ and $(c', d')$, is a pair of morphisms, $(f, g)$, where\n$f \\Colon c \\to c'$ and $g \\Colon d \\to d'$. These pairs of morphisms\ncompose component-wise, and there is always an identity pair that is\njust a pair of identity morphisms. To make the long story short,\n$\\Cat$ is a full-blown Cartesian closed category in which there is\nan exponential object $\\cat{D^C}$ for any pair of categories.\nAnd by ``object'' in $\\Cat$ I mean a category, so\n$\\cat{D^C}$ is a category, which we can identify with the\nfunctor category between $\\cat{C}$ and $\\cat{D}$.\n\n\\section{2-Categories}\n\nWith that out of the way, let's have a closer look at $\\Cat$. By\ndefinition, any Hom-set in $\\Cat$ is a set of functors. But, as we\nhave seen, functors between two objects have a richer structure than\njust a set. They form a category, with natural transformations acting as\nmorphisms. Since functors are considered morphisms in $\\Cat$,\nnatural transformations are morphisms between morphisms.\n\nThis richer structure is an example of a $\\cat{2}$-category, a generalization of\na category where, besides objects and morphisms (which might be called\n$1$-morphisms in this context), there are also $2$-morphisms, which are\nmorphisms between morphisms.\n\nIn the case of $\\Cat$ seen as a $\\cat{2}$-category we have:\n\n\\begin{itemize}\n  \\tightlist\n  \\item\n        Objects: (Small) categories\n  \\item\n        1-morphisms: Functors between categories\n  \\item\n        2-morphisms: Natural transformations between functors.\n\\end{itemize}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/8_cat-2-cat.jpg}\n\\end{figure}\n\n\\noindent\nInstead of a Hom-set between two categories $\\cat{C}$ and $\\cat{D}$, we have a\nHom-category --- the functor category $\\cat{D^C}$. We have\nregular functor composition: a functor $F$ from $\\cat{D^C}$\ncomposes with a functor $G$ from $\\cat{E^D}$ to give $G \\circ F$ from\n$\\cat{E^C}$. But we also have composition inside each\nHom-category --- vertical composition of natural transformations, or\n2-morphisms, between functors.\n\nWith two kinds of composition in a $\\cat{2}$-category, the question arises: How\ndo they interact with each other?\n\nLet's pick two functors, or 1-morphisms, in $\\Cat$:\n\\begin{gather*}\n  F \\Colon \\cat{C} \\to \\cat{D} \\\\\n  G \\Colon \\cat{D} \\to \\cat{E}\n\\end{gather*}\nand their composition:\n\\[G \\circ F \\Colon \\cat{C} \\to \\cat{E}\\]\nSuppose we have two natural transformations, $\\alpha$ and $\\beta$, that act,\nrespectively, on functors $F$ and $G$:\n\\begin{gather*}\n  \\alpha \\Colon F \\to F' \\\\\n  \\beta \\Colon G \\to G'\n\\end{gather*}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/10_horizontal.jpg}\n\\end{figure}\n\n\\noindent\nNotice that we cannot apply vertical composition to this pair, because\nthe target of $\\alpha$ is different from the source of $\\beta$. In fact they are\nmembers of two different functor categories: $\\cat{D^C}$ and $\\cat{E^D}$.\nWe can, however, apply composition to the functors\n$F'$ and $G'$, because the target of $F'$ is the source of $G'$ --- it's the\ncategory $\\cat{D}$. What's the relation between the functors $G' \\circ F'$ and $G \\circ F$?\n\nHaving $\\alpha$ and $\\beta$ at our disposal, can we define a natural transformation\nfrom $G \\circ F$ to $G' \\circ F'$? Let me sketch the construction.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/9_horizontal.jpg}\n\\end{figure}\n\n\\noindent\nAs usual, we start with an object $a$ in $\\cat{C}$. Its image splits into\ntwo objects in $\\cat{D}$: $F a$ and $F'a$. There is also a\nmorphism, a component of $\\alpha$, connecting these two objects:\n\\[\\alpha_a \\Colon F a \\to F'a\\]\nWhen going from $\\cat{D}$ to $\\cat{E}$, these two objects split further into four\nobjects: $G (F a)$, $G'(F a)$, $G (F'a)$, $G'(F'a)$.\nWe also have four morphisms forming a square. Two of these morphisms are\nthe components of the natural transformation $\\beta$:\n\\begin{gather*}\n  \\beta_{F a} \\Colon G (F a) \\to G'(F a) \\\\\n  \\beta_{F'a} \\Colon G (F'a) \\to G'(F'a)\n\\end{gather*}\nThe other two are the images of $\\alpha_a$ under the two\nfunctors (functors map morphisms):\n\\begin{gather*}\n  G \\alpha_a \\Colon G (F a) \\to G (F'a) \\\\\n  G'\\alpha_a \\Colon G'(F a) \\to G'(F'a)\n\\end{gather*}\nThat's a lot of morphisms. Our goal is to find a morphism that goes from\n$G (F a)$ to $G'(F'a)$, a candidate for the\ncomponent of a natural transformation connecting the two functors $G \\circ F$\nand $G' \\circ F'$. In fact there's not one but two paths we can take from\n$G (F a)$ to $G'(F'a)$:\n\\begin{gather*}\n  G'\\alpha_a \\circ \\beta_{F a} \\\\\n  \\beta_{F'a} \\circ G \\alpha_a\n\\end{gather*}\nLuckily for us, they are equal, because the square we have formed turns\nout to be the naturality square for $\\beta$.\n\nWe have just defined a component of a natural transformation from $G \\circ F$\nto $G' \\circ F'$. The proof of naturality for this transformation is pretty\nstraightforward, provided you have enough patience.\n\nWe call this natural transformation the \\newterm{horizontal composition} of\n$\\alpha$ and $\\beta$:\n\\[\\beta \\circ \\alpha \\Colon G \\circ F \\to G' \\circ F'\\]\nAgain, following Mac Lane I use the small circle for horizontal\ncomposition, although you may also encounter star in its place.\n\nHere's a categorical rule of thumb: Every time you have composition, you\nshould look for a category. We have vertical composition of natural\ntransformations, and it's part of the functor category. But what about\nthe horizontal composition? What category does that live in?\n\nThe way to figure this out is to look at $\\Cat$ sideways. Look at\nnatural transformations not as arrows between functors but as arrows\nbetween categories. A natural transformation sits between two\ncategories, the ones that are connected by the functors it transforms.\nWe can think of it as connecting these two categories.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/sideways.jpg}\n\\end{figure}\n\n\\noindent\nLet's focus on two objects of $\\Cat$ --- categories $\\cat{C}$ and $\\cat{D}$. There\nis a set of natural transformations that go between functors that\nconnect $\\cat{C}$ to $\\cat{D}$. These natural transformations are our new arrows from $\\cat{C}$\nto $\\cat{D}$. By the same token, there are natural transformations going between\nfunctors that connect $\\cat{D}$ to $\\cat{E}$, which we can treat as new arrows going\nfrom $\\cat{D}$ to $\\cat{E}$. Horizontal composition is the composition of these arrows.\n\nWe also have an identity arrow going from $\\cat{C}$ to $\\cat{C}$. It's the identity\nnatural transformation that maps the identity functor on $\\cat{C}$ to itself.\nNotice that the identity for horizontal composition is also the identity\nfor vertical composition, but not vice versa.\n\nFinally, the two compositions satisfy the interchange law:\n\\[(\\beta' \\cdot \\alpha') \\circ (\\beta \\cdot \\alpha) = (\\beta' \\circ \\beta) \\cdot (\\alpha' \\circ \\alpha)\\]\nI will quote Saunders Mac Lane here: The reader may enjoy writing down\nthe evident diagrams needed to prove this fact.\n\nThere is one more piece of notation that might come in handy in the\nfuture. In this new sideways interpretation of $\\Cat$ there are\ntwo ways of getting from object to object: using a functor or using a\nnatural transformation. We can, however, re-interpret the functor arrow\nas a special kind of natural transformation: the identity natural\ntransformation acting on this functor. So you'll often see this\nnotation:\n\\[F \\circ \\alpha\\]\nwhere $F$ is a functor from $\\cat{D}$ to $\\cat{E}$, and $\\alpha$ is a natural transformation\nbetween two functors going from $\\cat{C}$ to $\\cat{D}$. Since you can't compose a\nfunctor with a natural transformation, this is interpreted as a\nhorizontal composition of the identity natural transformation\n$1_F$ after $\\alpha$.\n\nSimilarly:\n\\[\\alpha \\circ F\\]\nis a horizontal composition of $\\alpha$ after $1_F$.\n\n\\section{Conclusion}\n\nThis concludes the first part of the book. We've learned the basic\nvocabulary of category theory. You may think of objects and categories\nas nouns; and morphisms, functors, and natural transformations as verbs.\nMorphisms connect objects, functors connect categories, natural\ntransformations connect functors.\n\nBut we've also seen that, what appears as an action at one level of\nabstraction, becomes an object at the next level. A set of morphisms\nturns into a function object. As an object, it can be a source or a\ntarget of another morphism. That's the idea behind higher order\nfunctions.\n\nA functor maps objects to objects, so we can use it as a type\nconstructor, or a parametric type. A functor also maps morphisms, so it\nis a higher order function --- \\code{fmap}. There are some simple\nfunctors, like \\code{Const}, product, and coproduct, that can be used\nto generate a large variety of algebraic data types. Function types are\nalso functorial, both covariant and contravariant, and can be used to\nextend algebraic data types.\n\nFunctors may be looked upon as objects in the functor category. As such,\nthey become sources and targets of morphisms: natural transformations. A\nnatural transformation is a special type of polymorphic function.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Define a natural transformation from the \\code{Maybe} functor to the\n        list functor. Prove the naturality condition for it.\n  \\item\n        Define at least two different natural transformations between\n        \\code{Reader ()} and the list functor. How many different lists of\n        \\code{()} are there?\n  \\item\n        Continue the previous exercise with \\code{Reader Bool} and\n        \\code{Maybe}.\n  \\item\n        Show that horizontal composition of natural transformation satisfies\n        the naturality condition (hint: use components). It's a good exercise\n        in diagram chasing.\n  \\item\n        Write a short essay about how you may enjoy writing down the evident\n        diagrams needed to prove the interchange law.\n  \\item\n        Create a few test cases for the opposite naturality condition of\n        transformations between different \\code{Op} functors. Here's one\n        choice:\n\n        \\begin{snip}{haskell}\nop :: Op Bool Int\nop = Op (\\x -> x > 0)\n\\end{snip}\n        and\n\n        \\begin{snip}{haskell}\nf :: String -> Int\nf x = read x\n\\end{snip}\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet01.hs",
    "content": "x :: Integer"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet02.hs",
    "content": "f :: Bool -> Bool"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet03.hs",
    "content": "f :: Bool -> Bool\nf x = undefined"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet04.hs",
    "content": "f :: Bool -> Bool\nf = undefined"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet05.hs",
    "content": "fact n = product [1..n]"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet06.hs",
    "content": "absurd :: Void -> a"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet07.hs",
    "content": "f44 :: () -> Integer\nf44 () = 44"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet08.hs",
    "content": "fInt :: Integer -> ()\nfInt x = ()"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet09.hs",
    "content": "fInt :: Integer -> ()\nfInt _ = ()"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet10.hs",
    "content": "unit :: a -> ()\nunit _ = ()"
  },
  {
    "path": "src/content/1.2/code/haskell/snippet11.hs",
    "content": "data Bool = True | False"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet01.ml",
    "content": "module type Chapter2_DeclareVariable = sig\n  val x : int\nend\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet010.ml",
    "content": "let unit _ = ()\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet011.ml",
    "content": "type bool =\n  | false\n  | true\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet02.ml",
    "content": "module type Chapter2_DeclareFunction = sig\n  val f : bool -> bool\nend\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet03.ml",
    "content": "module Chapter2_Bottom : Chapter2_DeclareFunction = struct\n  let f (b : bool) : bool = failwith \"Not Implemented\"\nend\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet04.ml",
    "content": "module Chapter2_Bottom : Chapter2_DeclareFunction = struct\n  let f : bool -> bool = fun _ -> failwith \"Not implemented\"\nend\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet05.ml",
    "content": "let fact n = List.fold (List.range 1 n) ~init:1 ~f:( * )\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet06.ml",
    "content": "type void\n\nlet rec absurd (x : void) = absurd x\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet07.ml",
    "content": "let f44 () : int = 44\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet08.ml",
    "content": "let f_int (x : int) = ()\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet09.ml",
    "content": "let f_int (_ : int) = ()\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet10.ml",
    "content": "let unit _ = ()\n"
  },
  {
    "path": "src/content/1.2/code/ocaml/snippet11.ml",
    "content": "type bool =\n  | false\n  | true\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet01.re",
    "content": "module type Chapter2_DeclareVariable = {let x: int;};\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet010.re",
    "content": "let unit = _ => ();\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet011.re",
    "content": "type bool =\n  | false\n  | true;\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet02.re",
    "content": "module type Chapter2_DeclareFunction = {let f: bool => bool;};\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet03.re",
    "content": "module Chapter2_Bottom: Chapter2_DeclareFunction = {\n  let f = (b: bool): bool => failwith(\"Not Implemented\");\n};\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet04.re",
    "content": "module Chapter2_Bottom: Chapter2_DeclareFunction = {\n  let f: bool => bool = _ => failwith(\"Not implemented\");\n};"
  },
  {
    "path": "src/content/1.2/code/reason/snippet05.re",
    "content": "let fact = n => List.fold(List.range(1, n), ~init=1, ~f=( * ));\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet06.re",
    "content": "type void;\n\nlet rec absurd = (x: void) => absurd(x);\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet07.re",
    "content": "let f44 = (): int => 44;\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet08.re",
    "content": "let f_int = (x: int) => ();\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet09.re",
    "content": "let f_int = (_: int) => ();\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet10.re",
    "content": "let unit = _ => ();\n"
  },
  {
    "path": "src/content/1.2/code/reason/snippet11.re",
    "content": "type bool =\n  | false\n  | true;\n"
  },
  {
    "path": "src/content/1.2/code/scala/snippet01.scala",
    "content": "val x: BigInt"
  },
  {
    "path": "src/content/1.2/code/scala/snippet02.scala",
    "content": "val f: Boolean => Boolean"
  },
  {
    "path": "src/content/1.2/code/scala/snippet03.scala",
    "content": "val f: Boolean => Boolean = x => ???"
  },
  {
    "path": "src/content/1.2/code/scala/snippet04.scala",
    "content": "def f: Boolean => Boolean = ???"
  },
  {
    "path": "src/content/1.2/code/scala/snippet05.scala",
    "content": "val fact = (n: Int) => (1 to n).product"
  },
  {
    "path": "src/content/1.2/code/scala/snippet06.scala",
    "content": "def absurd[A]: Nothing => A"
  },
  {
    "path": "src/content/1.2/code/scala/snippet07.scala",
    "content": "val f44: Unit => BigInt = _ => 44"
  },
  {
    "path": "src/content/1.2/code/scala/snippet08.scala",
    "content": "val fInt: BigInt => Unit = x => ()"
  },
  {
    "path": "src/content/1.2/code/scala/snippet09.scala",
    "content": "val fInt: BigInt => Unit = _ => ()"
  },
  {
    "path": "src/content/1.2/code/scala/snippet10.scala",
    "content": "def unit[A]: A => Unit = _ => ()"
  },
  {
    "path": "src/content/1.2/code/scala/snippet11.scala",
    "content": "sealed trait Bool\ncase object True extends Bool\ncase object False extends Bool"
  },
  {
    "path": "src/content/1.2/types-and-functions.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{T}{he category of types and functions} plays an important role in\nprogramming, so let's talk about what types are and why we need them.\n\n\\section{Who Needs Types?}\n\nThere seems to be some controversy about the advantages of static vs.\ndynamic and strong vs. weak typing. Let me illustrate these choices with\na thought experiment. Imagine millions of monkeys at computer keyboards\nhappily hitting random keys, producing programs, compiling, and running\nthem.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/img_1329.jpg}\n\\end{figure}\n\n\\noindent\nWith machine language, any combination of bytes produced by monkeys\nwould be accepted and run. But with higher level languages, we do\nappreciate the fact that a compiler is able to detect lexical and\ngrammatical errors. Lots of monkeys will go without bananas, but the\nremaining programs will have a better chance of being useful. Type\nchecking provides yet another barrier against nonsensical programs.\nMoreover, whereas in a dynamically typed language, type mismatches would\nbe discovered at runtime, in strongly typed statically checked languages,\ntype mismatches are discovered at compile time, eliminating lots of\nincorrect programs before they have a chance to run.\n\nSo the question is, do we want to make monkeys happy, or do we want to\nproduce correct programs?\n\nThe usual goal in the typing monkeys thought experiment is the\nproduction of the complete works of Shakespeare. Having a spell checker\nand a grammar checker in the loop would drastically increase the odds.\nThe analog of a type checker would go even further by making sure that,\nonce Romeo is declared a human being, he doesn't sprout leaves or trap\nphotons in his powerful gravitational field.\n\n\\section{Types Are About Composability}\n\nCategory theory is about composing arrows. But not any two arrows can be\ncomposed. The target object of one arrow must be the same as the source\nobject of the next arrow. In programming we pass the results of\none function to another. The program will not work if the target\nfunction is not able to correctly interpret the data produced by the\nsource function. The two ends must fit for the composition to work. The\nstronger the type system of the language, the better this match can be\ndescribed and mechanically verified.\n\nThe only serious argument I hear against strong static type checking is\nthat it might eliminate some programs that are semantically correct. In\npractice, this happens extremely rarely and, in any case, every language\nprovides some kind of a backdoor to bypass the type system when that's\nreally necessary. Even Haskell has \\code{unsafeCoerce}. But such\ndevices should be used judiciously. Franz Kafka's character, Gregor\nSamsa, breaks the type system when he metamorphoses into a giant bug,\nand we all know how it ends.\n\nAnother argument I hear a lot is that dealing with types imposes too\nmuch burden on the programmer. I could sympathize with this sentiment\nafter having to write a few declarations of iterators in C++ myself,\nexcept that there is a technology called \\newterm{type inference} that lets\nthe compiler deduce most of the types from the context in which they are\nused. In C++, you can now declare a variable \\code{auto} and let the\ncompiler figure out its type.\n\nIn Haskell, except on rare occasions, type annotations are purely\noptional. Programmers tend to use them anyway, because they can tell a\nlot about the semantics of code, and they make compilation errors easier\nto understand. It's a common practice in Haskell to start a project by\ndesigning the types. \\sloppy{Later, type annotations drive the implementation\n  and become compiler-enforced comments.}\n\nStrong static typing is often used as an excuse for not testing the\ncode. You may sometimes hear Haskell programmers saying, ``If it\ncompiles, it must be correct.'' Of course, there is no guarantee that a\ntype-correct program is correct in the sense of producing the right\noutput. The result of this cavalier attitude is that in several studies\nHaskell didn't come as strongly ahead of the pack in code quality as one\nwould expect. It seems that, in the commercial setting, the pressure to\nfix bugs is applied only up to a certain quality level, which has\neverything to do with the economics of software development and the\ntolerance of the end user, and very little to do with the programming\nlanguage or methodology. A better criterion would be to measure how many\nprojects fall behind schedule or are delivered with drastically reduced\nfunctionality.\n\nAs for the argument that unit testing can replace strong typing,\nconsider the common refactoring practice in strongly typed languages:\nchanging the type of an argument of a particular function. In a strongly\ntyped language, it's enough to modify the declaration of that function\nand then fix all the build breaks. In a weakly typed language, the fact\nthat a function now expects different data cannot be propagated to call\nsites. Unit testing may catch some of the mismatches, but testing is\nalmost always a probabilistic rather than a deterministic process.\nTesting is a poor substitute for proof.\n\n\\section{What Are Types?}\n\nThe simplest intuition for types is that they are sets of values. The\ntype \\code{Bool} (remember, concrete types start with a capital letter\nin Haskell) is a two-element set of \\code{True} and \\code{False}.\nType \\code{Char} is a set of all Unicode characters like\n\\code{a} or \\code{ą}.\n\nSets can be finite or infinite. The type of \\code{String}, which is a\nsynonym for a list of \\code{Char}, is an example of an infinite set.\n\nWhen we declare \\code{x} to be an \\code{Integer}:\n\n\\src{snippet01}\nwe are saying that it's an element of the set of integers.\n\\code{Integer} in Haskell is an infinite set, and it can be used to do\narbitrary precision arithmetic. There is also a finite-set \\code{Int}\nthat corresponds to machine type, just like the C++ \\code{int}.\n\nThere are some subtleties that make this identification of types and\nsets tricky. There are problems with polymorphic functions that involve\ncircular definitions, and with the fact that you can't have a set of all\nsets; but as I promised, I won't be a stickler for math. The great thing\nis that there is a category of sets, which is called $\\Set$, and\nwe'll just work with it. In $\\Set$, objects are sets and morphisms\n(arrows) are functions.\n\n$\\Set$ is a very special category, because we can actually peek\ninside its objects and get a lot of intuitions from doing that. For\ninstance, we know that an empty set has no elements. We know that there\nare special one-element sets. We know that functions map elements of one\nset to elements of another set. They can map two elements to one, but\nnot one element to two. We know that an identity function maps each\nelement of a set to itself, and so on. The plan is to gradually forget\nall this information and instead express all those notions in purely\ncategorical terms, that is in terms of objects and arrows.\n\nIn the ideal world we would just say that Haskell types are sets and\nHaskell functions are mathematical functions between sets. There is just\none little problem: A mathematical function does not execute any code\n--- it just knows the answer. A Haskell function has to calculate the\nanswer. It's not a problem if the answer can be obtained in a finite\nnumber of steps --- however big that number might be. But there are some\ncalculations that involve recursion, and those might never terminate. We\ncan't just ban non-terminating functions from Haskell because\ndistinguishing between terminating and non-terminating functions is\nundecidable --- the famous halting problem. That's why computer\nscientists came up with a brilliant idea, or a major hack, depending on\nyour point of view, to extend every type by one more special value\ncalled the \\newterm{bottom} and denoted by \\code{\\_|\\_}, or\nUnicode $\\bot$. This ``value'' corresponds to a non-terminating computation.\nSo a function declared as:\n\n\\src{snippet02}\nmay return \\code{True}, \\code{False}, or \\code{\\_|\\_};\nthe latter meaning that it would never terminate.\n\nInterestingly, once you accept the bottom as part of the type system, it\nis convenient to treat every runtime error as a bottom, and even allow\nfunctions to return the bottom explicitly. The latter is usually done\nusing the expression \\code{undefined}, as in:\n\n\\src{snippet03}\nThis definition type checks because \\code{undefined} evaluates to\nbottom, which is a member of any type, including \\code{Bool}. You can\neven write:\n\n\\src{snippet04}\n(without the \\code{x}) because the bottom is also a member of the type\n\\code{Bool -> Bool}.\n\nFunctions that may return bottom are called partial, as opposed to total\nfunctions, which return valid results for every possible argument.\n\nBecause of the bottom, you'll see the category of Haskell types and\nfunctions referred to as $\\Hask$ rather than $\\Set$. From\nthe theoretical point of view, this is the source of never-ending\ncomplications, so at this point I will use my butcher's knife and\nterminate this line of reasoning. From the pragmatic point of view, it's\nokay to ignore non-terminating functions and bottoms, and treat\n$\\Hask$ as bona fide $\\Set$.\\footnote{Nils Anders Danielsson,\n  John Hughes, Patrik Jansson, Jeremy Gibbons, \\href{http://www.cs.ox.ac.uk/jeremy.gibbons/publications/fast+loose.pdf}{\n    Fast and Loose Reasoning is Morally Correct}. This paper provides justification for ignoring bottoms in most contexts.}\n\n\\section{Why Do We Need a Mathematical Model?}\n\nAs a programmer you are intimately familiar with the syntax and grammar\nof your programming language. These aspects of the language are usually\ndescribed using formal notation at the very beginning of the language\nspec. But the meaning, or semantics, of the language is much harder to\ndescribe; it takes many more pages, is rarely formal enough, and almost\nnever complete. Hence the never ending discussions among language\nlawyers, and a whole cottage industry of books dedicated to the exegesis\nof the finer points of language standards.\n\nThere are formal tools for describing the semantics of a language but,\nbecause of their complexity, they are mostly used with simplified\nacademic languages, not real-life programming behemoths. One such tool\ncalled \\newterm{operational semantics} describes the mechanics of program\nexecution. It defines a formalized idealized interpreter. The semantics\nof industrial languages, such as C++, is usually described using\ninformal operational reasoning, often in terms of an ``abstract\nmachine.''\n\nThe problem is that it's very hard to prove things about programs using\noperational semantics. To show a property of a program you essentially\nhave to ``run it'' through the idealized interpreter.\n\nIt doesn't matter that programmers never perform formal proofs of\ncorrectness. We always ``think'' that we write correct programs. Nobody\nsits at the keyboard saying, ``Oh, I'll just throw a few lines of code\nand see what happens.'' We think that the code we write will perform\ncertain actions that will produce desired results. We are usually quite\nsurprised when it doesn't. That means we do reason about programs we\nwrite, and we usually do it by running an interpreter in our heads. It's\njust really hard to keep track of all the variables. Computers are good\nat running programs --- humans are not! If we were, we wouldn't need\ncomputers.\n\nBut there is an alternative. It's called \\newterm{denotational semantics}\nand it's based on math. In denotational semantics every programming\nconstruct is given its mathematical interpretation. With that, if you\nwant to prove a property of a program, you just prove a mathematical\ntheorem. You might think that theorem proving is hard, but the fact is\nthat we humans have been building up mathematical methods for thousands\nof years, so there is a wealth of accumulated knowledge to tap into.\nAlso, as compared to the kind of theorems that professional\nmathematicians prove, the problems that we encounter in programming are\nusually quite simple, if not trivial.\n\nConsider the definition of a factorial function in Haskell, which is a\nlanguage quite amenable to denotational semantics:\n\n\\src{snippet05}\nThe expression \\code{{[}1..n{]}} is a list of integers from \\code{1} to \\code{n}.\nThe function \\code{product} multiplies all elements of a list. That's\njust like a definition of factorial taken from a math text. Compare this\nwith C:\n\n\\begin{snip}{c}\nint fact(int n) {\n    int i;\n    int result = 1;\n    for (i = 2; i <= n; ++i)\n        result *= i;\n    return result;\n}\n\\end{snip}\nNeed I say more?\n\nOkay, I'll be the first to admit that this was a cheap shot! A factorial\nfunction has an obvious mathematical denotation. An astute reader might\nask: What's the mathematical model for reading a character from the\nkeyboard or sending a packet across the network? For the longest time\nthat would have been an awkward question leading to a rather convoluted\nexplanation. It seemed like denotational semantics wasn't the best fit\nfor a considerable number of important tasks that were essential for\nwriting useful programs, and which could be easily tackled by\noperational semantics. The breakthrough came from category theory.\nEugenio Moggi discovered that computational effect can be mapped to\nmonads. This turned out to be an important observation that not only\ngave denotational semantics a new lease on life and made pure functional\nprograms more usable, but also shed new light on traditional\nprogramming. I'll talk about monads later, when we develop more\ncategorical tools.\n\nOne of the important advantages of having a mathematical model for\nprogramming is that it's possible to perform formal proofs of\ncorrectness of software. This might not seem so important when you're\nwriting consumer software, but there are areas of programming where the\nprice of failure may be exorbitant, or where human life is at stake. But\neven when writing web applications for the health system, you may\nappreciate the thought that functions and algorithms from the Haskell\nstandard library come with proofs of correctness.\n\n\\section{Pure and Dirty Functions}\n\nThe things we call functions in C++ or any other imperative language,\nare not the same things mathematicians call functions. A mathematical\nfunction is just a mapping of values to values.\n\nWe can implement a mathematical function in a programming language: Such\na function, given an input value will calculate the output value. A\nfunction to produce a square of a number will probably multiply the\ninput value by itself. It will do it every time it's called, and it's\nguaranteed to produce the same output every time it's called with the\nsame input. The square of a number doesn't change with the phases of the\nMoon.\n\nAlso, calculating the square of a number should not have a side effect\nof dispensing a tasty treat for your dog. A ``function'' that does that\ncannot be easily modelled as a mathematical function.\n\nIn programming languages, functions that always produce the same result\ngiven the same input and have no side effects are called \\newterm{pure\n  functions}. In a pure functional language like Haskell all functions are\npure. Because of that, it's easier to give these languages denotational\nsemantics and model them using category theory. As for other languages,\nit's always possible to restrict yourself to a pure subset, or reason\nabout side effects separately. Later we'll see how monads let us model\nall kinds of effects using only pure functions. So we really don't lose\nanything by restricting ourselves to mathematical functions.\n\n\\section{Examples of Types}\n\nOnce you realize that types are sets, you can think of some rather\nexotic types. For instance, what's the type corresponding to an empty\nset? No, it's not C++ \\code{void}, although this type \\emph{is} called\n\\code{Void} in Haskell. It's a type that's not inhabited by any\nvalues. You can define a function that takes \\code{Void}, but you can\nnever call it. To call it, you would have to provide a value of the type\n\\code{Void}, and there just aren't any. As for what this function can\nreturn, there are no restrictions whatsoever. It can return any type\n(although it never will, because it can't be called). In other words\nit's a function that's polymorphic in the return type. Haskellers have a\nname for it:\n\n\\src{snippet06}\n(Remember, \\code{a} is a type variable that can stand for any type.)\nThe name is not coincidental. There is deeper interpretation of types\nand functions in terms of logic called the Curry-Howard isomorphism. The\ntype \\code{Void} represents falsity, and the type of the function\n\\code{absurd} corresponds to the statement that from falsity follows\nanything, as in the Latin adage ``ex falso sequitur quodlibet.''\n\nNext is the type that corresponds to a singleton set. It's a type that\nhas only one possible value. This value just ``is.'' You might not\nimmediately recognize it as such, but that is the C++ \\code{void}.\nThink of functions from and to this type. A function from \\code{void}\ncan always be called. If it's a pure function, it will always return the\nsame result. Here's an example of such a function:\n\n\\begin{snip}{c}\nint f44() { return 44; }\n\\end{snip}\nYou might think of this function as taking ``nothing'', but as we've\njust seen, a function that takes ``nothing'' can never be called because\nthere is no value representing ``nothing.'' So what does this function\ntake? Conceptually, it takes a dummy value of which there is only one\ninstance ever, so we don't have to mention it explicitly. In Haskell,\nhowever, there is a symbol for this value: an empty pair of parentheses,\n\\code{()}. So, by a funny coincidence (or is it a coincidence?), the\ncall to a function of void looks the same in C++ and in Haskell. Also,\nbecause of the Haskell's love of terseness, the same symbol \\code{()}\nis used for the type, the constructor, and the only value corresponding\nto a singleton set. So here's this function in Haskell:\n\n\\src{snippet07}\nThe first line declares that \\code{f44} takes the type \\code{()},\npronounced ``unit,'' into the type \\code{Integer}. The second line\ndefines \\code{f44} by pattern matching the only constructor for unit,\nnamely \\code{()}, and producing the number 44. You call this function\nby providing the unit value \\code{()}:\n\n\\begin{snip}{c}\nf44 ()\n\\end{snip}\nNotice that every function of unit is equivalent to picking a single\nelement from the target type (here, picking the \\code{Integer} 44). In\nfact you could think of \\code{f44} as a different representation for\nthe number 44. This is an example of how we can replace explicit mention\nof elements of a set by talking about functions (arrows) instead.\nFunctions from unit to any type $A$ are in one-to-one correspondence with\nthe elements of that set $A$.\n\nWhat about functions with the \\code{void} return type, or, in Haskell,\nwith the unit return type? In C++ such functions are used for side\neffects, but we know that these are not real functions in the\nmathematical sense of the word. A pure function that returns unit does\nnothing: it discards its argument.\n\nMathematically, a function from a set $A$ to a singleton set maps every\nelement of $A$ to the single element of that singleton set. For every $A$\nthere is exactly one such function. Here's this function for\n\\code{Integer}:\n\n\\src{snippet08}\nYou give it any integer, and it gives you back a unit. In the spirit of\nterseness, Haskell lets you use the wildcard pattern, the underscore,\nfor an argument that is discarded. This way you don't have to invent a\nname for it. So the above can be rewritten as:\n\n\\src{snippet09}\nNotice that the implementation of this function not only doesn't depend\non the value passed to it, but it doesn't even depend on the type of the\nargument.\n\nFunctions that can be implemented with the same formula for any type are\ncalled parametrically polymorphic. You can implement a whole family of\nsuch functions with one equation using a type parameter instead of a\nconcrete type. What should we call a polymorphic function from any type\nto unit type? Of course we'll call it \\code{unit}:\n\n\\src{snippet10}\nIn C++ you would write this function as:\n\n\\begin{snip}{cpp}\ntemplate<typename T>\nvoid unit(T) {}\n\\end{snip}\nNext in the typology of types is a two-element set. In C++ it's called\n\\code{bool} and in Haskell, predictably, \\code{Bool}. The difference\nis that in C++ \\code{bool} is a built-in type, whereas in Haskell it\ncan be defined as follows:\n\n\\src{snippet11}\n(The way to read this definition is that \\code{Bool} is either\n\\code{True} or \\code{False}.) In principle, one should also be able\nto define a Boolean type in C++ as an enumeration:\n\n\\begin{snip}{cpp}\nenum bool {\n    true,\n    false\n};\n\\end{snip}\nbut C++ \\code{enum} is secretly an integer. The C++11\n``\\code{enum class}'' could have been used instead, but then you\nwould have to qualify its values with the class name, as in\n\\code{bool::true} and \\code{bool::false}, not to mention having to\ninclude the appropriate header in every file that uses it.\n\nPure functions from \\code{Bool} just pick two values from the target\ntype, one corresponding to \\code{True} and another to \\code{False}.\n\nFunctions to \\code{Bool} are called \\newterm{predicates}. For instance,\nthe Haskell library \\code{Data.Char} is full of predicates like\n\\code{isAlpha} or \\code{isDigit}. In C++ there is a similar library\n\\code{} that defines, among others, \\code{isalpha} and\n\\code{isdigit}, but these return an \\code{int} rather than a\nBoolean. The actual predicates are defined in \\code{std::ctype} and\nhave the form \\code{ctype::is(alpha, c)}, \\code{ctype::is(digit, c)}, etc.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Define a higher-order function (or a function object) \\code{memoize}\n        in your favorite language. This function takes a pure function\n        \\code{f} as an argument and returns a function that behaves almost\n        exactly like \\code{f}, except that it only calls the original\n        function once for every argument, stores the result internally, and\n        subsequently returns this stored result every time it's called with\n        the same argument. You can tell the memoized function from the\n        original by watching its performance. For instance, try to memoize a\n        function that takes a long time to evaluate. You'll have to wait for\n        the result the first time you call it, but on subsequent calls, with\n        the same argument, you should get the result immediately.\n  \\item\n        Try to memoize a function from your standard library that you normally\n        use to produce random numbers. Does it work?\n  \\item\n        Most random number generators can be initialized with a seed.\n        Implement a function that takes a seed, calls the random number\n        generator with that seed, and returns the result. Memoize that\n        function. Does it work?\n  \\item\n        Which of these C++ functions are pure? Try to memoize them and observe\n        what happens when you call them multiple times: memoized and not.\n\n        \\begin{enumerate}\n          \\tightlist\n          \\item\n                The factorial function from the example in the text.\n          \\item\n                \\begin{minted}{cpp}\nstd::getchar()\n\\end{minted}\n          \\item\n                \\begin{minted}{cpp}\nbool f() {\n    std::cout << \"Hello!\" << std::endl;\n    return true;\n}\n\\end{minted}\n          \\item\n                \\begin{minted}{cpp}\nint f(int x) {\n    static int y = 0;\n    y += x;\n    return y;\n}\n\\end{minted}\n        \\end{enumerate}\n  \\item\n        How many different functions are there from \\code{Bool} to\n        \\code{Bool}? Can you implement them all?\n  \\item\n        Draw a picture of a category whose only objects are the types\n        \\code{Void}, \\code{()} (unit), and \\code{Bool}; with arrows\n        corresponding to all possible functions between these types. Label the\n        arrows with the names of the functions.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.3/categories-great-and-small.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{Y}{ou can get} real appreciation for categories by studying a variety of\nexamples. Categories come in all shapes and sizes and often pop up in\nunexpected places. We'll start with something really simple.\n\n\\section{No Objects}\n\nThe most trivial category is one with zero objects and, consequently,\nzero morphisms. It's a very sad category by itself, but it may be\nimportant in the context of other categories, for instance, in the\ncategory of all categories (yes, there is one). If you think that an\nempty set makes sense, then why not an empty category?\n\n\\section{Simple Graphs}\n\nYou can build categories just by connecting objects with arrows. You can\nimagine starting with any directed graph and making it into a category\nby simply adding more arrows. First, add an identity arrow at each node.\nThen, for any two arrows such that the end of one coincides with the\nbeginning of the other (in other words, any two \\newterm{composable}\narrows), add a new arrow to serve as their composition. Every time you\nadd a new arrow, you have to also consider its composition with any\nother arrow (except for the identity arrows) and itself. You usually end\nup with infinitely many arrows, but that's okay.\n\nAnother way of looking at this process is that you're creating a\ncategory, which has an object for every node in the graph, and all\npossible \\newterm{chains} of composable graph edges as morphisms. (You may\neven consider identity morphisms as special cases of chains of length\nzero.)\n\nSuch a category is called a \\newterm{free category} generated by a given\ngraph. It's an example of a free construction, a process of completing a\ngiven structure by extending it with a minimum number of items to\nsatisfy its laws (here, the laws of a category). We'll see more examples\nof it in the future.\n\n\\section{Orders}\n\nAnd now for something completely different! A category where a morphism\nis a relation between objects: the relation of being less than or equal.\nLet's check if it indeed is a category. Do we have identity morphisms?\nEvery object is less than or equal to itself: check! Do we have\ncomposition? If $a \\leqslant b$ and $b \\leqslant c$ then $a \\leqslant c$: check! Is composition associative? Check! A set with a\nrelation like this is called a \\newterm{preorder}, so a preorder is indeed\na category.\n\nYou can also have a stronger relation, that satisfies an additional\ncondition that, if $a \\leqslant b$ and $b \\leqslant a$ then $a$ must be\nthe same as $b$. That's called a \\newterm{partial order}.\n\nFinally, you can impose the condition that any two objects are in a\nrelation with each other, one way or another; and that gives you a\n\\newterm{linear order} or \\newterm{total order}.\n\nLet's characterize these ordered sets as categories. A preorder is a\ncategory where there is at most one morphism going from any object $a$ to\nany object $b$. Another name for such a category is ``thin.'' A preorder\nis a thin category.\n\nA set of morphisms from object $a$ to object $b$ in a category $\\cat{C}$ is called a\n\\newterm{hom-set} and is written as $\\cat{C}(a, b)$ (or, sometimes,\n$\\mathbf{Hom}_{\\cat{C}}(a, b)$). So every hom-set in a preorder is either\nempty or a singleton. That includes the hom-set $\\cat{C}(a, a)$, the set of\nmorphisms from $a$ to $a$, which must be a singleton, containing only the\nidentity, in any preorder. You may, however, have cycles in a preorder.\nCycles are forbidden in a partial order.\n\nIt's very important to be able to recognize preorders, partial orders,\nand total orders because of sorting. Sorting algorithms, such as\nquicksort, bubble sort, merge sort, etc., can only work correctly on\ntotal orders. Partial orders can be sorted using topological sort.\n\n\\section{Monoid as Set}\n\nMonoid is an embarrassingly simple but amazingly powerful concept. It's\nthe concept behind basic arithmetics: Both addition and multiplication\nform a monoid. Monoids are ubiquitous in programming. They show up as\nstrings, lists, foldable data structures, futures in concurrent\nprogramming, events in functional reactive programming, and so on.\n\nTraditionally, a monoid is defined as a set with a binary operation. All\nthat's required from this operation is that it's associative, and that\nthere is one special element that behaves like a unit with respect to\nit.\n\nFor instance, natural numbers with zero form a monoid under addition.\nAssociativity means that:\n\\[(a + b) + c = a + (b + c)\\]\n(In other words, we can skip parentheses when adding numbers.)\n\nThe neutral element is zero, because:\n\\[0 + a = a\\]\nand\n\\[a + 0 = a\\]\nThe second equation is redundant, because addition is commutative $(a + b\n  = b + a)$, but commutativity is not part of the definition of a monoid.\nFor instance, string concatenation is not commutative and yet it forms a\nmonoid. The neutral element for string concatenation, by the way, is an\nempty string, which can be attached to either side of a string without\nchanging it.\n\nIn Haskell we can define a type class for monoids --- a type for which\nthere is a neutral element called \\code{mempty} and a binary operation\ncalled \\code{mappend}:\n\n\\src{snippet01}\nThe type signature for a two-argument function,\n\\code{m -> m -> m}, might look strange at first,\nbut it will make perfect sense after we talk about currying. You may\ninterpret a signature with multiple arrows in two basic ways: as a\nfunction of multiple arguments, with the rightmost type being the return\ntype; or as a function of one argument (the leftmost one), returning a\nfunction. The latter interpretation may be emphasized by adding\nparentheses (which are redundant, because the arrow is\nright-associative), as in: \\code{m -> (m -> m)}.\nWe'll come back to this interpretation in a moment.\n\nNotice that, in Haskell, there is no way to express the monoidal\nproperties of \\code{mempty} and \\code{mappend} (i.e., the fact that\n\\code{mempty} is neutral and that \\code{mappend} is associative).\nIt's the responsibility of the programmer to make sure they are\nsatisfied.\n\nHaskell classes are not as intrusive as C++ classes. When you're\ndefining a new type, you don't have to specify its class up front. You\nare free to procrastinate and declare a given type to be an instance of\nsome class much later. As an example, let's declare \\code{String} to\nbe a monoid by providing the implementation of \\code{mempty} and\n\\code{mappend} (this is, in fact, done for you in the standard\nPrelude):\n\n\\src{snippet02}\nHere, we have reused the list concatenation operator \\code{(++)},\nbecause a \\code{String} is just a list of characters.\n\nA word about Haskell syntax: Any infix operator can be turned into a\ntwo-argument function by surrounding it with parentheses. Given two\nstrings, you can concatenate them by inserting \\code{++} between them:\n\n\\begin{snip}{haskell}\n\"Hello \" ++ \"world!\"\n\\end{snip}\nor by passing them as two arguments to the parenthesized \\code{(++)}:\n\n\\begin{snip}{haskell}\n(++) \"Hello \" \"world!\"\n\\end{snip}\nNotice that arguments to a function are not separated by commas or\nsurrounded by parentheses. (This is probably the hardest thing to get\nused to when learning Haskell.)\n\nIt's worth emphasizing that Haskell lets you express equality of\nfunctions, as in:\n\n\\begin{snip}{haskell}\nmappend = (++)\n\\end{snip}\nConceptually, this is different than expressing the equality of values\nproduced by functions, as in:\n\n\\begin{snip}{haskell}\nmappend s1 s2 = (++) s1 s2\n\\end{snip}\nThe former translates into equality of morphisms in the category\n$\\Hask$ (or $\\Set$, if we ignore bottoms, which is the name\nfor never-ending calculations). Such equations are not only more\nsuccinct, but can often be generalized to other categories. The latter\nis called \\newterm{extensional} equality, and states the fact that for any\ntwo input strings, the outputs of \\code{mappend} and \\code{(++)} are\nthe same. Since the values of arguments are sometimes called\n\\newterm{points} (as in: the value of $f$ at point $x$), this is called\npoint-wise equality. Function equality without specifying the arguments\nis described as \\newterm{point-free}. (Incidentally, point-free equations\noften involve composition of functions, which is symbolized by a point,\nso this might be a little confusing to the beginner.)\n\nThe closest one can get to declaring a monoid in C++ would be to use the\nC++20 standard's concept feature.\n\n\\begin{snip}{cpp}\ntemplate<typename T>\nstruct mempty;\n\ntemplate<typename T>\nT mappend(T, T) = delete;\n\ntemplate<typename M>\nconcept Monoid = requires (M m) {\n    { mempty<M>::value() } -> std::same_as<M>;\n    { mappend(m, m) } -> std::same_as<M>;\n};\n\\end{snip}\nThe first definition is a structure meant to hold the neutral element for each\nspecialization.\n\nThe keyword \\code{delete} means that there is no default value\ndefined: It will have to be specified on a case-by-case basis.\nSimilarly, there is no default for \\code{mappend}.\n\nThe concept \\code{Monoid} tests whether there exist appropriate definitions of\n\\code{mempty} and \\code{mappend} for a given type \\code{M}.\n\nAn instantiation of the Monoid concept can be accomplished by providing\nappropriate specializations and overloads:\n\n\\begin{snip}{cpp}\ntemplate<>\nstruct mempty<std::string> {\n    static std::string value() { return \"\"; }\n};\n\ntemplate<>\nstd::string mappend(std::string s1, std::string s2) {\n    return s1 + s2;\n}\n\\end{snip}\n\n\\section{Monoid as Category}\n\nThat was the ``familiar'' definition of the monoid in terms of elements\nof a set. But as you know, in category theory we try to get away from\nsets and their elements, and instead talk about objects and morphisms.\nSo let's change our perspective a bit and think of the application of\nthe binary operator as ``moving'' or ``shifting'' things around the set.\n\nFor instance, there is the operation of adding 5 to every natural\nnumber. It maps 0 to 5, 1 to 6, 2 to 7, and so on. That's a function\ndefined on the set of natural numbers. That's good: we have a function\nand a set. In general, for any number n there is a function of adding $n$\n--- the ``adder'' of $n$.\n\nHow do adders compose? The composition of the function that adds 5 with\nthe function that adds 7 is a function that adds 12. So the composition\nof adders can be made equivalent to the rules of addition. That's good\ntoo: we can replace addition with function composition.\n\nBut wait, there's more: There is also the adder for the neutral element,\nzero. Adding zero doesn't move things around, so it's the identity\nfunction in the set of natural numbers.\n\nInstead of giving you the traditional rules of addition, I could as well\ngive you the rules of composing adders, without any loss of information.\nNotice that the composition of adders is associative, because the\ncomposition of functions is associative; and we have the zero adder\ncorresponding to the identity function.\n\nAn astute reader might have noticed that the mapping from integers to\nadders follows from the second interpretation of the type signature of\n\\code{mappend} as \\code{m -> (m -> m)}. It\ntells us that \\code{mappend} maps an element of a monoid set to a\nfunction acting on that set.\n\nNow I want you to forget that you are dealing with the set of natural\nnumbers and just think of it as a single object, a blob with a bunch of\nmorphisms --- the adders. A monoid is a single object category. In fact\nthe name monoid comes from Greek \\emph{mono}, which means single. Every\nmonoid can be described as a single object category with a set of\nmorphisms that follow appropriate rules of composition.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/monoid.jpg}\n\\end{figure}\n\n\\noindent\nString concatenation is an interesting case, because we have a choice of\ndefining right appenders and left appenders (or \\emph{prependers}, if\nyou will). The composition tables of the two models are a mirror reverse\nof each other. You can easily convince yourself that appending ``bar''\nafter ``foo'' corresponds to prepending ``foo'' after prepending\n``bar''.\n\nYou might ask the question whether every categorical monoid --- a\none-object category --- defines a unique set-with-binary-operator\nmonoid. It turns out that we can always extract a set from a\nsingle-object category. This set is the set of morphisms --- the adders\nin our example. In other words, we have the hom-set $\\cat{M}(m, m)$ of the\nsingle object $m$ in the category $\\cat{M}$. We can easily define a binary\noperator in this set: The monoidal product of two set-elements is the\nelement corresponding to the composition of the corresponding morphisms.\nIf you give me two elements of $\\cat{M}(m, m)$ corresponding to $f$ and\n$g$, their product will correspond to the composition\n$f \\circ g$. The composition always exists, because the source and the\ntarget for these morphisms are the same object. And it's associative by\nthe rules of category. The identity morphism is the neutral element of\nthis product. So we can always recover a set monoid from a category\nmonoid. For all intents and purposes they are one and the same.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/monoidhomset.jpg}\n  \\caption{Monoid hom-set seen as morphisms and as points in a set.}\n\\end{figure}\n\n\\noindent\nThere is just one little nit for mathematicians to pick: morphisms don't\nhave to form a set. In the world of categories there are things larger\nthan sets. A category in which morphisms between any two objects form a\nset is called locally small. As promised, I will be mostly ignoring such\nsubtleties, but I thought I should mention them for the record.\n\nA lot of interesting phenomena in category theory have their root in the\nfact that elements of a hom-set can be seen both as morphisms, which\nfollow the rules of composition, and as points in a set. Here,\ncomposition of morphisms in $\\cat{M}$ translates into monoidal product in the\nset $\\cat{M}(m, m)$.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Generate a free category from:\n\n        \\begin{enumerate}\n          \\tightlist\n          \\item\n                A graph with one node and no edges\n          \\item\n                A graph with one node and one (directed) edge (hint: this edge can\n                be composed with itself)\n          \\item\n                A graph with two nodes and a single arrow between them\n          \\item\n                A graph with a single node and 26 arrows marked with the letters of\n                the alphabet: a, b, c \\ldots{} z.\n        \\end{enumerate}\n  \\item\n        What kind of order is this?\n\n        \\begin{enumerate}\n          \\tightlist\n          \\item\n                A set of sets with the inclusion relation: $A$ is included in $B$ if\n                every element of $A$ is also an element of $B$.\n          \\item\n                C++ types with the following subtyping relation: \\code{T1} is a subtype of\n                \\code{T2} if a pointer to \\code{T1} can be passed to a function that expects a\n                pointer to \\code{T2} without triggering a compilation error.\n        \\end{enumerate}\n  \\item\n        Considering that \\code{Bool} is a set of two values \\code{True} and \\code{False}, show that\n        it forms two (set-theoretical) monoids with respect to, respectively,\n        operator \\code{\\&\\&} (AND) and \\code{||} (OR).\n  \\item\n        Represent the \\code{Bool} monoid with the AND operator as a category: List\n        the morphisms and their rules of composition.\n  \\item\n        Represent addition modulo 3 as a monoid category.\n\\end{enumerate}"
  },
  {
    "path": "src/content/1.3/code/haskell/snippet01.hs",
    "content": "class Monoid m where\n    mempty  :: m\n    mappend :: m -> m -> m"
  },
  {
    "path": "src/content/1.3/code/haskell/snippet02.hs",
    "content": "instance Monoid String where\n    mempty = \"\"\n    mappend = (++)"
  },
  {
    "path": "src/content/1.3/code/ocaml/snippet01.ml",
    "content": "module type Monoid = sig\n  type a\n\n  val mempty : a\n  val mappend : a -> a -> a\nend\n"
  },
  {
    "path": "src/content/1.3/code/ocaml/snippet02.ml",
    "content": "module StringMonoid : Monoid = struct\n  type a = string\n\n  let mempty = \"\"\n  let mappend = ( ^ )\nend\n"
  },
  {
    "path": "src/content/1.3/code/reason/snippet01.re",
    "content": "module type Monoid = {\n  type a;\n  \n  let mempty: a;\n  let mappend: (a, a) => a;\n};\n"
  },
  {
    "path": "src/content/1.3/code/reason/snippet02.re",
    "content": "module StringMonoid: Monoid = {\n  type a = string;\n  \n  let mempty = \"\";\n  let mappend = (++);\n};\n"
  },
  {
    "path": "src/content/1.3/code/scala/snippet01.scala",
    "content": "trait Monoid[M] {\n  def combine(m1: M, m2: M): M\n  def empty: M\n}"
  },
  {
    "path": "src/content/1.3/code/scala/snippet02.scala",
    "content": "object Monoid {\n  implicit val stringMonoid: Monoid[String] = new Monoid[String] {\n    def combine(m1: String, m2: String): String = m1 + m2\n    def empty: String = \"\"\n  }\n}"
  },
  {
    "path": "src/content/1.4/code/haskell/snippet01.hs",
    "content": "type Writer a = (a, String)"
  },
  {
    "path": "src/content/1.4/code/haskell/snippet02.hs",
    "content": "a -> Writer b"
  },
  {
    "path": "src/content/1.4/code/haskell/snippet03.hs",
    "content": "(>=>) :: (a -> Writer b) -> (b -> Writer c) -> (a -> Writer c)"
  },
  {
    "path": "src/content/1.4/code/haskell/snippet04.hs",
    "content": "m1 >=> m2 = \\x ->\n    let (y, s1) = m1 x\n        (z, s2) = m2 y\n    in (z, s1 ++ s2)"
  },
  {
    "path": "src/content/1.4/code/haskell/snippet05.hs",
    "content": "return :: a -> Writer a\nreturn x = (x, \"\")"
  },
  {
    "path": "src/content/1.4/code/haskell/snippet06.hs",
    "content": "upCase :: String -> Writer String\nupCase s = (map toUpper s, \"upCase \")\n\ntoWords :: String -> Writer [String]\ntoWords s = (words s, \"toWords \")"
  },
  {
    "path": "src/content/1.4/code/haskell/snippet07.hs",
    "content": "process :: String -> Writer [String]\nprocess = upCase >=> toWords"
  },
  {
    "path": "src/content/1.4/code/ocaml/snippet01.ml",
    "content": "type 'a writer = 'a * string\n"
  },
  {
    "path": "src/content/1.4/code/ocaml/snippet02.ml",
    "content": "'a -> 'b writer\n"
  },
  {
    "path": "src/content/1.4/code/ocaml/snippet03.ml",
    "content": "module type Kleisli = sig\n  type a\n  type b\n  type c\n\n  val ( >=> ) : (a -> b writer) -> (b -> c writer) -> a -> c writer\nend\n"
  },
  {
    "path": "src/content/1.4/code/ocaml/snippet04.ml",
    "content": "let pure x = x, \"\"\n"
  },
  {
    "path": "src/content/1.4/code/ocaml/snippet05.ml",
    "content": "let up_case : string -> string writer =\n fun s -> String.uppercase s, \"up_case \"\n;;\n"
  },
  {
    "path": "src/content/1.4/code/ocaml/snippet06.ml",
    "content": "let to_words : string -> string list writer =\n fun s -> String.split s ~on:' ', \"to_words \"\n;;\n"
  },
  {
    "path": "src/content/1.4/code/ocaml/snippet07.ml",
    "content": "module KleisiExample\n    (K : Kleisli\n           with type a = string\n            and type b = string\n            and type c = string list) =\nstruct\n  let up_case_and_to_words : string -> string list writer =\n    K.( >=> ) up_case to_words\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.4/code/reason/snippet01.re",
    "content": "type writer('a) = ('a, string);\n"
  },
  {
    "path": "src/content/1.4/code/reason/snippet02.re",
    "content": "'a => writer('b)"
  },
  {
    "path": "src/content/1.4/code/reason/snippet03.re",
    "content": "module type Kleisli = {\n  type a;\n  type b;\n  type c;\n  \n  let (>=>): (a => writer(b), b => writer(c), a) => writer(c);\n};\n"
  },
  {
    "path": "src/content/1.4/code/reason/snippet04.re",
    "content": "let pure = x => (x, \"\");\n"
  },
  {
    "path": "src/content/1.4/code/reason/snippet05.re",
    "content": "let up_case: string => writer(string) =\n  s => (String.uppercase(s), \"up_case \");"
  },
  {
    "path": "src/content/1.4/code/reason/snippet06.re",
    "content": "let to_words: string => writer(list(string)) = (\n  s => (String.split(s, ~on=' '), \"to_words \"):\n    string => writer(list(string))\n);\n"
  },
  {
    "path": "src/content/1.4/code/reason/snippet07.re",
    "content": "module KleisiExample =\n       (K: Kleisli\n          with type a = string\n          and type b = string\n          and type c = list(string)\n       ) => {\n  let up_case_and_to_words: string => writer(list(string)) = (\n    K.(>=>)(up_case, to_words): string => writer(list(string))\n  );\n};\n"
  },
  {
    "path": "src/content/1.4/code/scala/snippet01.scala",
    "content": "type Writer[A] = (A, String)"
  },
  {
    "path": "src/content/1.4/code/scala/snippet02.scala",
    "content": "A => Writer[B]"
  },
  {
    "path": "src/content/1.4/code/scala/snippet03.scala",
    "content": "def >=>[A, B, C](m1: A => Writer[B], m2: B => Writer[C]): A => Writer[C]"
  },
  {
    "path": "src/content/1.4/code/scala/snippet04.scala",
    "content": "object kleisli {\n  //allows us to use >=> as an infix operator\n  implicit class KleisliOps[A, B](m1: A => Writer[B]) {\n    def >=>[C](m2: B => Writer[C]): A => Writer[C] =\n      x => {\n        val (y, s1) = m1(x)\n        val (z, s2) = m2(y)\n        (z, s1 + s2)\n      }\n    }\n}"
  },
  {
    "path": "src/content/1.4/code/scala/snippet05.scala",
    "content": "def pure[A](x: A): Writer[A] = (x, \"\")"
  },
  {
    "path": "src/content/1.4/code/scala/snippet06.scala",
    "content": "val upCase: String => Writer[String] =\n  s => (s.toUpperCase, \"upCase \")\n\nval toWords: String => Writer[List[String]] =\n  s => (s.split(' ').toList, \"toWords \")"
  },
  {
    "path": "src/content/1.4/code/scala/snippet07.scala",
    "content": "val process: String => Writer[List[String]] = {\n  import kleisli._\n  upCase >=> toWords\n}"
  },
  {
    "path": "src/content/1.4/kleisli-categories.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{Y}{ou've seen how to model} types and pure functions as a category. I also\nmentioned that there is a way to model side effects, or non-pure\nfunctions, in category theory. Let's have a look at one such example:\nfunctions that log or trace their execution. Something that, in an\nimperative language, would likely be implemented by mutating some global\nstate, as in:\n\n\\begin{snip}{cpp}\nstring logger;\n\nbool negate(bool b) {\n    logger += \"Not so! \";\n    return !b;\n}\n\\end{snip}\nYou know that this is not a pure function, because its memoized version\nwould fail to produce a log. This function has \\newterm{side effects}.\n\nIn modern programming, we try to stay away from global mutable state as\nmuch as possible --- if only because of the complications of\nconcurrency. And you would never put code like this in a library.\n\nFortunately for us, it's possible to make this function pure. You just\nhave to pass the log explicitly, in and out. Let's do that by adding a\nstring argument, and pairing regular output with a string that contains\nthe updated log:\n\n\\begin{snip}{cpp}\npair<bool, string> negate(bool b, string logger) {\n    return make_pair(!b, logger + \"Not so! \");\n}\n\\end{snip}\nThis function is pure, it has no side effects, it returns the same pair\nevery time it's called with the same arguments, and it can be memoized\nif necessary. However, considering the cumulative nature of the log,\nyou'd have to memoize all possible histories that can lead to a given\ncall. There would be a separate memo entry for:\n\n\\begin{snip}{cpp}\nnegate(true, \"It was the best of times. \");\n\\end{snip}\nand\n\n\\begin{snip}{cpp}\nnegate(true, \"It was the worst of times. \");\n\\end{snip}\nand so on.\n\nIt's also not a very good interface for a library function. The callers\nare free to ignore the string in the return type, so that's not a huge\nburden; but they are forced to pass a string as input, which might be\ninconvenient.\n\nIs there a way to do the same thing less intrusively? Is there a way to\nseparate concerns? In this simple example, the main purpose of the\nfunction \\code{negate} is to turn one Boolean into another. The\nlogging is secondary. Granted, the message that is logged is specific to\nthe function, but the task of aggregating the messages into one\ncontinuous log is a separate concern. We still want the function to\nproduce a string, but we'd like to unburden it from producing a log. So\nhere's the compromise solution:\n\n\\begin{snip}{cpp}\npair<bool, string> negate(bool b) {\n    return make_pair(!b, \"Not so! \");\n}\n\\end{snip}\nThe idea is that the log will be aggregated \\emph{between} function\ncalls.\n\nTo see how this can be done, let's switch to a slightly more realistic\nexample. We have one function from string to string that turns lower\ncase characters to upper case:\n\n\\begin{snip}{cpp}\nstring toUpper(string s) {\n    string result;\n    int (*toupperp)(int) = &toupper; // toupper is overloaded\n    transform(begin(s), end(s), back_inserter(result), toupperp);\n    return result;\n}\n\\end{snip}\nand another that splits a string into a vector of strings, breaking it\non whitespace boundaries:\n\n\\begin{snip}{cpp}\nvector<string> toWords(string s) {\n    return words(s);\n}\n\\end{snip}\nThe actual work is done in the auxiliary function \\code{words}:\n\n\\begin{snip}{cpp}\nvector<string> words(string s) {\n    vector<string> result{\"\"};\n    for (auto i = begin(s); i != end(s); ++i)\n    {\n        if (isspace(*i))\n            result.push_back(\"\");\n        else\n            result.back() += *i;\n    }\n    return result;\n}\n\\end{snip}\nWe want to modify the functions \\code{toUpper} and \\code{toWords} so\nthat they piggyback a message string on top of their regular return\nvalues.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/piggyback.jpg}\n\\end{figure}\n\\noindent\nWe will ``embellish'' the return values of these functions. Let's do it\nin a generic way by defining a template \\code{Writer} that\nencapsulates a pair whose first component is a value of arbitrary type\n\\code{A} and the second component is a string:\n\n\\begin{snip}{cpp}\ntemplate<typename A>\nusing Writer = pair<A, string>;\n\\end{snip}\nHere are the embellished functions:\n\n\\begin{snip}{cpp}\nWriter<string> toUpper(string s) {\n    string result;\n    int (*toupperp)(int) = &toupper;\n    transform(begin(s), end(s), back_inserter(result), toupperp);\n    return make_pair(result, \"toUpper \");\n}\n\nWriter<vector<string>> toWords(string s) {\n    return make_pair(words(s), \"toWords \");\n}\n\\end{snip}\nWe want to compose these two functions into another embellished function\nthat uppercases a string and splits it into words, all the while\nproducing a log of those actions. Here's how we may do it:\n\n\\begin{snip}{cpp}\nWriter<vector<string>> process(string s) {\n    auto p1 = toUpper(s);\n    auto p2 = toWords(p1.first);\n    return make_pair(p2.first, p1.second + p2.second);\n}\n\\end{snip}\nWe have accomplished our goal: The aggregation of the log is no longer\nthe concern of the individual functions. They produce their own\nmessages, which are then, externally, concatenated into a larger log.\n\nNow imagine a whole program written in this style. It's a nightmare of\nrepetitive, error-prone code. But we are programmers. We know how to\ndeal with repetitive code: we abstract it! This is, however, not your\nrun of the mill abstraction --- we have to abstract \\newterm{function\n  composition} itself. But composition is the essence of category theory,\nso before we write more code, let's analyze the problem from the\ncategorical point of view.\n\n\\section{The Writer Category}\n\nThe idea of embellishing the return types of a bunch of functions in\norder to piggyback some additional functionality turns out to be very\nfruitful. We'll see many more examples of it. The starting point is our\nregular category of types and functions. We'll leave the types as\nobjects, but redefine our morphisms to be the embellished functions.\n\nFor instance, suppose that we want to embellish the function\n\\code{isEven} that goes from \\code{int} to \\code{bool}. We turn it\ninto a morphism that is represented by an embellished function. The\nimportant point is that this morphism is still considered an arrow\nbetween the objects \\code{int} and \\code{bool}, even though the\nembellished function returns a pair:\n\n\\begin{snip}{cpp}\npair<bool, string> isEven(int n) {\n    return make_pair(n % 2 == 0, \"isEven \");\n}\n\\end{snip}\nBy the laws of a category, we should be able to compose this morphism\nwith another morphism that goes from the object \\code{bool} to\nwhatever. In particular, we should be able to compose it with our\nearlier \\code{negate}:\n\n\\begin{snip}{cpp}\npair<bool, string> negate(bool b) {\n    return make_pair(!b, \"Not so! \");\n}\n\\end{snip}\nObviously, we cannot compose these two morphisms the same way we compose\nregular functions, because of the input/output mismatch. Their\ncomposition should look more like this:\n\n\\begin{snip}{cpp}\npair<bool, string> isOdd(int n) {\n    pair<bool, string> p1 = isEven(n);\n    pair<bool, string> p2 = negate(p1.first);\n    return make_pair(p2.first, p1.second + p2.second);\n}\n\\end{snip}\nSo here's the recipe for the composition of two morphisms in this new\ncategory we are constructing:\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Execute the embellished function corresponding to the first morphism\n  \\item\n        Extract the first component of the result pair and pass it to the\n        embellished function corresponding to the second morphism\n  \\item\n        Concatenate the second component (the string) of the first result\n        and the second component (the string) of the second result\n  \\item\n        Return a new pair combining the first component of the final result\n        with the concatenated string.\n\\end{enumerate}\n\nIf we want to abstract this composition as a higher order function in\nC++, we have to use a template parameterized by three types\ncorresponding to three objects in our category. It should take two\nembellished functions that are composable according to our rules, and\nreturn a third embellished function:\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B, typename C>\nfunction<Writer<C>(A)> compose(function<Writer<B>(A)> m1,\n                               function<Writer<C>(B)> m2)\n{\n    return [m1, m2](A x) {\n        auto p1 = m1(x);\n        auto p2 = m2(p1.first);\n        return make_pair(p2.first, p1.second + p2.second);\n    };\n}\n\\end{snip}\nNow we can go back to our earlier example and implement the composition\nof \\code{toUpper} and \\code{toWords} using this new template:\n\n\\begin{snip}{cpp}\nWriter<vector<string>> process(string s) {\n    return compose<string, string, vector<string>>(\n        toUpper, toWords)(s);\n}\n\\end{snip}\nThere is still a lot of noise with the passing of types to the\n\\code{compose} template. This can be avoided as long as you have a\nC++14-compliant compiler that supports generalized lambda functions with\nreturn type deduction (credit for this code goes to Eric Niebler):\n\n\\begin{snip}{cpp}\nauto const compose = [](auto m1, auto m2) {\n    return [m1, m2](auto x) {\n        auto p1 = m1(x);\n        auto p2 = m2(p1.first);\n        return make_pair(p2.first, p1.second + p2.second);\n    };\n};\n\\end{snip}\nIn this new definition, the implementation of \\code{process}\nsimplifies to:\n\n\\begin{snip}{cpp}\nWriter<vector<string>> process(string s) {\n    return compose(toUpper, toWords)(s);\n}\n\\end{snip}\nBut we are not finished yet. We have defined composition in our new\ncategory, but what are the identity morphisms? These are not our regular\nidentity functions! They have to be morphisms from type A back to type\nA, which means they are embellished functions of the form:\n\n\\begin{snip}{cpp}\nWriter<A> identity(A);\n\\end{snip}\nThey have to behave like units with respect to composition. If you look\nat our definition of composition, you'll see that an identity morphism\nshould pass its argument without change, and only contribute an empty\nstring to the log:\n\n\\begin{snip}{cpp}\ntemplate<typename A>\nWriter<A> identity(A x) {\n    return make_pair(x, \"\");\n}\n\\end{snip}\nYou can easily convince yourself that the category we have just defined\nis indeed a legitimate category. In particular, our composition is\ntrivially associative. If you follow what's happening with the first\ncomponent of each pair, it's just a regular function composition, which\nis associative. The second components are being concatenated, and\nconcatenation is also associative.\n\nAn astute reader may notice that it would be easy to generalize this\nconstruction to any monoid, not just the string monoid. We would use\n\\code{mappend} inside \\code{compose} and \\code{mempty} inside\n\\code{identity} (in place of \\code{+} and \\code{\"\"}). There really\nis no reason to limit ourselves to logging just strings. A good library\nwriter should be able to identify the bare minimum of constraints that\nmake the library work --- here the logging library's only requirement is\nthat the log have monoidal properties.\n\n\\section{Writer in Haskell}\n\nThe same thing in Haskell is a little more terse, and we also get a lot\nmore help from the compiler. Let's start by defining the \\code{Writer}\ntype:\n\n\\src{snippet01}\nHere I'm just defining a type alias, an equivalent of a \\code{typedef}\n(or \\code{using}) in C++. The type \\code{Writer} is parameterized by\na type variable \\code{a} and is equivalent to a pair of \\code{a} and\n\\code{String}. The syntax for pairs is minimal: just two items in\nparentheses, separated by a comma.\n\nOur morphisms are functions from an arbitrary type to some\n\\code{Writer} type:\n\n\\src{snippet02}\nWe'll declare the composition as a funny infix operator, sometimes\ncalled the ``fish'':\n\n\\src{snippet03}\nIt's a function of two arguments, each being a function on its own, and\nreturning a function. The first argument is of the type\n\\code{(a -> Writer b)}, the second is\n\\code{(b -> Writer c)}, and the result is\n\\code{(a -> Writer c)}.\n\nHere's the definition of this infix operator --- the two arguments\n\\code{m1} and \\code{m2} appearing on either side of the fishy\nsymbol:\n\n\\src{snippet04}\nThe result is a lambda function of one argument \\code{x}. The lambda\nis written as a backslash --- think of it as the Greek letter $\\lambda$ with an\namputated leg.\n\nThe \\code{let} expression lets you declare auxiliary variables. Here\nthe result of the call to \\code{m1} is pattern matched to a pair of\nvariables \\code{(y, s1)}; and the result of the call to \\code{m2},\nwith the argument \\code{y} from the first pattern, is matched to\n\\code{(z, s2)}.\n\nIt is common in Haskell to pattern match pairs, rather than use\naccessors, as we did in C++. Other than that there is a pretty\nstraightforward correspondence between the two implementations.\n\nThe overall value of the \\code{let} expression is specified in its\n\\code{in} clause: here it's a pair whose first component is \\code{z}\nand the second component is the concatenation of two strings,\n\\code{s1++s2}.\n\nI will also define the identity morphism for our category, but for\nreasons that will become clear much later, I will call it\n\\code{return}.\n\n\\src{snippet05}\nFor completeness, let's have the Haskell versions of the embellished\nfunctions \\code{upCase} and \\code{toWords}:\n\n\\src{snippet06}\nThe function \\code{map} corresponds to the C++ \\code{transform}. It\napplies the character function \\code{toUpper} to the string\n\\code{s}. The auxiliary function \\code{words} is defined in the\nstandard Prelude library.\n\nFinally, the composition of the two functions is accomplished with the\nhelp of the fish operator:\n\n\\src{snippet07}\n\n\\section{Kleisli Categories}\n\nYou might have guessed that I haven't invented this category on the\nspot. It's an example of the so called Kleisli category --- a category\nbased on a monad. We are not ready to discuss monads yet, but I wanted\nto give you a taste of what they can do. For our limited purposes, a\nKleisli category has, as objects, the types of the underlying\nprogramming language. Morphisms from type $A$ to type $B$ are functions that\ngo from $A$ to a type derived from $B$ using the particular embellishment.\nEach Kleisli category defines its own way of composing such morphisms,\nas well as the identity morphisms with respect to that composition.\n(Later we'll see that the imprecise term ``embellishment'' corresponds\nto the notion of an endofunctor in a category.)\n\nThe particular monad that I used as the basis of the category in this\nchapter is called the \\newterm{writer monad} and it's used for logging or\ntracing the execution of functions. It's also an example of a more\ngeneral mechanism for embedding effects in pure computations. You've\nseen previously that we could model programming-language types and\nfunctions in the category of sets (disregarding bottoms, as usual). Here\nwe have extended this model to a slightly different category, a category\nwhere morphisms are represented by embellished functions, and their\ncomposition does more than just pass the output of one function to the\ninput of another. We have one more degree of freedom to play with: the\ncomposition itself. It turns out that this is exactly the degree of\nfreedom which makes it possible to give simple denotational semantics to\nprograms that in imperative languages are traditionally implemented\nusing side effects.\n\n\\section{Challenge}\n\nA function that is not defined for all possible values of its argument\nis called a partial function. It's not really a function in the\nmathematical sense, so it doesn't fit the standard categorical mold. It\ncan, however, be represented by a function that returns an embellished\ntype \\code{optional}:\n\n\\begin{snip}{cpp}\ntemplate<typename A>\nclass optional {\n    bool _isValid;\n    A _value;\npublic:\n    optional()    : _isValid(false) {}\n    optional(A v) : _isValid(true), _value(v) {}\n    bool isValid() const { return _isValid; }\n    A value() const { return _value; }\n};\n\\end{snip}\nFor example, here's the implementation of the embellished function\n\\code{safe\\_root}:\n\n\\begin{snip}{cpp}\noptional<double> safe_root(double x) {\n    if (x >= 0) return optional<double>{sqrt(x)};\n    else return optional<double>{};\n}\n\\end{snip}\nHere's the challenge:\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Construct the Kleisli category for partial functions (define\n        composition and identity).\n  \\item\n        Implement the embellished function \\code{safe\\_reciprocal} that\n        returns a valid reciprocal of its argument, if it's different from\n        zero.\n  \\item\n        Compose the functions \\code{safe\\_root} and \\code{safe\\_reciprocal} to implement\n        \\code{safe\\_root\\_reciprocal} that calculates \\code{sqrt(1/x)}\n        whenever possible.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet01.hs",
    "content": "absurd :: Void -> a"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet02.hs",
    "content": "unit :: a -> ()\nunit _ = ()"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet03.hs",
    "content": "yes :: a -> Bool\nyes _ = True"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet04.hs",
    "content": "no :: a -> Bool\nno _ = False"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet05.hs",
    "content": "f . g = id\ng . f = id"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet06.hs",
    "content": "fst :: (a, b) -> a\nfst (x, y) = x"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet07.hs",
    "content": "snd :: (a, b) -> b\nsnd (x, y) = y"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet08.hs",
    "content": "fst (x, _) = x\nsnd (_, y) = y"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet09.hs",
    "content": "p :: c -> a\nq :: c -> b"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet10.hs",
    "content": "p :: Int -> Int\np x = x\n\nq :: Int -> Bool\nq _ = True"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet11.hs",
    "content": "p :: (Int, Int, Bool) -> Int\np (x, _, _) = x\n\nq :: (Int, Int, Bool) -> Bool\nq (_, _, b) = b"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet12.hs",
    "content": "p' = p . m\nq' = q . m"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet13.hs",
    "content": "m :: Int -> (Int, Bool)\nm x = (x, True)"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet14.hs",
    "content": "p x = fst (m x) = x\nq x = snd (m x) = True"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet15.hs",
    "content": "m (x, _, b) = (x, b)"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet16.hs",
    "content": "fst = p . m'\nsnd = q . m'"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet17.hs",
    "content": "m' (x, b) = (x, x, b)"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet18.hs",
    "content": "m' (x, b) = (x, 42, b)"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet19.hs",
    "content": "m :: c -> (a, b)\nm x = (p x, q x)"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet20.hs",
    "content": "factorizer :: (c -> a) -> (c -> b) -> (c -> (a, b))\nfactorizer p q = \\x -> (p x, q x)"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet21.hs",
    "content": "i :: a -> c\nj :: b -> c"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet22.hs",
    "content": "i' = m . i\nj' = m . j"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet23.hs",
    "content": "data Contact = PhoneNum Int | EmailAddr String"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet24.hs",
    "content": "helpdesk :: Contact\nhelpdesk = PhoneNum 2222222"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet25.hs",
    "content": "data Either a b = Left a | Right b"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet26.hs",
    "content": "factorizer :: (a -> c) -> (b -> c) -> Either a b -> c\nfactorizer i j (Left a)  = i a\nfactorizer i j (Right b) = j b"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet27.hs",
    "content": "p = fst . m\nq = snd . m"
  },
  {
    "path": "src/content/1.5/code/haskell/snippet28.hs",
    "content": "p () = fst (m ())\nq () = snd (m ())"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet01.ml",
    "content": "type void (* Uninhabited type *)\n\nval absurd : void -> 'a\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet02.ml",
    "content": "let unit x = ()\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet03.ml",
    "content": "let yes _ = true\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet04.ml",
    "content": "let no _ = false\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet05.ml",
    "content": "compose f g = id\ncompose g f = id\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet06.ml",
    "content": "let fst (a, b) = a\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet07.ml",
    "content": "let snd (a, b) = b\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet08.ml",
    "content": "let fst (a, _) = a\nlet snd (_, b) = b\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet09.ml",
    "content": "module type Chapter5_Product = sig\n  type a\n  type c\n  type b\n\n  val p : c -> a\n  val q : c -> b\nend\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet10.ml",
    "content": "module Chapter5_Product_Example :\n  Chapter5_Product\n    with type a = int\n     and type b = bool\n     and type c = int = struct\n  type a = int\n  type b = bool\n  type c = int\n\n  let p x = x\n  let q _ = true\nend\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet11.ml",
    "content": "module Chapter5_Product_Example2 : Chapter5_Product = struct\n  type a = int\n  type b = bool\n  type c = int * int * bool\n\n  let p (x, _, _) = x\n  let q (_, _, b) = b\nend\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet12.ml",
    "content": "let p' = compose Chapter5_Product_Example.p m\nlet q' = compose Chapter5_Product_Example.q m\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet13.ml",
    "content": "let m (x : int) = x, true\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet14.ml",
    "content": "let p x = fst (m x)\nlet q x = snd (m x)\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet15.ml",
    "content": "let m ((x, _, b) : int * int * bool) = x, b\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet16.ml",
    "content": "fst = compose p m'\nsnd = compose q m'\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet17.ml",
    "content": "let m' ((x, b) : int * bool) = x, x, b\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet18.ml",
    "content": "let m' ((x, b) : int * bool) = x, 42, b\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet19.ml",
    "content": "module type Chapter5_product_projection_example = functor\n  (Product : Chapter5_Product)\n  -> sig\n  val m : Product.c -> Product.a * Product.b\nend\n\nmodule ProjectionImpl (Product : Chapter5_Product) = struct\n  let m c = Product.p c, Product.q c\nend\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet20.ml",
    "content": "module type Factorizer = functor (Product : Chapter5_Product) -> sig\n  val factorizer\n    :  (Product.c -> Product.a)\n    -> (Product.c -> Product.b)\n    -> Product.c\n    -> Product.a * Product.b\nend\n\nmodule FactorizerImpl (Product : Chapter5_Product) = struct\n  let factorizer ca cb = Product.p ca, Product.q cb\nend\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet21.ml",
    "content": "module type CoProduct = sig\n  type a\n  type b\n  type c\n\n  val i : a -> c\n  val j : b -> c\nend\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet22.ml",
    "content": "i' == compose m i\nj' == compose m j\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet23.ml",
    "content": "type contact =\n  | PhoneNum of int\n  | EmailAddr of string\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet24.ml",
    "content": "let helpdesk = PhoneNum 2222222\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet25.ml",
    "content": "type ('a, 'b) either =\n  | Left of 'a\n  | Right of 'b\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet26.ml",
    "content": "let factorizer i j = function\n  | Left a -> i a\n  | Right b -> j b\n;;\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet27.ml",
    "content": "p = compose fst m\nq = compose snd m\n"
  },
  {
    "path": "src/content/1.5/code/ocaml/snippet28.ml",
    "content": "p () = fst (m ())\nq () = snd (m ())\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet01.re",
    "content": "type void; /* Uninhabited type */\n\ntype absurd = void => 'a = ;\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet02.re",
    "content": "let unit = x => ();\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet03.re",
    "content": "let yes = _ => true;\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet04.re",
    "content": "let no = _ => false;\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet05.re",
    "content": "compose(f, g) == id;\ncompose(g, f) == id;\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet06.re",
    "content": "let fst = ((a, b)) => a;\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet07.re",
    "content": "let snd = ((a, b)) => b;\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet08.re",
    "content": "let fst = ((a, _)) => a;\nlet snd = ((_, b)) => b;\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet09.re",
    "content": "module type Chapter5_Product = {\n  type a;\n  type c;\n  type b;\n  \n  let p: c => a;\n  let q: c => b;\n};\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet10.re",
    "content": "module Chapter5_Product_Example:\n  Chapter5_Product \n    with type a = int\n    and type b = bool\n    and type c = int = {\n  type a = int;\n  type b = bool;\n  type c = int;\n\n  let p = x => x;\n  let q = _ => true;\n};\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet11.re",
    "content": "module Chapter5_Product_Example2: Chapter5_Product = {\n  type a = int;\n  type b = bool;\n  type c = (int, int, bool);\n  \n  let p = ((x, _, _)) => x;\n  let q = ((_, _, b)) => b;\n};\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet12.re",
    "content": "let p' = compose(Chapter5_Product_Example.p, m);\nlet q' = compose(Chapter5_Product_Example.q, m);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet13.re",
    "content": "let m = (x: int) => (x, true);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet14.re",
    "content": "let p = x => fst(m(x));\nlet q = x => snd(m(x));\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet15.re",
    "content": "let m = ((x, _, b): (int, int, bool)) => (x, b);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet16.re",
    "content": "fst == compose(p, m');\nsnd == compose(q, m');\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet17.re",
    "content": "let m' = ((x, b): (int, bool)) => (x, x, b);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet18.re",
    "content": "let m' = ((x, b): (int, bool)) => (x, 42, b);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet19.re",
    "content": "module type Chapter5_product_projection_example =\n  (Product: Chapter5_Product) => {\n    let m: Product.c => (Product.a, Product.b);\n};\n\nmodule ProjectionImpl = (Product: Chapter5_Product) => {\n  let m = c => (Product.p(c), Product.q(c));\n};\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet20.re",
    "content": "module type Factorizer = (Product: Chapter5_Product) => {\n  let factorizer:\n    (Product.c => Product.a, Product.c => Product.b, Product.c) =>\n    (Product.a, Product.b);\n};\n\nmodule FactorizerImpl = (Product: Chapter5_Product) => {\n  let factorizer = (ca, cb) => (Product.p(ca), Product.q(cb));\n};\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet21.re",
    "content": "module type CoProduct = {\n  type a;\n  type b;\n  type c;\n  \n  let i: a => c;\n  let j: b => c;\n};\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet22.re",
    "content": "i' === compose(m, i)\nj' === compose(m, j);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet23.re",
    "content": "type contact =\n  | PhoneNum(int)\n  | EmailAddr(string);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet24.re",
    "content": "let helpdesk = PhoneNum(2222222);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet25.re",
    "content": "type either('a, 'b) =\n  | Left('a)\n  | Right('b);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet26.re",
    "content": "let factorizer = (i, j) =>\n  fun\n  | Left(a) => i(a)\n  | Right(b) => j(b);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet27.re",
    "content": "p == compose(fst, m);\nq == compose(snd, m);\n"
  },
  {
    "path": "src/content/1.5/code/reason/snippet28.re",
    "content": "p() == fst(m());\nq() == snd(m());\n"
  },
  {
    "path": "src/content/1.5/code/scala/snippet01.scala",
    "content": "def absurd[A]: Nothing => A"
  },
  {
    "path": "src/content/1.5/code/scala/snippet02.scala",
    "content": "def unit[A]: A => Unit = _ => ()"
  },
  {
    "path": "src/content/1.5/code/scala/snippet03.scala",
    "content": "def yes[A]: A => Boolean = _ => true"
  },
  {
    "path": "src/content/1.5/code/scala/snippet04.scala",
    "content": "def no[A]: A => Boolean = _ => false"
  },
  {
    "path": "src/content/1.5/code/scala/snippet05.scala",
    "content": "f compose g == identity _\ng compose f == identity _"
  },
  {
    "path": "src/content/1.5/code/scala/snippet06.scala",
    "content": "def fst[A, B]: ((A, B)) => A = {\n  case (x, y) => x\n}"
  },
  {
    "path": "src/content/1.5/code/scala/snippet07.scala",
    "content": "def snd[A, B]: ((A, B)) => B = {\n  case (x, y) => y\n}"
  },
  {
    "path": "src/content/1.5/code/scala/snippet08.scala",
    "content": "def fst[A, B]: ((A, B)) => A = _._1\ndef snd[A, B]: ((A, B)) => B = _._2"
  },
  {
    "path": "src/content/1.5/code/scala/snippet09.scala",
    "content": "def p: C => A\ndef q: C => B"
  },
  {
    "path": "src/content/1.5/code/scala/snippet10.scala",
    "content": "def p: Int => Int = x => x\n\ndef q: Int => Boolean = _ => true"
  },
  {
    "path": "src/content/1.5/code/scala/snippet11.scala",
    "content": "def p: ((Int, Int, Boolean)) => Int = _._1\n\ndef q: ((Int, Int, Boolean)) => Boolean = _._3"
  },
  {
    "path": "src/content/1.5/code/scala/snippet12.scala",
    "content": "p1 == p compose m\nq1 == q compose m"
  },
  {
    "path": "src/content/1.5/code/scala/snippet13.scala",
    "content": "def m: Int => (Int, Boolean) = x => (x, true)"
  },
  {
    "path": "src/content/1.5/code/scala/snippet14.scala",
    "content": "def p: Int => Int = x => fst(m(x)) // == x\ndef q: Int => Boolean = x => snd(m(x)) // == true"
  },
  {
    "path": "src/content/1.5/code/scala/snippet15.scala",
    "content": "def m: ((Int, Int, Boolean)) => (Int, Boolean) = {\n  case (x, _, b) => (x, b)\n}"
  },
  {
    "path": "src/content/1.5/code/scala/snippet16.scala",
    "content": "fst == p compose m1\nsnd == q compose m1"
  },
  {
    "path": "src/content/1.5/code/scala/snippet17.scala",
    "content": "def m1: ((Int, Boolean)) => (Int, Int, Boolean) = {\n  case (x, b) => (x, x, b)\n}"
  },
  {
    "path": "src/content/1.5/code/scala/snippet18.scala",
    "content": "def m1: ((Int, Boolean)) => (Int, Int, Boolean) = {\n  case (x, b) => (x, 42, b)\n}"
  },
  {
    "path": "src/content/1.5/code/scala/snippet19.scala",
    "content": "def m: C => (A, B) = x => (p(x), q(x))"
  },
  {
    "path": "src/content/1.5/code/scala/snippet20.scala",
    "content": "def factorizer[A, B, C]: (C => A) => (C => B) => (C => (A, B)) =\n  p => q => x => (p(x), q(x))"
  },
  {
    "path": "src/content/1.5/code/scala/snippet21.scala",
    "content": "def i: A => C\ndef j: B => C"
  },
  {
    "path": "src/content/1.5/code/scala/snippet22.scala",
    "content": "i1 == m compose i\nj1 == m compose j"
  },
  {
    "path": "src/content/1.5/code/scala/snippet23.scala",
    "content": "sealed trait Contact\ncase class PhoneNum(num: Int) extends Contact\ncase class EmailAddr(addr: String) extends Contact"
  },
  {
    "path": "src/content/1.5/code/scala/snippet24.scala",
    "content": "def helpdesk: Contact = PhoneNum(2222222)"
  },
  {
    "path": "src/content/1.5/code/scala/snippet25.scala",
    "content": "sealed trait Either[A, B]\ncase class Left[A](v: A) extends Either[A, Nothing]\ncase class Right[B](v: B) extends Either[Nothing, B]"
  },
  {
    "path": "src/content/1.5/code/scala/snippet26.scala",
    "content": "def factorizer[A, B, C]: (A => C) => (B => C) => Either[A, B] => C =\n  i => j => {\n    case Left(a) => i(a)\n    case Right(b) => j(b)\n  }"
  },
  {
    "path": "src/content/1.5/code/scala/snippet27.scala",
    "content": "p == fst compose m\nq == snd compose m"
  },
  {
    "path": "src/content/1.5/code/scala/snippet28.scala",
    "content": "p(()) == fst(m(()))\nq(()) == snd(m(()))"
  },
  {
    "path": "src/content/1.5/products-and-coproducts.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{T}{he Ancient Greek} playwright Euripides once said: ``Every man is like\nthe company he is wont to keep.'' We are defined by our relationships.\nNowhere is this more true than in category theory. If we want to single\nout a particular object in a category, we can only do this by describing\nits pattern of relationships with other objects (and itself). These\nrelationships are defined by morphisms.\n\nThere is a common construction in category theory called the\n\\newterm{universal construction} for defining objects in terms of their\nrelationships. One way of doing this is to pick a pattern, a particular\nshape constructed from objects and morphisms, and look for all its\noccurrences in the category. If it's a common enough pattern, and the\ncategory is large, chances are you'll have lots and lots of hits. The\ntrick is to establish some kind of ranking among those hits, and pick\nwhat could be considered the best fit.\n\nThis process is reminiscent of the way we do web searches. A query is\nlike a pattern. A very general query will give you large \\emph{recall}:\nlots of hits. Some may be relevant, others not. To eliminate irrelevant\nhits, you refine your query. That increases its \\emph{precision}.\nFinally, the search engine will rank the hits and, hopefully, the one\nresult that you're interested in will be at the top of the list.\n\n\\section{Initial Object}\n\nThe simplest shape is a single object. Obviously, there are as many\ninstances of this shape as there are objects in a given category. That's\na lot to choose from. We need to establish some kind of ranking and try\nto find the object that tops this hierarchy. The only means at our\ndisposal are morphisms. If you think of morphisms as arrows, then it's\npossible that there is an overall net flow of arrows from one end of the\ncategory to another. This is true in ordered categories, for instance in\npartial orders. We could generalize that notion of object precedence by\nsaying that object $a$ is ``more initial'' than object $b$, if\nthere is an arrow (a morphism) going from $a$ to $b$. We would\nthen define \\emph{the} initial object as one that has arrows going to\nall other objects. Obviously there is no guarantee that such an object\nexists, and that's okay. A bigger problem is that there may be too many\nsuch objects: The recall is good, but precision is lacking. The solution\nis to take a hint from ordered categories --- they allow at most one\narrow between any two objects: there is only one way of being less-than\nor equal-to another object. Which leads us to this definition of the\ninitial object:\n\n\\begin{quote}\n  The \\textbf{initial object} is the object that has one and only one\n  morphism going to any object in the category.\n\\end{quote}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/initial.jpg}\n\\end{figure}\n\n\\noindent\nHowever, even that doesn't guarantee the uniqueness of the initial\nobject (if one exists). But it guarantees the next best thing:\nuniqueness \\newterm{up to isomorphism}. Isomorphisms are very important in\ncategory theory, so I'll talk about them shortly. For now, let's just\nagree that uniqueness up to isomorphism justifies the use of ``the'' in\nthe definition of the initial object.\n\nHere are some examples: The initial object in a partially ordered set\n(often called a \\newterm{poset}) is its least element. Some posets don't\nhave an initial object --- like the set of all integers, positive and\nnegative, with less-than-or-equal relation for morphisms.\n\nIn the category of sets and functions, the initial object is the empty\nset. Remember, an empty set corresponds to the Haskell type\n\\code{Void} (there is no corresponding type in C++) and the unique\npolymorphic function from \\code{Void} to any other type is called\n\\code{absurd}:\n\n\\src{snippet01}\nIt's this family of morphisms that makes \\code{Void} the initial\nobject in the category of types.\n\n\\section{Terminal Object}\n\nLet's continue with the single-object pattern, but let's change the way\nwe rank the objects. We'll say that object $a$ is ``more terminal''\nthan object $b$ if there is a morphism going from $b$ to\n$a$ (notice the reversal of direction). We'll be looking for an\nobject that's more terminal than any other object in the category.\nAgain, we will insist on uniqueness:\n\n\\begin{quote}\n  The \\textbf{terminal object} is the object with one and only one\n  morphism coming to it from any object in the category.\n\\end{quote}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/final.jpg}\n\\end{figure}\n\n\\noindent\nAnd again, the terminal object is unique, up to isomorphism, which I\nwill show shortly. But first let's look at some examples. In a poset,\nthe terminal object, if it exists, is the biggest object. In the\ncategory of sets, the terminal object is a singleton. We've already\ntalked about singletons --- they correspond to the \\code{void} type in\nC++ and the unit type \\code{()} in Haskell. It's a type that has only\none value --- implicit in C++ and explicit in Haskell, denoted by\n\\code{()}. We've also established that there is one and only one pure\nfunction from any type to the unit type:\n\n\\src{snippet02}\nso all the conditions for the terminal object are satisfied.\n\nNotice that in this example the uniqueness condition is crucial, because\nthere are other sets (actually, all of them, except for the empty set)\nthat have incoming morphisms from every set. For instance, there is a\nBoolean-valued function (a predicate) defined for every type:\n\n\\src{snippet03}\nBut \\code{Bool} is not a terminal object. There is at least one more\n\\code{Bool}-valued function from every type (except \\code{Void}, for which both functions are equal to \\code{absurd}):\n\n\\src{snippet04}\nInsisting on uniqueness gives us just the right precision to narrow down\nthe definition of the terminal object to just one type.\n\n\\section{Duality}\n\nYou can't help but to notice the symmetry between the way we defined the\ninitial object and the terminal object. The only difference between the\ntwo was the direction of morphisms. It turns out that for any category $\\cat{C}$\nwe can define the \\newterm{opposite category} $\\cat{C}^\\mathit{op}$ just by\nreversing all the arrows. The opposite category automatically satisfies\nall the requirements of a category, as long as we simultaneously\nredefine composition. If original morphisms\n$f \\Colon a \\to b$ and $g \\Colon b \\to c$ composed\nto $h \\Colon a \\to c$ with $h = g \\circ f$, then the reversed\nmorphisms $f^\\mathit{op} \\Colon b \\to a$ and $g^\\mathit{op} \\Colon c \\to b$ will compose to\n$h^\\mathit{op} \\Colon c \\to a$ with $h^\\mathit{op} = f^\\mathit{op} \\circ g^\\mathit{op}$. And reversing\nthe identity arrows is a (pun alert!) no-op.\n\nDuality is a very important property of categories because it doubles\nthe productivity of every mathematician working in category theory. For\nevery construction you come up with, there is its opposite; and for\nevery theorem you prove, you get one for free. The constructions in the\nopposite category are often prefixed with ``co'', so you have products\nand coproducts, monads and comonads, cones and cocones, limits and\ncolimits, and so on. There are no cocomonads though, because reversing\nthe arrows twice gets us back to the original state.\n\nIt follows then that a terminal object is the initial object in the\nopposite category.\n\n\\section{Isomorphisms}\n\nAs programmers, we are well aware that defining equality is a nontrivial\ntask. What does it mean for two objects to be equal? Do they have to\noccupy the same location in memory (pointer equality)? Or is it enough\nthat the values of all their components are equal? Are two complex\nnumbers equal if one is expressed as the real and imaginary part, and\nthe other as modulus and angle? You'd think that mathematicians would\nhave figured out the meaning of equality, but they haven't. They have\nthe same problem of multiple competing definitions for equality. There\nis the propositional equality, intensional equality, extensional\nequality, and equality as a path in homotopy type theory. And then there\nare the weaker notions of isomorphism, and even weaker of equivalence.\n\nThe intuition is that isomorphic objects look the same --- they have the\nsame shape. It means that every part of one object corresponds to some\npart of another object in a one-to-one mapping. As far as our\ninstruments can tell, the two objects are a perfect copy of each other.\nMathematically it means that there is a mapping from object $a$ to\nobject $b$, and there is a mapping from object $b$ back to\nobject $a$, and they are the inverse of each other. In category\ntheory we replace mappings with morphisms. An isomorphism is an\ninvertible morphism; or a pair of morphisms, one being the inverse of\nthe other.\n\nWe understand the inverse in terms of composition and identity: Morphism\n$g$ is the inverse of morphism $f$ if their composition is the\nidentity morphism. These are actually two equations because there are\ntwo ways of composing two morphisms:\n\n\\src{snippet05}\nWhen I said that the initial (terminal) object was unique up to\nisomorphism, I meant that any two initial (terminal) objects are\nisomorphic. That's actually easy to see. Let's suppose that we have two\ninitial objects $i_{1}$ and $i_{2}$. Since\n$i_{1}$ is initial, there is a unique morphism $f$ from\n$i_{1}$ to $i_{2}$. By the same token, since\n$i_{2}$ is initial, there is a unique morphism $g$ from\n$i_{2}$ to $i_{1}$. What's the composition of\nthese two morphisms?\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/uniqueness.jpg}\n  \\caption{All morphisms in this diagram are unique.}\n\\end{figure}\n\n\\noindent\nThe composition $g \\circ f$ must be a morphism from $i_{1}$ to\n$i_{1}$. But $i_{1}$ is initial so there can only\nbe one morphism going from $i_{1}$ to $i_{1}$.\nSince we are in a category, we know that there is an identity morphism\nfrom $i_{1}$ to $i_{1}$, and since there is room\nfor only one, that must be it. Therefore $g \\circ f$ is equal to\nidentity. Similarly, $f \\circ g$ must be equal to identity, because there\ncan be only one morphism from $i_{2}$ back to\n$i_{2}$. This proves that $f$ and $g$ must be the\ninverse of each other. Therefore any two initial objects are isomorphic.\n\nNotice that in this proof we used the uniqueness of the morphism from\nthe initial object to itself. Without that we couldn't prove the ``up to\nisomorphism'' part. But why do we need the uniqueness of $f$ and\n$g$? Because not only is the initial object unique up to\nisomorphism, it is unique up to \\emph{unique} isomorphism. In principle,\nthere could be more than one isomorphism between two objects, but that's\nnot the case here. This ``uniqueness up to unique isomorphism'' is the\nimportant property of all universal constructions.\n\n\\section{Products}\n\nThe next universal construction is that of a product. We know what a\nCartesian product of two sets is: it's a set of pairs. But what's the\npattern that connects the product set with its constituent sets? If we\ncan figure that out, we'll be able to generalize it to other categories.\n\nAll we can say is that there are two functions, the projections, from\nthe product to each of the constituents. In Haskell, these two functions\nare called \\code{fst} and \\code{snd} and they pick, respectively,\nthe first and the second component of a pair:\n\n\\src{snippet06}\n\n\\src{snippet07}\nHere, the functions are defined by pattern matching their arguments: the\npattern that matches any pair is \\code{(x, y)}, and it extracts its\ncomponents into variables \\code{x} and \\code{y}.\n\nThese definitions can be simplified even further with the use of\nwildcards:\n\n\\src{snippet08}\nIn C++, we would use template functions, for instance:\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B>\nA fst(pair<A, B> const & p) {\n    return p.first;\n}\n\\end{snip}\nEquipped with this seemingly very limited knowledge, let's try to define\na pattern of objects and morphisms in the category of sets that will\nlead us to the construction of a product of two sets, $a$ and\n$b$. This pattern consists of an object $c$ and two morphisms\n$p$ and $q$ connecting it to $a$ and $b$,\nrespectively:\n\n\\src{snippet09}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/productpattern.jpg}\n\\end{figure}\n\n\\noindent\nAll $c$s that fit this pattern will be considered candidates for\nthe product. There may be lots of them.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/productcandidates.jpg}\n\\end{figure}\n\n\\noindent\nFor instance, let's pick, as our constituents, two Haskell types,\n\\code{Int} and \\code{Bool}, and get a sampling of candidates for\ntheir product.\n\nHere's one: \\code{Int}. Can \\code{Int} be considered a candidate for\nthe product of \\code{Int} and \\code{Bool}? Yes, it can --- and here\nare its projections:\n\n\\src{snippet10}\nThat's pretty lame, but it matches the criteria.\n\nHere's another one: \\code{(Int, Int, Bool)}. It's a tuple of three\nelements, or a triple. Here are two morphisms that make it a legitimate\ncandidate (we are using pattern matching on triples):\n\n\\src{snippet11}\nYou may have noticed that while our first candidate was too small --- it\nonly covered the \\code{Int} dimension of the product; the second was\ntoo big --- it spuriously duplicated the \\code{Int} dimension.\n\nBut we haven't explored yet the other part of the universal\nconstruction: the ranking. We want to be able to compare two instances\nof our pattern. We want to compare one candidate object $c$ and its\ntwo projections $p$ and $q$ with another candidate object\n$c'$ and its two projections $p'$ and $q'$. We would like\nto say that $c$ is ``better'' than $c'$ if there is a morphism\n$m$ from $c'$ to $c$ --- but that's too weak. We also\nwant its projections to be ``better,'' or ``more universal,'' than the\nprojections of $c'$. What it means is that the projections\n$p'$ and $q'$ can be reconstructed from $p$ and $q$ using $m$:\n\n\\src{snippet12}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/productranking.jpg}\n\\end{figure}\n\n\\noindent\nAnother way of looking at these equations is that $m$\n\\emph{factorizes} $p'$ and $q'$. Just pretend that these\nequations are in natural numbers, and the dot is multiplication:\n$m$ is a common factor shared by $p'$ and $q'$.\n\nJust to build some intuitions, let me show you that the pair\n\\code{(Int, Bool)} with the two canonical projections, \\code{fst}\nand \\code{snd} is indeed \\emph{better} than the two candidates I\npresented before.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/not-a-product.jpg}\n\\end{figure}\n\n\\noindent\nThe mapping \\code{m} for the first candidate is:\n\n\\src{snippet13}\nIndeed, the two projections, \\code{p} and \\code{q} can be\nreconstructed as:\n\n\\src{snippet14}\nThe \\code{m} for the second example is similarly uniquely determined:\n\n\\src{snippet15}\nWe were able to show that \\code{(Int, Bool)} is better than either of\nthe two candidates. Let's see why the opposite is not true. Could we\nfind some \\code{m'} that would help us reconstruct \\code{fst}\nand \\code{snd} from \\code{p} and \\code{q}?\n\n\\src{snippet16}\nIn our first example, \\code{q} always returned \\code{True} and we\nknow that there are pairs whose second component is \\code{False}. We\ncan't reconstruct \\code{snd} from \\code{q}.\n\nThe second example is different: we retain enough information after\nrunning either \\code{p} or \\code{q}, but there is more than one way\nto factorize \\code{fst} and \\code{snd}. Because both \\code{p} and\n\\code{q} ignore the second component of the triple, our \\code{m'}\ncan put anything in it. We can have:\n\n\\src{snippet17}\n\nor\n\\src{snippet18}\nand so on.\n\nPutting it all together, given any type \\code{c} with two projections\n\\code{p} and \\code{q}, there is a unique \\code{m} from \\code{c}\nto the Cartesian product \\code{(a, b)} that factorizes them. In fact,\nit just combines \\code{p} and \\code{q} into a pair.\n\n\\src{snippet19}\nThat makes the Cartesian product \\code{(a, b)} our best match, which\nmeans that this universal construction works in the category of sets. It\npicks the product of any two sets.\n\nNow let's forget about sets and define a product of two objects in any\ncategory using the same universal construction. Such a product doesn't\nalways exist, but when it does, it is unique up to a unique isomorphism.\n\n\\begin{quote}\n  A \\textbf{product} of two objects $a$ and $b$ is the object\n  $c$ equipped with two projections such that for any other object\n  $c'$ equipped with two projections there is a unique morphism\n  $m$ from $c'$ to $c$ that factorizes those projections.\n\\end{quote}\n\n\\noindent\nA (higher order) function that produces the factorizing function\n\\code{m} from two candidates is sometimes called the\n\\newterm{factorizer}. In our case, it would be the function:\n\n\\src{snippet20}\n\n\\section{Coproduct}\n\nLike every construction in category theory, the product has a dual,\nwhich is called the coproduct. When we reverse the arrows in the product\npattern, we end up with an object $c$ equipped with two\n\\emph{injections}, \\code{i} and \\code{j}: morphisms from $a$\nand $b$ to $c$.\n\n\\src{snippet21}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/coproductpattern.jpg}\n\\end{figure}\n\n\\noindent\nThe ranking is also inverted: object $c$ is ``better'' than object\n$c'$ that is equipped with the injections $i'$ and $j'$\nif there is a morphism $m$ from $c$ to $c'$ that\nfactorizes the injections:\n\n\\src{snippet22}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/coproductranking.jpg}\n\\end{figure}\n\n\\noindent\nThe ``best'' such object, one with a unique morphism connecting it to\nany other pattern, is called a coproduct and, if it exists, is unique up\nto unique isomorphism.\n\n\\begin{quote}\n  A \\textbf{coproduct} of two objects $a$ and $b$ is the object\n  $c$ equipped with two injections such that for any other object\n  $c'$ equipped with two injections there is a unique morphism\n  $m$ from $c$ to $c'$ that factorizes those injections.\n\\end{quote}\n\n\\noindent\nIn the category of sets, the coproduct is the \\emph{disjoint union} of\ntwo sets. An element of the disjoint union of $a$ and $b$ is\neither an element of $a$ or an element of $b$. If the two sets\noverlap, the disjoint union contains two copies of the common part. You\ncan think of an element of a disjoint union as being tagged with an\nidentifier that specifies its origin.\n\nFor a programmer, it's easier to understand a coproduct in terms of\ntypes: it's a tagged union of two types. C++ supports unions, but they\nare not tagged. It means that in your program you have to somehow keep\ntrack which member of the union is valid. To create a tagged union, you\nhave to define a tag --- an enumeration --- and combine it with the\nunion. For instance, a tagged union of an \\code{int} and a\n\\code{char const *} could be implemented as:\n\n\\begin{snip}{cpp}\nstruct Contact {\n    enum { isPhone, isEmail } tag;\n    union { int phoneNum; char const * emailAddr; };\n};\n\\end{snip}\nThe two injections can either be implemented as constructors or as\nfunctions. For instance, here's the first injection as a function\n\\code{PhoneNum}:\n\n\\begin{snip}{cpp}\nContact PhoneNum(int n) {\n    Contact c;\n    c.tag = isPhone;\n    c.phoneNum = n;\n    return c;\n}\n\\end{snip}\nIt injects an integer into \\code{Contact}.\n\nA tagged union is also called a \\newterm{variant}, and there is a very\ngeneral implementation of a variant in the C++17 standard,\n\\code{std::variant}.\n\nIn Haskell, you can combine any data types into a tagged union by\nseparating data constructors with a vertical bar. The \\code{Contact}\nexample translates into the declaration:\n\n\\src{snippet23}\nHere, \\code{PhoneNum} and \\code{EmailAddr} serve both as\nconstructors (injections), and as tags for pattern matching (more about\nthis later). For instance, this is how you would construct a contact\nusing a phone number:\n\n\\src{snippet24}\nUnlike the canonical implementation of the product that is built into\nHaskell as the primitive pair, the canonical implementation of the\ncoproduct is a data type called \\code{Either}, which is defined in the\nstandard Prelude as:\n\n\\src{snippet25}\nIt is parameterized by two types, \\code{a} and \\code{b} and has two\nconstructors: \\code{Left} that takes a value of type \\code{a}, and\n\\code{Right} that takes a value of type \\code{b}.\n\nJust as we've defined the factorizer for a product, we can define one\nfor the coproduct. Given a candidate type \\code{c} and two candidate\ninjections \\code{i} and \\code{j}, the factorizer for \\code{Either}\nproduces the factoring function:\n\n\\src{snippet26}\n\n\\section{Asymmetry}\n\nWe've seen two sets of dual definitions: The definition of a terminal\nobject can be obtained from the definition of the initial object by\nreversing the direction of arrows; in a similar way, the definition of\nthe coproduct can be obtained from that of the product. Yet in the\ncategory of sets the initial object is very different from the final\nobject, and coproduct is very different from product. We'll see later\nthat product behaves like multiplication, with the terminal object\nplaying the role of one; whereas coproduct behaves more like the sum,\nwith the initial object playing the role of zero. In particular, for\nfinite sets, the size of the product is the product of the sizes of\nindividual sets, and the size of the coproduct is the sum of the sizes.\n\nThis shows that the category of sets is not symmetric with respect to\nthe inversion of arrows.\n\nNotice that while the empty set has a unique morphism to any set (the\n\\code{absurd} function), it has no morphisms coming back. The\nsingleton set has a unique morphism coming to it from any set, but it\n\\emph{also} has outgoing morphisms to every set (except for the empty\none). As we've seen before, these outgoing morphisms from the terminal\nobject play a very important role of picking elements of other sets (the\nempty set has no elements, so there's nothing to pick).\n\nIt's the relationship of the singleton set to the product that sets it\napart from the coproduct. Consider using the singleton set, represented\nby the unit type \\code{()}, as yet another --- vastly inferior ---\ncandidate for the product pattern. Equip it with two projections\n\\code{p} and \\code{q}: functions from the singleton to each of the\nconstituent sets. Each selects a concrete element from either set.\nBecause the product is universal, there is also a (unique) morphism\n\\code{m} from our candidate, the singleton, to the product. This\nmorphism selects an element from the product set --- it selects a\nconcrete pair. It also factorizes the two projections:\n\n\\src{snippet27}\nWhen acting on the singleton value \\code{()}, the only element of the\nsingleton set, these two equations become:\n\n\\src{snippet28}\nSince \\code{m ()} is the element of the product picked by \\code{m},\nthese equations tell us that the element picked by \\code{p} from the\nfirst set, \\code{p ()}, is the first component of the pair picked by\n\\code{m}. Similarly, \\code{q ()} is equal to the second component.\nThis is in total agreement with our understanding that elements of the\nproduct are pairs of elements from the constituent sets.\n\nThere is no such simple interpretation of the coproduct. We could try\nthe singleton set as a candidate for a coproduct, in an attempt to\nextract the elements from it, but there we would have two injections\ngoing into it rather than two projections coming out of it. They'd tell\nus nothing about their sources (in fact, we've seen that they ignore the\ninput parameter). Neither would the unique morphism from the coproduct\nto our singleton. The category of sets just looks very different when\nseen from the direction of the initial object than it does when seen\nfrom the terminal end.\n\nThis is not an intrinsic property of sets, it's a property of functions,\nwhich we use as morphisms in $\\Set$. Functions are, in general,\nasymmetric. Let me explain.\n\nA function must be defined for every element of its domain set (in\nprogramming, we call it a \\newterm{total} function), but it doesn't have to\ncover the whole codomain. We've seen some extreme cases of it: functions\nfrom a singleton set --- functions that select just a single element in\nthe codomain. (Actually, functions from an empty set are the real\nextremes.) When the size of the domain is much smaller than the size of\nthe codomain, we often think of such functions as embedding the domain\nin the codomain. For instance, we can think of a function from a\nsingleton set as embedding its single element in the codomain. I call\nthem \\newterm{embedding} functions, but mathematicians prefer to give a\nname to the opposite: functions that tightly fill their codomains are\ncalled \\newterm{surjective} or \\newterm{onto}.\n\nThe other source of asymmetry is that functions are allowed to map many\nelements of the domain set into one element of the codomain. They can\ncollapse them. The extreme case are functions that map whole sets into a\nsingleton. You've seen the polymorphic \\code{unit} function that does\njust that. The collapsing can only be compounded by composition. A\ncomposition of two collapsing functions is even more collapsing than the\nindividual functions. Mathematicians have a name for non-collapsing\nfunctions: they call them \\newterm{injective} or \\newterm{one-to-one}.\n\nOf course there are some functions that are neither embedding nor\ncollapsing. They are called \\newterm{bijections} and they are truly\nsymmetric, because they are invertible. In the category of sets, an\nisomorphism is the same as a bijection.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Show that the terminal object is unique up to unique isomorphism.\n  \\item\n        What is a product of two objects in a poset? Hint: Use the universal\n        construction.\n  \\item\n        What is a coproduct of two objects in a poset?\n  \\item\n        Implement the equivalent of Haskell \\code{Either} as a generic type\n        in your favorite language (other than Haskell).\n  \\item\n        Show that \\code{Either} is a ``better'' coproduct than \\code{int}\n        equipped with two injections:\n\n        \\begin{snip}{cpp}\nint i(int n) { return n; }\nint j(bool b) { return b ? 0: 1; }\n\\end{snip}\n\n        Hint: Define a function\n\n        \\begin{snip}{cpp}\nint m(Either const & e);\n\\end{snip}\n\n        that factorizes \\code{i} and \\code{j}.\n  \\item\n        Continuing the previous problem: How would you argue that \\code{int}\n        with the two injections \\code{i} and \\code{j} cannot be ``better''\n        than \\code{Either}?\n  \\item\n        Still continuing: What about these injections?\n\n        \\begin{snip}{cpp}\nint i(int n) {\n    if (n < 0) return n;\n    return n + 2;\n}\n\nint j(bool b) { return b ? 0: 1; }\n\\end{snip}\n  \\item\n        Come up with an inferior candidate for a coproduct of \\code{int} and\n        \\code{bool} that cannot be better than \\code{Either} because it\n        allows multiple acceptable morphisms from it to \\code{Either}.\n\\end{enumerate}\n\n\\section{Bibliography}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        The Catsters,\n        \\urlref{https://www.youtube.com/watch?v=upCSDIO9pjc}{Products and\n          Coproducts} video.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet01.hs",
    "content": "swap :: (a, b) -> (b, a)\nswap (x, y) = (y, x)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet02.hs",
    "content": "((a, b), c)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet03.hs",
    "content": "(a, (b, c))"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet04.hs",
    "content": "alpha :: ((a, b), c) -> (a, (b, c))\nalpha ((x, y), z) = (x, (y, z))"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet05.hs",
    "content": "alpha_inv :: (a, (b, c)) -> ((a, b), c)\nalpha_inv (x, (y, z)) = ((x, y), z)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet06.hs",
    "content": "(a, ())"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet07.hs",
    "content": "rho :: (a, ()) -> a\nrho (x, ()) = x"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet08.hs",
    "content": "rho_inv :: a -> (a, ())\nrho_inv x = (x, ())"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet09.hs",
    "content": "data Pair a b = P a b"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet10.hs",
    "content": "stmt :: Pair String Bool\nstmt = P \"This statement is\" False"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet11.hs",
    "content": "data Pair a b = Pair a b"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet12.hs",
    "content": "stmt = (,) \"This statement is\" False"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet13.hs",
    "content": "data Stmt = Stmt String Bool"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet14.hs",
    "content": "startsWithSymbol :: (String, String, Int) -> Bool\nstartsWithSymbol (name, symbol, _) = isPrefixOf symbol name"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet15.hs",
    "content": "data Element = Element { name :: String \n                       , symbol :: String \n                       , atomicNumber :: Int }"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet16.hs",
    "content": "tupleToElem :: (String, String, Int) -> Element\ntupleToElem (n, s, a) = Element { name = n \n                                , symbol = s \n                                , atomicNumber = a }"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet17.hs",
    "content": "elemToTuple :: Element -> (String, String, Int)\nelemToTuple e = (name e, symbol e, atomicNumber e)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet18.hs",
    "content": "atomicNumber :: Element -> Int"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet19.hs",
    "content": "startsWithSymbol :: Element -> Bool\nstartsWithSymbol e = isPrefixOf (symbol e) (name e)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet20.hs",
    "content": "startsWithSymbol e = symbol e `isPrefixOf` name e"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet21.hs",
    "content": "data Either a b = Left a | Right b"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet22.hs",
    "content": "data OneOfThree a b c = Sinistral a | Medial b | Dextral c"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet23.hs",
    "content": "Either a Void"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet24.hs",
    "content": "data Color = Red | Green | Blue"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet25.hs",
    "content": "data Bool = True | False"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet26.hs",
    "content": "data Maybe a = Nothing | Just a"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet27.hs",
    "content": "data NothingType = Nothing"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet28.hs",
    "content": "data JustType a = Just a"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet29.hs",
    "content": "type Maybe a = Either () a\n"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet30.hs",
    "content": "data List a = Nil | Cons a (List a)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet31.hs",
    "content": "maybeTail :: List a -> Maybe (List a)\nmaybeTail Nil = Nothing\nmaybeTail (Cons _ t) = Just t"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet32.hs",
    "content": "(a, Either b c)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet33.hs",
    "content": "Either (a, b) (a, c)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet34.hs",
    "content": "prodToSum :: (a, Either b c) -> Either (a, b) (a, c)\nprodToSum (x, e) =\n    case e of\n      Left  y -> Left  (x, y)\n      Right z -> Right (x, z)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet35.hs",
    "content": "sumToProd :: Either (a, b) (a, c) -> (a, Either b c)\nsumToProd e =\n    case e of\n      Left  (x, y) -> (x, Left  y)\n      Right (x, z) -> (x, Right z)"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet36.hs",
    "content": "prod1 :: (Int, Either String Float)\nprod1 = (2, Left \"Hi!\")"
  },
  {
    "path": "src/content/1.6/code/haskell/snippet37.hs",
    "content": "data List a = Nil | Cons a (List a)"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet01.ml",
    "content": "let swap (a, b) = b, a\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet02.ml",
    "content": "(('a * 'b) * 'c)\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet03.ml",
    "content": "('a * ('b * 'c))\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet04.ml",
    "content": "let alpha ((a, b), c) = a, (b, c)\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet05.ml",
    "content": "let alpha_inv (a, (b, c)) = (a, b), c\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet06.ml",
    "content": "'a * unit\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet07.ml",
    "content": "let rho (a, ()) = a\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet08.ml",
    "content": "let rho_inv a = a, ()\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet09.ml",
    "content": "type ('a, 'b) pair = P of 'a * 'b\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet10.ml",
    "content": "let stmt = P (\"This statement is\", false)\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet11.ml",
    "content": "type ('a, 'b) pair = Pair of ('a * 'b)\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet12.ml",
    "content": "let stmt = \"This statement is\", false\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet13.ml",
    "content": "type stmt = Stmt of string * int\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet14.ml",
    "content": "let starts_with_symbol (name, symbol, _) =\n  String.is_prefix name ~prefix:symbol\n;;\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet15.ml",
    "content": "type element =\n  { name : string\n  ; symbol : string\n  ; atomic_number : int\n  }\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet16.ml",
    "content": "let tuple_to_elem (name, symbol, atomic_number) =\n  { name; symbol; atomic_number }\n;;\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet17.ml",
    "content": "let elem_to_tuple { name; symbol; atomic_number } =\n  name, symbol, atomic_number\n;;\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet18.ml",
    "content": "let atomic_number { atomic_number } = atomic_number\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet19.ml",
    "content": "let starts_with_symbol { name; symbol; _ } =\n  String.is_prefix name ~prefix:symbol\n;;\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet20.ml",
    "content": "(* OCaml only allows special characters in the infix operator.\n   So, the above function name cannot be applied be infix. *)\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet21.ml",
    "content": "type ('a, 'b) either =\n  | Left of 'a\n  | Right of 'b\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet22.ml",
    "content": "type ('a, 'b, 'c) one_of_three =\n  | Sinistrial of 'a\n  | Medial of 'b\n  | Dextral of 'c\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet23.ml",
    "content": "'a void either\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet24.ml",
    "content": "type color =\n  | Red\n  | Green\n  | Blue\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet25.ml",
    "content": "type bool =\n  | True\n  | False\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet26.ml",
    "content": "type 'a maybe =\n  | Nothing\n  | Just of 'a\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet27.ml",
    "content": "type nothing_type = Nothing\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet28.ml",
    "content": "type 'a just_type = Just of 'a\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet29.ml",
    "content": "type 'a maybe = (unit, 'a) either\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet30.ml",
    "content": "type 'a list =\n  | Nil\n  | Cons of 'a * 'a list\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet31.ml",
    "content": "type 'a maybe =\n  | Nothing\n  | Just of 'a\n\nlet maybe_tail = function\n  | Nil -> Nothing\n  | Cons (_, xs) -> Just xs\n;;\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet32.ml",
    "content": "'a * ('b, 'c) either\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet33.ml",
    "content": "('a * 'b, 'c * 'd) either\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet34.ml",
    "content": "let prod_to_sum (x, e) =\n  match e with\n  | Left y -> Left (x, y)\n  | Right z -> Right (x, z)\n;;\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet35.ml",
    "content": "let sum_to_prod = function\n  | Left (x, y) -> x, Left y\n  | Right (x, z) -> x, Right z\n;;\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet36.ml",
    "content": "let prod1 = 2, Left \"Hi!\"\n"
  },
  {
    "path": "src/content/1.6/code/ocaml/snippet37.ml",
    "content": "type 'a list =\n  | Nil\n  | Cons of 'a * 'a list\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet01.re",
    "content": "let swap = ((a, b)) => (b, a);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet02.re",
    "content": "(('a, 'b), 'c)"
  },
  {
    "path": "src/content/1.6/code/reason/snippet03.re",
    "content": "('a, ('b, 'c))"
  },
  {
    "path": "src/content/1.6/code/reason/snippet04.re",
    "content": "let alpha = (((a, b), c)) => (a, (b, c));\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet05.re",
    "content": "let alpha_inv = ((a, (b, c))) => ((a, b), c);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet06.re",
    "content": "('a, unit)"
  },
  {
    "path": "src/content/1.6/code/reason/snippet07.re",
    "content": "let rho = ((a, ())) => a;\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet08.re",
    "content": "let rho_inv = a => (a, ());\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet09.re",
    "content": "type pair('a, 'b) =\n  | P('a, 'b);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet10.re",
    "content": "let stmt = P(\"This statement is\", false);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet11.re",
    "content": "type pair('a, 'b) =\n  | Pair(('a, 'b));\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet12.re",
    "content": "let stmt = (\"This statement is\", false);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet13.re",
    "content": "type stmt =\n  | Stmt(string, int);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet14.re",
    "content": "let starts_with_symbol = ((name, symbol, _)) =>\n  String.is_prefix(name, ~prefix=symbol);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet15.re",
    "content": "type element = {\n  name: string,\n  symbol: string,\n  atomic_number: int,\n};\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet16.re",
    "content": "let tuple_to_elem = ((name, symbol, atomic_number)) => {\n  name,\n  symbol,\n  atomic_number,\n};\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet17.re",
    "content": "let elem_to_tuple = ({name, symbol, atomic_number}) => (\n  name,\n  symbol,\n  atomic_number,\n);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet18.re",
    "content": "let atomic_number = ({atomic_number}) => atomic_number;\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet19.re",
    "content": "let starts_with_symbol = ({name, symbol, _}) =>\n  String.is_prefix(name, ~prefix=symbol);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet20.re",
    "content": "// ReasonML only allows special characters in the infix operator.\n// So, the above function name cannot be applied as infix.\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet21.re",
    "content": "type either('a, 'b) =\n  | Left('a)\n  | Right('b);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet22.re",
    "content": "type one_of_three('a, 'b, 'c) =\n  | Sinistrial('a)\n  | Medial('b)\n  | Dextral('c);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet23.re",
    "content": "either('a, void)"
  },
  {
    "path": "src/content/1.6/code/reason/snippet24.re",
    "content": "type color =\n  | Red\n  | Green\n  | Blue;\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet25.re",
    "content": "type bool =\n  | True\n  | False;\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet26.re",
    "content": "type maybe('a) =\n  | Nothing\n  | Just('a);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet27.re",
    "content": "type nothing_type =\n  | Nothing;\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet28.re",
    "content": "type just_type('a) =\n  | Just('a);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet29.re",
    "content": "type maybe('a) = either(unit, 'a);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet30.re",
    "content": "type list('a) =\n  | Nil\n  | Cons('a, list('a));\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet31.re",
    "content": "type maybe('a) =\n  | Nothing\n  | Just('a);\n  \nlet maybe_tail =\n  fun\n  | Nil => Nothing\n  | Cons(_, xs) => Just(xs);\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet32.re",
    "content": "('a, either('b, 'c))"
  },
  {
    "path": "src/content/1.6/code/reason/snippet33.re",
    "content": "either(('a, 'b), ('c, 'd))"
  },
  {
    "path": "src/content/1.6/code/reason/snippet34.re",
    "content": "let prod_to_sum = ((x, e)) =>\n  switch (e) {\n  | Left(y) => Left(x, y)\n  | Right(z) => Right(x, z)\n  };\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet35.re",
    "content": "let sum_to_prod =\n  fun\n  | Left(x, y) => (x, Left(y))\n  | Right(x, z) => (x, Right(z));\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet36.re",
    "content": "let prod1 = (2, Left(\"Hi!\"));\n"
  },
  {
    "path": "src/content/1.6/code/reason/snippet37.re",
    "content": "type list('a) =\n  | Nil\n  | Cons('a, list('a));\n"
  },
  {
    "path": "src/content/1.6/code/scala/snippet01.scala",
    "content": "def swap[A, B]: ((A, B)) => (B, A) = {\n  case (x, y) => (y, x)\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet02.scala",
    "content": "((A, B), C)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet03.scala",
    "content": "(A, (B, C))"
  },
  {
    "path": "src/content/1.6/code/scala/snippet04.scala",
    "content": "def alpha[A, B, C]: (((A, B), C)) => ((A, (B, C))) = {\n  case ((x, y), z) => (x, (y, z))\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet05.scala",
    "content": "def alphaInv[A, B, C]: ((A, (B, C))) => (((A, B), C)) = {\n  case (x, (y, z)) => ((x, y), z)\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet06.scala",
    "content": "(A, Unit)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet07.scala",
    "content": "def rho[A]: ((A, Unit)) => A = {\n  case (x, ()) => x\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet08.scala",
    "content": "def rhoInv[A]: A => (A, Unit) =\n  x => (x, ())"
  },
  {
    "path": "src/content/1.6/code/scala/snippet09.scala",
    "content": "sealed trait Pair[A, B]\ncase class P[A, B](a: A, b: B) extends Pair[A, B]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet10.scala",
    "content": "val stmt: Pair[String, Boolean] =\n  P(\"This statement is\", false)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet11.scala",
    "content": "case class Pair[A, B](a: A, b: B)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet12.scala",
    "content": "val stmt = (\"This statement is\", false)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet13.scala",
    "content": "case class Stmt(s: String, b: Boolean)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet14.scala",
    "content": "val startsWithSymbol: ((String, String, Int)) => Boolean = {\n  case (name, symbol, _) => name.startsWith(symbol)\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet15.scala",
    "content": "case class Element(\n  name: String,\n  symbol: String,\n  atomicNumber: Int\n)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet16.scala",
    "content": "val tupleToElem: ((String, String, Int)) => Element = {\n  case (n, s, a) => Element(n, s, a)\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet17.scala",
    "content": "val elemToTuple: Element => (String, String, Int) =\n  e => (e.name, e.symbol, e.atomicNumber)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet18.scala",
    "content": "val atomicNumber: Element => Int"
  },
  {
    "path": "src/content/1.6/code/scala/snippet19.scala",
    "content": "val startsWithSymbol: Element => Boolean =\n  e => e.name startsWith e.symbol"
  },
  {
    "path": "src/content/1.6/code/scala/snippet20.scala",
    "content": "val startsWithSymbol: Element => Boolean =\n  e => e.name startsWith e.symbol"
  },
  {
    "path": "src/content/1.6/code/scala/snippet21.scala",
    "content": "sealed trait Either[+A, +B]\ncase class Left[A](v: A) extends Either[A, Nothing]\ncase class Right[B](v: B) extends Either[Nothing, B]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet22.scala",
    "content": "sealed trait OneOfThree[+A, +B, +C]\ncase class Sinistral[A](v: A) extends OneOfThree[A, Nothing, Nothing]\ncase class Medial[B](v: B) extends OneOfThree[Nothing, B, Nothing]\ncase class Dextral[C](v: C) extends OneOfThree[Nothing, Nothing, C]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet23.scala",
    "content": "Either[A, Nothing]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet24.scala",
    "content": "sealed trait Color\ncase object Red extends Color\ncase object Green extends Color\ncase object Blue extends Color"
  },
  {
    "path": "src/content/1.6/code/scala/snippet25.scala",
    "content": "sealed trait Bool\ncase object True extends Bool\ncase object False extends Bool"
  },
  {
    "path": "src/content/1.6/code/scala/snippet26.scala",
    "content": "sealed trait Option[+A]\ncase object None extends Option[Nothing]\ncase class Some[A](a: A) extends Option[A]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet27.scala",
    "content": "case object NoneType"
  },
  {
    "path": "src/content/1.6/code/scala/snippet28.scala",
    "content": "case class SomeType[A](a: A)"
  },
  {
    "path": "src/content/1.6/code/scala/snippet29.scala",
    "content": "type Option[A] = Either[Unit, A]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet30.scala",
    "content": "sealed trait List[+A]\ncase object Nil extends List[Nothing]\ncase class Cons[A](h: A, t: List[A]) extends List[A]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet31.scala",
    "content": "def maybeTail[A]: List[A] => Option[List[A]] = {\n  case Nil => None\n  case Cons(_, t) => Some(t)\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet32.scala",
    "content": "(A, Either[B, C])"
  },
  {
    "path": "src/content/1.6/code/scala/snippet33.scala",
    "content": "Either[(A, B), (A, C)]"
  },
  {
    "path": "src/content/1.6/code/scala/snippet34.scala",
    "content": "def prodToSum[A, B, C]: ((A, Either[B, C])) => Either[(A, B), (A, C)] = {\n  case (x, e) => e match {\n    case Left(y) => Left((x, y))\n    case Right(z) => Right((x, z))\n  }\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet35.scala",
    "content": "def sumToProd[A, B, C]: Either[(A, B), (A, C)] => (A, Either[B, C]) = {\n  case Left((x, y)) => (x, Left(y))\n  case Right((x, z)) => (x, Right(z))\n}"
  },
  {
    "path": "src/content/1.6/code/scala/snippet36.scala",
    "content": "val prod1: (Int, Either[String, Float]) =\n  (2, Left(\"Hi!\"))"
  },
  {
    "path": "src/content/1.6/code/scala/snippet37.scala",
    "content": "sealed trait List[+A]\ncase object Nil extends List[Nothing]\ncase class Cons[A](h: A, t: List[A]) extends List[A]"
  },
  {
    "path": "src/content/1.6/simple-algebraic-data-types.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{W}{e've seen two basic} ways of combining types: using a product and a\ncoproduct. It turns out that a lot of data structures in everyday\nprogramming can be built using just these two mechanisms. This fact has\nimportant practical consequences. Many properties of data structures are\ncomposable. For instance, if you know how to compare values of basic\ntypes for equality, and you know how to generalize these comparisons to\nproduct and coproduct types, you can automate the derivation of equality\noperators for composite types. In Haskell you can automatically derive\nequality, comparison, conversion to and from string, and more, for a\nlarge subset of composite types.\n\nLet's have a closer look at product and sum types as they appear in\nprogramming.\n\n\\section{Product Types}\n\nThe canonical implementation of a product of two types in a programming\nlanguage is a pair. In Haskell, a pair is a primitive type constructor;\nin C++ it's a relatively complex template defined in the Standard\nLibrary.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/pair.jpg}\n\\end{figure}\n\n\\noindent\nPairs are not strictly commutative: a pair \\code{(Int, Bool)} cannot\nbe substituted for a pair \\code{(Bool, Int)}, even though they carry\nthe same information. They are, however, commutative up to isomorphism\n--- the isomorphism being given by the \\code{swap} function (which is\nits own inverse):\n\n\\src{snippet01}\nYou can think of the two pairs as simply using a different format for\nstoring the same data. It's just like big endian vs. little endian.\n\nYou can combine an arbitrary number of types into a product by nesting\npairs inside pairs, but there is an easier way: nested pairs are\nequivalent to tuples. It's the consequence of the fact that different\nways of nesting pairs are isomorphic. If you want to combine three types\nin a product, \\code{a}, \\code{b}, and \\code{c}, in this order, you\ncan do it in two ways:\n\n\\src{snippet02}\n\nor\n\\src{snippet03}\nThese types are different --- you can't pass one to a function that\nexpects the other --- but their elements are in one-to-one\ncorrespondence. There is a function that maps one to another:\n\n\\src{snippet04}\nand this function is invertible:\n\n\\src{snippet05}\nso it's an isomorphism. These are just different ways of repackaging the\nsame data.\n\nYou can interpret the creation of a product type as a binary operation\non types. From that perspective, the above isomorphism looks very much\nlike the associativity law we've seen in monoids:\n\\[(a * b) * c = a * (b * c)\\]\nExcept that, in the monoid case, the two ways of composing products were\nequal, whereas here they are only equal ``up to isomorphism.''\n\nIf we can live with isomorphisms, and don't insist on strict equality,\nwe can go even further and show that the unit type, \\code{()}, is the\nunit of the product the same way 1 is the unit of multiplication.\nIndeed, the pairing of a value of some type \\code{a} with a unit\ndoesn't add any information. The type:\n\n\\src{snippet06}\nis isomorphic to \\code{a}. Here's the isomorphism:\n\n\\src{snippet07}\n\n\\src{snippet08}\nThese observations can be formalized by saying that $\\Set$ (the\ncategory of sets) is a \\newterm{monoidal category}. It's a category that's\nalso a monoid, in the sense that you can multiply objects (here, take\ntheir Cartesian product). I'll talk more about monoidal categories, and\ngive the full definition in the future.\n\nThere is a more general way of defining product types in Haskell ---\nespecially, as we'll see soon, when they are combined with sum types. It\nuses named constructors with multiple arguments. A pair, for instance,\ncan be defined alternatively as:\n\n\\src{snippet09}\nHere, \\code{Pair a b} is the name of the type parameterized by two\nother types, \\code{a} and \\code{b}; and \\code{P} is the name of\nthe data constructor. You define a pair type by passing two types to the\n\\code{Pair} type constructor. You construct a pair value by passing\ntwo values of appropriate types to the constructor \\code{P}. For\ninstance, let's define a value \\code{stmt} as a pair of\n\\code{String} and \\code{Bool}:\n\n\\src{snippet10}\nThe first line is the type signature. It uses the type constructor\n\\code{Pair}, with \\code{String} and \\code{Bool} replacing\n\\code{a} and the \\code{b} in the generic definition of\n\\code{Pair}. The second line defines the actual value by passing a\nconcrete string and a concrete Boolean to the data constructor\n\\code{P}. Type constructors are used to construct types; data\nconstructors, to construct values.\n\nSince the name spaces for type and data constructors are separate in\nHaskell, you will often see the same name used for both, as in:\n\n\\src{snippet11}\nAnd if you squint hard enough, you may even view the built-in pair type\nas a variation on this kind of declaration, where the name \\code{Pair}\nis replaced with the binary operator \\code{(,)}. In fact you can use\n\\code{(,)} just like any other named constructor and create pairs\nusing prefix notation:\n\n\\src{snippet12}\nSimilarly, you can use \\code{(,,)} to create triples, and so on.\n\nInstead of using generic pairs or tuples, you can also define specific\nnamed product types, as in:\n\n\\src{snippet13}\nwhich is just a product of \\code{String} and \\code{Bool}, but it's\ngiven its own name and constructor. The advantage of this style of\ndeclaration is that you may define many types that have the same content\nbut different meaning and functionality, and which cannot be substituted\nfor each other.\n\nProgramming with tuples and multi-argument constructors can get messy\nand error prone --- keeping track of which component represents what.\nIt's often preferable to give names to components. A product type with\nnamed fields is called a \\newterm{record} in Haskell, and a \\code{struct} in C.\n\n\\section{Records}\n\nLet's have a look at a simple example. We want to describe chemical\nelements by combining two strings, name and symbol; and an integer, the\natomic number; into one data structure. We can use a tuple\n\\code{(String, String, Int)} and remember which component represents\nwhat. We would extract components by pattern matching, as in this\nfunction that checks if the symbol of the element is the prefix of its\nname (as in \\textbf{He} being the prefix of \\textbf{Helium}):\n\n\\src{snippet14}\nThis code is error prone, and is hard to read and maintain. It's much\nbetter to define a record:\n\n\\src{snippet15}\nThe two representations are isomorphic, as witnessed by these two\nconversion functions, which are the inverse of each other:\n\n\\src{snippet16}\n\n\\src{snippet17}\nNotice that the names of record fields also serve as functions to access\nthese fields. For instance, \\code{atomicNumber e} retrieves the\n\\code{atomicNumber} field from \\code{e}. We use\n\\code{atomicNumber} as a function of the type:\n\n\\src{snippet18}\nWith the record syntax for \\code{Element}, our function\n\\code{startsWithSymbol} becomes more readable:\n\n\\src{snippet19}\nWe could even use the Haskell trick of turning the function\n\\code{isPrefixOf} into an infix operator by surrounding it with\nbackquotes, and make it read almost like a sentence:\n\n\\src{snippet20}\nThe parentheses could be omitted in this case, because an infix operator\nhas lower precedence than a function call.\n\n\\section{Sum Types}\n\nJust as the product in the category of sets gives rise to product types,\nthe coproduct gives rise to sum types. The canonical implementation of a\nsum type in Haskell is:\n\n\\src{snippet21}\nAnd like pairs, \\code{Either}s are commutative (up to isomorphism),\ncan be nested, and the nesting order is irrelevant (up to isomorphism).\nSo we can, for instance, define a sum equivalent of a triple:\n\n\\src{snippet22}\nand so on.\n\nIt turns out that $\\Set$ is also a (symmetric) monoidal category\nwith respect to coproduct. The role of the binary operation is played by\nthe disjoint sum, and the role of the unit element is played by the\ninitial object. In terms of types, we have \\code{Either} as the\nmonoidal operator and \\code{Void}, the uninhabited type, as its\nneutral element. You can think of \\code{Either} as plus, and\n\\code{Void} as zero. Indeed, adding \\code{Void} to a sum type\ndoesn't change its content. For instance:\n\n\\src{snippet23}\nis isomorphic to \\code{a}. That's because there is no way to construct\na \\code{Right} version of this type --- there isn't a value of type\n\\code{Void}. The only inhabitants of \\code{Either a Void} are\nconstructed using the \\code{Left} constructors and they simply\nencapsulate a value of type \\code{a}. So, symbolically, $a + 0 = a$.\n\nSum types are pretty common in Haskell, but their C++ equivalents,\nunions or variants, are much less common. There are several reasons for\nthat.\n\nFirst of all, the simplest sum types are just enumerations and are\nimplemented using \\code{enum} in C++. The equivalent of the Haskell\nsum type:\n\n\\src{snippet24}\nis the C++:\n\n\\begin{snip}{cpp}\nenum { Red, Green, Blue };\n\\end{snip}\nAn even simpler sum type:\n\n\\src{snippet25}\nis the primitive \\code{bool} in C++.\n\nSimple sum types that encode the presence or absence of a value are\nvariously implemented in C++ using special tricks and ``impossible''\nvalues, like empty strings, negative numbers, null pointers, etc. This\nkind of optionality, if deliberate, is expressed in Haskell using the\n\\code{Maybe} type:\n\n\\src{snippet26}\nThe \\code{Maybe} type is a sum of two types. You can see this if you\nseparate the two constructors into individual types. The first one would\nlook like this:\n\n\\src{snippet27}\nIt's an enumeration with one value called \\code{Nothing}. In other\nwords, it's a singleton, which is equivalent to the unit type\n\\code{()}. The second part:\n\n\\src{snippet28}\nis just an encapsulation of the type \\code{a}. We could have encoded\n\\code{Maybe} as:\n\n\\src{snippet29}\nMore complex sum types are often faked in C++ using pointers. A pointer\ncan be either null, or point to a value of specific type. For instance,\na Haskell list type, which can be defined as a (recursive) sum type:\n\n\\src{snippet30}\ncan be translated to C++ using the null pointer trick to implement the\nempty list:\n\n\\begin{snip}{cpp}\ntemplate<typename A>\nclass List {\n    Node<A> * _head;\npublic:\n    List() : _head(nullptr) {} // Nil\n    List(A a, List<A> l)       // Cons\n      : _head(new Node<A>(a, l))\n    {}\n};\n\\end{snip}\nNotice that the two Haskell constructors \\code{Nil} and \\code{Cons}\nare translated into two overloaded \\code{List} constructors with\nanalogous arguments (none, for \\code{Nil}; and a value and a list for\n\\code{Cons}). The \\code{List} class doesn't need a tag to\ndistinguish between the two components of the sum type. Instead it uses\nthe special \\code{nullptr} value for \\code{\\_head} to encode\n\\code{Nil}.\n\nThe main difference, though, between Haskell and C++ types is that\nHaskell data structures are immutable. If you create an object using one\nparticular constructor, the object will forever remember which\nconstructor was used and what arguments were passed to it. So a\n\\code{Maybe} object that was created as \\code{Just \"energy\"} will\nnever turn into \\code{Nothing}. Similarly, an empty list will forever\nbe empty, and a list of three elements will always have the same three\nelements.\n\nIt's this immutability that makes construction reversible. Given an\nobject, you can always disassemble it down to parts that were used in\nits construction. This deconstruction is done with pattern matching and\nit reuses constructors as patterns. Constructor arguments, if any, are\nreplaced with variables (or other patterns).\n\nThe \\code{List} data type has two constructors, so the deconstruction\nof an arbitrary \\code{List} uses two patterns corresponding to those\nconstructors. One matches the empty \\code{Nil} list, and the other a\n\\code{Cons}-constructed list. For instance, here's the definition of a\nsimple function on \\code{List}s:\n\n\\src{snippet31}\nThe first part of the definition of \\code{maybeTail} uses the\n\\code{Nil} constructor as pattern and returns \\code{Nothing}. The\nsecond part uses the \\code{Cons} constructor as pattern. It replaces\nthe first constructor argument with a wildcard, because we are not\ninterested in it. The second argument to \\code{Cons} is bound to the\nvariable \\code{t} (I will call these things variables even though,\nstrictly speaking, they never vary: once bound to an expression, a\nvariable never changes). The return value is \\code{Just t}. Now,\ndepending on how your \\code{List} was created, it will match one of\nthe clauses. If it was created using \\code{Cons}, the two arguments\nthat were passed to it will be retrieved (and the first discarded).\n\nEven more elaborate sum types are implemented in C++ using polymorphic\nclass hierarchies. A family of classes with a common ancestor may be\nunderstood as one variant type, in which the vtable serves as a hidden\ntag. What in Haskell would be done by pattern matching on the\nconstructor, and by calling specialized code, in C++ is accomplished by\ndispatching a call to a virtual function based on the vtable pointer.\n\nYou will rarely see \\code{union} used as a sum type in C++ because of\nsevere limitations on what can go into a union. You can't even put a\n\\code{std::string} into a union because it has a copy constructor.\n\n\\section{Algebra of Types}\n\nTaken separately, product and sum types can be used to define a variety\nof useful data structures, but the real strength comes from combining\nthe two. Once again we are invoking the power of composition.\n\nLet's summarize what we've discovered so far. We've seen two commutative\nmonoidal structures underlying the type system: We have the sum types\nwith \\code{Void} as the neutral element, and the product types with\nthe unit type, \\code{()}, as the neutral element. We'd like to think\nof them as analogous to addition and multiplication. In this analogy,\n\\code{Void} would correspond to zero, and unit, \\code{()}, to one.\n\nLet's see how far we can stretch this analogy. For instance, does\nmultiplication by zero give zero? In other words, is a product type with\none component being \\code{Void} isomorphic to \\code{Void}? For\nexample, is it possible to create a pair of, say \\code{Int} and\n\\code{Void}?\n\nTo create a pair you need two values. Although you can easily come up\nwith an integer, there is no value of type \\code{Void}. Therefore, for\nany type \\code{a}, the type \\code{(a, Void)} is uninhabited --- has\nno values --- and is therefore equivalent to \\code{Void}. In other\nwords, $a \\times 0 = 0$.\n\nAnother thing that links addition and multiplication is the distributive\nproperty:\n\\[a \\times (b + c) = a \\times b + a \\times c\\]\nDoes it also hold for product and sum types? Yes, it does --- up to\nisomorphisms, as usual. The left hand side corresponds to the type:\n\n\\src{snippet32}\nand the right hand side corresponds to the type:\n\n\\src{snippet33}\nHere's the function that converts them one way:\n\n\\src{snippet34}\nand here's one that goes the other way:\n\n\\src{snippet35}\nThe \\code{case of} clause is used for pattern matching inside\nfunctions. Each pattern is followed by an arrow and the expression to be\nevaluated when the pattern matches. For instance, if you call\n\\code{prodToSum} with the value:\n\n\\src{snippet36}\nthe \\code{e} in \\code{case e of} will be equal to\n\\code{Left \"Hi!\"}. It will match the pattern \\code{Left y},\nsubstituting \\code{\"Hi!\"} for \\code{y}. Since the \\code{x} has\nalready been matched to \\code{2}, the result of the \\code{case of}\nclause, and the whole function, will be \\code{Left (2, \"Hi!\")}, as\nexpected.\n\nI'm not going to prove that these two functions are the inverse of each\nother, but if you think about it, they must be! They are just trivially\nre-packing the contents of the two data structures. It's the same data,\nonly different format.\n\nMathematicians have a name for two such intertwined monoids: it's called\na \\newterm{semiring}. It's not a full \\newterm{ring}, because we can't define\nsubtraction of types. That's why a semiring is sometimes called a\n\\newterm{rig}, which is a pun on ``ring without an \\emph{n}'' (negative).\nBut barring that, we can get a lot of mileage from translating\nstatements about, say, natural numbers, which form a rig, to statements\nabout types. Here's a translation table with some entries of interest:\n\n\\begin{longtable}[]{@{}ll@{}}\n  \\toprule\n  Numbers      & Types\\tabularnewline\n  \\midrule\n  \\endhead\n  $0$          & \\code{Void}\\tabularnewline\n  $1$          & \\code{()}\\tabularnewline\n  $a + b$      & \\code{data Either a b = Left a | Right b}\\tabularnewline\n  $a \\times b$ & \\code{(a, b)} or \\code{data Pair a b = Pair a b}\\tabularnewline\n  $2 = 1 + 1$  & \\code{data Bool = True | False}\\tabularnewline\n  $1 + a$      & \\code{data Maybe a = Nothing | Just a}\\tabularnewline\n  \\bottomrule\n\\end{longtable}\n\n\\noindent\nThe list type is quite interesting, because it's defined as a solution\nto an equation. The type we are defining appears on both sides of the\nequation:\n\n\\src{snippet37}\nIf we do our usual substitutions, and also replace \\code{List a} with\n\\code{x}, we get the equation:\n\n\\begin{Verbatim}\n  x = 1 + a * x\n\\end{Verbatim}\nWe can't solve it using traditional algebraic methods because we can't\nsubtract or divide types. But we can try a series of substitutions,\nwhere we keep replacing \\code{x} on the right hand side with\n\\code{(1 + a*x)}, and use the distributive property. This leads to\nthe following series:\n\n\\begin{Verbatim}\n  x = 1 + a*x\n  x = 1 + a*(1 + a*x) = 1 + a + a*a*x\n  x = 1 + a + a*a*(1 + a*x) = 1 + a + a*a + a*a*a*x\n  ...\n  x = 1 + a + a*a + a*a*a + a*a*a*a...\n\\end{Verbatim}\nWe end up with an infinite sum of products (tuples), which can be\ninterpreted as: A list is either empty, \\code{1}; or a singleton,\n\\code{a}; or a pair, \\code{a*a}; or a triple, \\code{a*a*a};\netc\\ldots{} Well, that's exactly what a list is --- a string of\n\\code{a}s!\n\nThere's much more to lists than that, and we'll come back to them and\nother recursive data structures after we learn about functors and fixed\npoints.\n\nSolving equations with symbolic variables --- that's algebra! It's what\ngives these types their name: algebraic data types.\n\nFinally, I should mention one very important interpretation of the\nalgebra of types. Notice that a product of two types \\code{a} and\n\\code{b} must contain both a value of type \\code{a} \\emph{and} a\nvalue of type \\code{b}, which means both types must be inhabited. A\nsum of two types, on the other hand, contains either a value of type\n\\code{a} \\emph{or} a value of type \\code{b}, so it's enough if one\nof them is inhabited. Logical \\emph{and} and \\emph{or} also form a\nsemiring, and it too can be mapped into type theory:\n\n\\begin{longtable}[]{@{}ll@{}}\n  \\toprule\n  Logic                & Types\\tabularnewline\n  \\midrule\n  \\endhead\n  $\\mathit{false}$     & \\code{Void}\\tabularnewline\n  $\\mathit{true}$      & \\code{()}\\tabularnewline\n  $a \\mathbin{||} b$   & \\code{data Either a b = Left a | Right b}\\tabularnewline\n  $a \\mathbin{\\&\\&} b$ & \\code{(a, b)}\\tabularnewline\n  \\bottomrule\n\\end{longtable}\n\n\\noindent\nThis analogy goes deeper, and is the basis of the Curry-Howard\nisomorphism between logic and type theory. We'll come back to it when we\ntalk about function types.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Show the isomorphism between \\code{Maybe a} and\n        \\code{Either () a}.\n  \\item\n        Here's a sum type defined in Haskell:\n\n        \\begin{snip}{haskell}\ndata Shape = Circle Float\n           | Rect Float Float\n\\end{snip}\n        When we want to define a function like \\code{area} that acts on a\n        \\code{Shape}, we do it by pattern matching on the two constructors:\n\n        \\begin{snip}{haskell}\narea :: Shape -> Float\narea (Circle r) = pi * r * r\narea (Rect d h) = d * h\n\\end{snip}\n        Implement \\code{Shape} in C++ or Java as an interface and create two\n        classes: \\code{Circle} and \\code{Rect}. Implement \\code{area} as\n        a virtual function.\n  \\item\n        Continuing with the previous example: We can easily add a new function\n        \\code{circ} that calculates the circumference of a \\code{Shape}.\n        We can do it without touching the definition of \\code{Shape}:\n\n        \\begin{snip}{haskell}\ncirc :: Shape -> Float\ncirc (Circle r) = 2.0 * pi * r\ncirc (Rect d h) = 2.0 * (d + h)\n\\end{snip}\n        Add \\code{circ} to your C++ or Java implementation. What parts of\n        the original code did you have to touch?\n  \\item\n        Continuing further: Add a new shape, \\code{Square}, to\n        \\code{Shape} and make all the necessary updates. What code did you\n        have to touch in Haskell vs. C++ or Java? (Even if you're not a\n        Haskell programmer, the modifications should be pretty obvious.)\n  \\item\n        Show that $a + a = 2 \\times a$ holds for types (up to\n        isomorphism). Remember that $2$ corresponds to \\code{Bool},\n        according to our translation table.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet01.hs",
    "content": "data Maybe a = Nothing | Just a"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet02.hs",
    "content": "f :: a -> b"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet03.hs",
    "content": "f' :: Maybe a -> Maybe b\nf' Nothing = Nothing\nf' (Just x) = Just (f x)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet04.hs",
    "content": "fmap :: (a -> b) -> (Maybe a -> Maybe b)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet05.hs",
    "content": "fmap :: (a -> b) -> Maybe a -> Maybe b"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet06.hs",
    "content": "fmap _ Nothing = Nothing\nfmap f (Just x) = Just (f x)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet07.hs",
    "content": "id x = x"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet08.hs",
    "content": "fmap id = id"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet09.hs",
    "content": "fmap (g . f) = fmap g . fmap f"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet10.hs",
    "content": "class Eq a where\n    (==) :: a -> a -> Bool"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet11.hs",
    "content": "data Point = Pt Float Float"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet12.hs",
    "content": "instance Eq Point where\n    (Pt x y) == (Pt x' y') = x == x' && y == y'"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet13.hs",
    "content": "class Functor f where\n    fmap :: (a -> b) -> f a -> f b"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet14.hs",
    "content": "instance Functor Maybe where\n    fmap _ Nothing = Nothing\n    fmap f (Just x) = Just (f x)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet15.hs",
    "content": "data List a = Nil | Cons a (List a)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet16.hs",
    "content": "fmap :: (a -> b) -> (List a -> List b)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet17.hs",
    "content": "fmap f (Cons x t) = Cons (f x) (fmap f t)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet18.hs",
    "content": "instance Functor List where\n    fmap _ Nil = Nil\n    fmap f (Cons x t) = Cons (f x) (fmap f t)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet19.hs",
    "content": "(->) a b"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet20.hs",
    "content": "(->) a"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet21.hs",
    "content": "fmap :: (a -> b) -> (r -> a) -> (r -> b)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet22.hs",
    "content": "instance Functor ((->) r) where\n    fmap f g = f . g"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet23.hs",
    "content": "fmap f g = (.) f g"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet24.hs",
    "content": "fmap = (.)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet25.hs",
    "content": "nats :: [Integer]\nnats = [1..]"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet26.hs",
    "content": "data Const c a = Const c"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet27.hs",
    "content": "fmap :: (a -> b) -> Const c a -> Const c b"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet28.hs",
    "content": "instance Functor (Const c) where\n    fmap _ (Const v) = Const v"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet29.hs",
    "content": "maybeTail :: [a] -> Maybe [a]\nmaybeTail [] = Nothing\nmaybeTail (x:xs) = Just xs"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet30.hs",
    "content": "square x = x * x\n\nmis :: Maybe [Int]\nmis = Just [1, 2, 3]\n\nmis2 = fmap (fmap square) mis"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet31.hs",
    "content": "mis2 = (fmap . fmap) square mis"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet32.hs",
    "content": "fmap :: (a -> b) -> (f a -> f b)"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet33.hs",
    "content": "square :: Int -> Int"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet34.hs",
    "content": "[Int] -> [Int]"
  },
  {
    "path": "src/content/1.7/code/haskell/snippet35.hs",
    "content": "Maybe [Int] -> Maybe [Int]"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet01.ml",
    "content": "type 'a option =\n  | None\n  | Some of 'a\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet02.ml",
    "content": "module type AtoB = sig\n  type a\n  type b\n\n  val f : a -> b\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet03.ml",
    "content": "let f' f = function\n  | None -> None\n  | Some x -> Some (f x)\n;;\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet04.ml",
    "content": "module type Maybe_Functor = sig\n  type a\n  type b\n\n  val fmap : (a -> b) -> a option -> b option\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet05.ml",
    "content": "module type Maybe_Functor = sig\n  type a\n  type b\n\n  val fmap : (a -> b) -> a option -> b option\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet06.ml",
    "content": "let fmap f = function\n  | None -> None\n  | Some x -> Some (f x)\n;;\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet07.ml",
    "content": "let id x = x\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet08.ml",
    "content": "module Test_Functor_Id (F : Functor) = struct\n  open F\n\n  let test_id x = assert (fmap id x = x)\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet09.ml",
    "content": "module Test_Functor_Compose (F : Functor) = struct\n  open F\n\n  (* Compose *)\n  let ( <.> ) f g x = f (g x)\n\n  let test_compose f g x =\n    assert (fmap (f <.> g) x = fmap f (fmap g x))\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet10.ml",
    "content": "module type Eq = sig\n  type a\n\n  val ( == ) : a -> a -> bool\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet11.ml",
    "content": "type point = Pt of float * float\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet12.ml",
    "content": "module Point_Eq (E : Eq with type a = float) = struct\n  type a = point\n\n  let ( == ) (Pt (p1x, p1y)) (Pt (p2x, p2y)) =\n    E.(p1x == p2x) && E.(p2x == p2y)\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet13.ml",
    "content": "module type Functor = sig\n  type 'a t\n\n  val fmap : ('a -> 'b) -> 'a t -> 'b t\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet14.ml",
    "content": "module Option_Functor : Functor with type 'a t = 'a option = struct\n  type 'a t = 'a option\n\n  let fmap f = function\n    | None -> None\n    | Some x -> Some (f x)\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet15.ml",
    "content": "type 'a list =\n  | Nil\n  | Cons of 'a * 'a list\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet16.ml",
    "content": "module type List_Functor_Type = sig\n  type 'a t = 'a list\n\n  val fmap : ('a -> 'b) -> 'a list -> 'b list\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet17.ml",
    "content": "let rec fmap f = function\n  | Nil -> Nil\n  | Cons (x, xs) -> Cons (f x, fmap f xs)\n;;\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet18.ml",
    "content": "module List_Functor : Functor with type 'a t = 'a list = struct\n  type 'a t = 'a list\n\n  let rec fmap f = function\n    | Nil -> Nil\n    | Cons (x, xs) -> Cons (f x, fmap f xs)\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet19.ml",
    "content": "type ('a, 'b) t = 'a -> 'b\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet20.ml",
    "content": "module type T = sig\n  type t\nend\n\nmodule Partially_Applied_FunctionType (T : T) = struct\n  type 'b t = T.t -> 'b\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet21.ml",
    "content": "module type Reader_Fmap_Example = sig\n  val fmap : ('a -> 'b) -> ('r -> 'a) -> 'r -> 'b\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet22.ml",
    "content": "module Reader_Functor (T : T) : Functor = struct\n  type 'a t = T.t -> 'a\n\n  let fmap f ra r = f (ra r)\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet23.ml",
    "content": "let fmap f g = compose f g\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet24.ml",
    "content": "let fmap : ('a -> 'b) -> ('r -> 'a) -> 'r -> 'b = compose\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet25.ml",
    "content": "let nats = Caml.Stream.from (fun i -> Some (i + 1))\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet26.ml",
    "content": "type ('c, 'a) const = Const of 'c\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet27.ml",
    "content": "module type Const_Functor_Example = sig\n  val fmap : ('a -> 'b) -> ('c, 'a) const -> ('c, 'b) const\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet28.ml",
    "content": "module Const_Functor (T : T) : Functor = struct\n  type 'a t = (T.t, 'a) const\n\n  let fmap f (Const c) = Const c (* or even let fmap _ c = c *)\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet29.ml",
    "content": "let maybe_tail = function\n  | [] -> None\n  | _ :: xs -> Some xs\n;;\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet30.ml",
    "content": "let square x = x * x\nlet mis = Some (Cons (1, Cons (2, Cons (3, Nil))))\nlet mis2 = Option_Functor.fmap (List_Functor.fmap square) mis\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet31.ml",
    "content": "let fmapO = Option_Functor.fmap\nlet fmapL = List_Functor.fmap\nlet fmapC f l = (compose fmapO fmapL) f l\nlet mis2 = fmapC square mis\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet32.ml",
    "content": "module type Fmap_Alt_Sig_Example = sig\n  type 'a t\n\n  val fmap : ('a -> 'b) -> 'a t -> 'b t\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet33.ml",
    "content": "module type Square_Signature = sig\n  val square : int -> int\nend\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet34.ml",
    "content": "int list -> int list\n"
  },
  {
    "path": "src/content/1.7/code/ocaml/snippet35.ml",
    "content": "int list option -> int list option\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet01.re",
    "content": "let compose = (f, g, x) => f(g(x));\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet02.re",
    "content": "type option('a) =\n  | None\n  | Some('a);\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet03.re",
    "content": "module type AtoB = {\n  type a;\n  type b;\n  \n  let f: a => b;\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet04.re",
    "content": "let f' = f =>\n  fun\n  | None => None\n  | Some(x) => Some(f(x));\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet05.re",
    "content": "module type Maybe_Functor = {\n  type a;\n  type b;\n  \n  let fmap: (a => b, option(a)) => option(b);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet06.re",
    "content": "module type Maybe_Functor = {\n  type a;\n  type b;\n  \n  let fmap: (a => b, option(a)) => option(b);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet07.re",
    "content": "let fmap = f =>\n  fun\n  | None => None\n  | Some(x) => Some(f(x));\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet08.re",
    "content": "let id = x => x;\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet09.re",
    "content": "module Test_Functor_Id = (F: Functor) => {\n  open F;\n  \n  let test_id = x => assert(fmap(id, x) == x);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet10.re",
    "content": "module Test_Functor_Compose = (F: Functor) => {\n  open F;\n\n  /* Compose */\n  let (<.>) = (f, g, x) => f(g(x));\n  \n  let test_compose = (f, g, x) =>\n    assert(fmap(f <.> g, x) == fmap(f, fmap(g, x)));\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet11.re",
    "content": "module type Eq = {\n  type a;\n  \n  let (===): (a, a) => bool;\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet12.re",
    "content": "type point =\n  | Pt(float, float);\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet13.re",
    "content": "module Point_Eq = (E: Eq with type a = float) => {\n  type a = point;\n  \n  let (===) = (Pt(p1x, p1y), Pt(p2x, p2y)) =>\n    E.(p1x === p2x) && E.(p2x === p2y);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet14.re",
    "content": "module type Functor = {\n  type t('a);\n  \n  let fmap: ('a => 'b, t('a)) => t('b);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet15.re",
    "content": "module Option_Functor: Functor with type t('a) = option('a) = {\n  type t('a) = option('a);\n  \n  let fmap = f =>\n    fun\n    | None => None\n    | Some(x) => Some(f(x));\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet16.re",
    "content": "type list('a) =\n  | Nil\n  | Cons('a, list('a));\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet17.re",
    "content": "module type List_Functor_Type = {\n  type t('a) = list('a);\n  \n  let fmap: ('a => 'b, list('a)) => list('b);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet18.re",
    "content": "let rec fmap = f =>\n  fun\n  | Nil => Nil\n  | Cons(x, xs) => Cons(f(x), fmap(f, xs));\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet19.re",
    "content": "module List_Functor: Functor with type t('a) = list('a) = {\n  type t('a) = list('a);\n  \n  let rec fmap = f =>\n    fun\n    | Nil => Nil\n    | Cons(x, xs) => Cons(f(x), fmap(f, xs));\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet20.re",
    "content": "type t('a, 'b) = 'a => 'b;\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet21.re",
    "content": "module type T = {type t;};\n\nmodule Partially_Applied_FunctionType = (T: T) => {\n  type t('b) = T.t => 'b;\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet22.re",
    "content": "module type Reader_Fmap_Example = {\n  let fmap: ('a => 'b, 'r => 'a, 'r) => 'b;\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet23.re",
    "content": "module Reader_Functor = (T: T) : Functor => {\n  type t('a) = T.t => 'a;\n  \n  let fmap = (f, ra, r) => f(ra(r));\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet24.re",
    "content": "let fmap: ('a => 'b, 'r => 'a, 'r) => 'b = (\n  compose: ('a => 'b, 'r => 'a, 'r) => 'b\n);\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet25.re",
    "content": "let nats = Caml.Stream.from(i => Some(i + 1));\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet26.re",
    "content": "type const('c, 'a) =\n  | Const('c);\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet27.re",
    "content": "module type Const_Functor_Example = {\n  let fmap: ('a => 'b, const('c, 'a)) => const('c, 'b);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet28.re",
    "content": "module Const_Functor = (T: T) : Functor => {\n  type t('a) = const(T.t, 'a);\n  \n  // or even let fmap = (_, c) => c;\n  let fmap = (f, Const(c)) => Const(c); \n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet29.re",
    "content": "let maybe_tail =\n  fun\n  | [] => None\n  | [_, ...xs] => Some(xs);\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet30.re",
    "content": "let square = x => x * x;\nlet mis = Some(Cons(1, Cons(2, Cons(3, Nil))));\nlet mis2 = Option_Functor.fmap(List_Functor.fmap(square), mis);\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet31.re",
    "content": "let fmapO = Option_Functor.fmap;\nlet fmapL = List_Functor.fmap;\nlet fmapC = (f, l) => (compose(fmapO, fmapL))(f, l);\nlet mis2 = fmapC(square, mis);\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet32.re",
    "content": "module type Fmap_Alt_Sig_Example = {\n  type t('a);\n  \n  let fmap: ('a => 'b, t('a)) => t('b);\n};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet33.re",
    "content": "module type Square_Signature = {let square: int => int;};\n"
  },
  {
    "path": "src/content/1.7/code/reason/snippet34.re",
    "content": "list(int) => list(int)"
  },
  {
    "path": "src/content/1.7/code/reason/snippet35.re",
    "content": "option(list(int)) => option(list(int))"
  },
  {
    "path": "src/content/1.7/code/scala/snippet01.scala",
    "content": "sealed trait Option[+A]\ncase object None extends Option[Nothing]\ncase class Some[A](a: A) extends Option[A]"
  },
  {
    "path": "src/content/1.7/code/scala/snippet02.scala",
    "content": "val f: A => B"
  },
  {
    "path": "src/content/1.7/code/scala/snippet03.scala",
    "content": "def f1[A, B]: Option[A] => Option[B] = {\n  case None => None\n  case Some(x) => Some(f(x))\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet04.scala",
    "content": "def fmap[A, B](f: A => B): (Option[A] => Option[B])"
  },
  {
    "path": "src/content/1.7/code/scala/snippet05.scala",
    "content": "def fmap[A, B](f: A => B)(fa: Option[A]): Option[B]"
  },
  {
    "path": "src/content/1.7/code/scala/snippet06.scala",
    "content": "def fmap[A, B](f: A => B): Option[A] => Option[B] = {\n  case None => None\n  case Some(x) => Some(f(x))\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet07.scala",
    "content": "def identity[A](x: A) = x"
  },
  {
    "path": "src/content/1.7/code/scala/snippet08.scala",
    "content": "fmap(identity) == identity"
  },
  {
    "path": "src/content/1.7/code/scala/snippet09.scala",
    "content": "fmap(g compose f) == fmap(g) compose fmap(f)"
  },
  {
    "path": "src/content/1.7/code/scala/snippet10.scala",
    "content": "trait Eq[A]{\n  def ===(x: A, y: A): Boolean\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet11.scala",
    "content": "case class Point(x: Float, y: Float)"
  },
  {
    "path": "src/content/1.7/code/scala/snippet12.scala",
    "content": "implicit val pointEq = new Eq[Point] {\n  def ===(a1: Point, a2: Point): Boolean =\n    a1.x == a2.x && a1.y == a2.y\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet13.scala",
    "content": "trait Functor[F[_]] {\n  def fmap[A, B](f: A => B)(fa: F[A]): F[B]\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet14.scala",
    "content": "implicit val optionFunctor = new Functor[Option] {\n  def fmap[A, B](f: A => B)(fa: Option[A]): Option[B] = fa match {\n    case None => None\n    case Some(x) => Some(f(x))\n  }\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet15.scala",
    "content": "sealed trait List[+E]\ncase object Nil extends List[Nothing]\ncase class Cons[E](h: E, t: List[E]) extends List[E]"
  },
  {
    "path": "src/content/1.7/code/scala/snippet16.scala",
    "content": "def fmap[A, B](f: A => B): (List[A] => List[B])"
  },
  {
    "path": "src/content/1.7/code/scala/snippet17.scala",
    "content": "def fmap[A, B](f: A => B)(fa: List[A]): List[B] = fa match {\n  case Cons(x, t) => Cons(f(x), fmap(f)(t))\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet18.scala",
    "content": "implicit val listFunctor = new Functor[List] {\n  def fmap[A, B](f: A => B)(fa: List[A]): List[B] = fa match {\n    case Nil => Nil\n    case Cons(x, t) => Cons(f(x), fmap(f)(t))\n  }\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet19.scala",
    "content": "Function1[A, B]\n// or\nA => B"
  },
  {
    "path": "src/content/1.7/code/scala/snippet20.scala",
    "content": "// with the Kind Projector plugin\nFunction1[A, ?] or A => ?"
  },
  {
    "path": "src/content/1.7/code/scala/snippet21.scala",
    "content": "def fmap[A, B](f: A => B)(g: R => A): (R => B)"
  },
  {
    "path": "src/content/1.7/code/scala/snippet22.scala",
    "content": "// with the Kind Projector plugin:\nimplicit def function1Functor[R] = new Functor[R => ?] {\n  def fmap[A, B](f: A => B)(g: R => A): (R => B) =\n    f compose g\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet23.scala",
    "content": "def fmap[A, B]: (A => B) => (R => A) => (R => B) =\n  f => g => f compose g"
  },
  {
    "path": "src/content/1.7/code/scala/snippet24.scala",
    "content": "def fmap[A, B]: (A => B) => (R => A) => (R => B) =\n  _ compose"
  },
  {
    "path": "src/content/1.7/code/scala/snippet25.scala",
    "content": "// LazyLists are supported as of Scala 2.13\ndef nats: LazyList[Int] = LazyList.from(1)\n"
  },
  {
    "path": "src/content/1.7/code/scala/snippet26.scala",
    "content": "case class Const[C, A](v: C)"
  },
  {
    "path": "src/content/1.7/code/scala/snippet27.scala",
    "content": "def fmap[A, B](f: A => B)(ca: Const[C, A]): Const[C, B]"
  },
  {
    "path": "src/content/1.7/code/scala/snippet28.scala",
    "content": "implicit def constFunctor[C] = new Functor[Const[C, ?]] {\n  def fmap[A, B](f: A => B)(ca: Const[C, A]): Const[C, B] =\n    Const(ca.v)\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet29.scala",
    "content": "def maybeTail[A]: List[A] => Option[List[A]] = {\n  case Nil => None\n  case Cons(x, xs) => Some(xs)\n}"
  },
  {
    "path": "src/content/1.7/code/scala/snippet30.scala",
    "content": "def square: Int => Int = x => x * x\n\nval mis: Option[List[Int]] =\n  Some(Cons(1, Cons(2, Cons(3, Nil))))\n\nval mis2 = optionFunctor.\n  fmap(listFunctor.fmap(square))(mis)"
  },
  {
    "path": "src/content/1.7/code/scala/snippet31.scala",
    "content": "def fmapO[A, B]: (A => B) => Option[A] => Option[B] =\n  optionFunctor.fmap\ndef fmapL[A, B]: (A => B) => List[A] => List[B] =\n  listFunctor.fmap\ndef fmapC[A, B]: (A => B) => Option[List[A]] => Option[List[B]] =\n  fmapO.compose(fmapL)\n\nval mis2 = fmapC(square)(mis)"
  },
  {
    "path": "src/content/1.7/code/scala/snippet32.scala",
    "content": "def fmap[F[_], A, B]: (A => B) => (F[A] => F[B])"
  },
  {
    "path": "src/content/1.7/code/scala/snippet33.scala",
    "content": "def square: Int => Int"
  },
  {
    "path": "src/content/1.7/code/scala/snippet34.scala",
    "content": "List[Int] => List[Int]"
  },
  {
    "path": "src/content/1.7/code/scala/snippet35.scala",
    "content": "Option[List[Int]] => Option[List[Int]]"
  },
  {
    "path": "src/content/1.7/functors.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{A}{t the risk of sounding} like a broken record, I will say this about\nfunctors: A functor is a very simple but powerful idea. Category theory\nis just full of those simple but powerful ideas. A functor is a mapping\nbetween categories. Given two categories, $\\cat{C}$ and $\\cat{D}$, a functor $F$ maps\nobjects in $\\cat{C}$ to objects in $\\cat{D}$ --- it's a function on objects. If $a$\nis an object in $\\cat{C}$, we'll write its image in $\\cat{D}$ as $F a$ (no\nparentheses). But a category is not just objects --- it's objects and\nmorphisms that connect them. A functor also maps morphisms --- it's a\nfunction on morphisms. But it doesn't map morphisms willy-nilly --- it\npreserves connections. So if a morphism $f$ in $\\cat{C}$ connects object\n$a$ to object $b$,\n\\[f \\Colon a \\to b\\]\nthe image of $f$ in $\\cat{D}$, $F f$, will connect the image of\n$a$ to the image of $b$:\n\\[F f \\Colon F a \\to F b\\]\n\n(This is a mixture of mathematical and Haskell notation that hopefully\nmakes sense by now. I won't use parentheses when applying functors to\nobjects or morphisms.)\n\n\\begin{figure}[H]\n  \\centering\\includegraphics[width=0.3\\textwidth]{images/functor.jpg}\n\\end{figure}\n\n\\noindent\nAs you can see, a\nfunctor preserves the structure of a category: what's connected in one\ncategory will be connected in the other category. But there's something\nmore to the structure of a category: there's also the composition of\nmorphisms. If $h$ is a composition of $f$ and $g$:\n\\[h = g \\circ f\\]\nwe want its image under $F$ to be a composition of the images of $f$\nand $g$:\n\\[F h = F g \\circ F f\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/functorcompos.jpg}\n\\end{figure}\n\n\\noindent\nFinally, we want all identity morphisms in $\\cat{C}$ to be mapped to identity morphisms in\n$\\cat{D}$:\n\\[F \\idarrow[a] = \\idarrow[F a]\\]\n\n\\noindent\nHere, $\\idarrow[a]$ is the identity at the object $a$,\nand $\\idarrow[F a]$ the identity at $F a$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/functorid.jpg}\n\\end{figure}\n\n\\noindent\nNote that these conditions make functors much more restrictive than regular functions.\nFunctors must preserve the structure of a category. If you picture a\ncategory as a collection of objects held together by a network of\nmorphisms, a functor is not allowed to introduce any tears into this\nfabric. It may smash objects together, it may glue multiple morphisms\ninto one, but it may never break things apart. This no-tearing\nconstraint is similar to the continuity condition you might know from\ncalculus. In this sense functors are ``continuous'' (although there\nexists an even more restrictive notion of continuity for functors). Just\nlike functions, functors may do both collapsing and embedding. The\nembedding aspect is more prominent when the source category is much\nsmaller than the target category. In the extreme, the source can be the\ntrivial singleton category --- a category with one object and one\nmorphism (the identity). A functor from the singleton category to any\nother category simply selects an object in that category. This is fully\nanalogous to the property of morphisms from singleton sets selecting\nelements in target sets. The maximally collapsing functor is called the\nconstant functor $\\Delta_c$. It maps every object in the source\ncategory to one selected object $c$ in the target category. It also\nmaps every morphism in the source category to the identity morphism\n$\\idarrow[c]$. It acts like a black hole, compacting\neverything into one singularity. We'll see more of this functor when we\ndiscuss limits and colimits.\n\n\\section{Functors in Programming}\n\nLet's get down to earth and talk about programming. We have our category\nof types and functions. We can talk about functors that map this\ncategory into itself --- such functors are called endofunctors. So\nwhat's an endofunctor in the category of types? First of all, it maps\ntypes to types. We've seen examples of such mappings, maybe without\nrealizing that they were just that. I'm talking about definitions of\ntypes that were parameterized by other types. Let's see a few examples.\n\n\\subsection{The Maybe Functor}\n\nThe definition of \\code{Maybe} is a mapping from type \\code{a} to\ntype \\code{Maybe a}:\n\n\\src{snippet01}\nHere's an important subtlety: \\code{Maybe} itself is not a type, it's\na \\emph{type constructor}. You have to give it a type argument, like\n\\code{Int} or \\code{Bool}, in order to turn it into a type.\n\\code{Maybe} without any argument represents a function on types. But\ncan we turn \\code{Maybe} into a functor? (From now on, when I speak of\nfunctors in the context of programming, I will almost always mean\nendofunctors.) A functor is not only a mapping of objects (here, types)\nbut also a mapping of morphisms (here, functions). For any function from\n\\code{a} to \\code{b}:\n\n\\src{snippet02}\nwe would like to produce a function from \\code{Maybe a} to\n\\code{Maybe b}. To define such a function, we'll have two cases to\nconsider, corresponding to the two constructors of \\code{Maybe}. The\n\\code{Nothing} case is simple: we'll just return \\code{Nothing}\nback. And if the argument is \\code{Just}, we'll apply the function\n\\code{f} to its contents. So the image of \\code{f} under\n\\code{Maybe} is the function:\n\n\\src{snippet03}\n(By the way, in Haskell you can use apostrophes in variables names,\nwhich is very handy in cases like these.) In Haskell, we implement the\nmorphism-mapping part of a functor as a higher order function called\n\\code{fmap}. In the case of \\code{Maybe}, it has the following\nsignature:\n\n\\src{snippet04}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/functormaybe.jpg}\n\\end{figure}\n\n\\noindent\nWe often say\nthat \\code{fmap} \\emph{lifts} a function. The lifted function acts on\n\\code{Maybe} values. As usual, because of currying, this signature may\nbe interpreted in two ways: as a function of one argument --- which\nitself is a function \\code{(a -> b)} --- returning a\nfunction \\code{(Maybe a -> Maybe b)}; or as a\nfunction of two arguments returning \\code{Maybe b}:\n\n\\src{snippet05}\nBased on our previous discussion, this is how we implement \\code{fmap}\nfor \\code{Maybe}:\n\n\\src{snippet06}\nTo show that the type constructor \\code{Maybe} together with the\nfunction \\code{fmap} form a functor, we have to prove that\n\\code{fmap} preserves identity and composition. These are called ``the\nfunctor laws,'' but they simply ensure the preservation of the structure\nof the category.\n\n\\subsection{Equational Reasoning}\n\nTo prove the functor laws, I will use \\newterm{equational reasoning}, which\nis a common proof technique in Haskell. It takes advantage of the fact\nthat Haskell functions are defined as equalities: the left hand side\nequals the right hand side. You can always substitute one for another,\npossibly renaming variables to avoid name conflicts. Think of this as\neither inlining a function, or the other way around, refactoring an\nexpression into a function. Let's take the identity function as an\nexample:\n\n\\src{snippet07}\nIf you see, for instance, \\code{id y} in some expression, you can\nreplace it with \\code{y} (inlining). Further, if you see \\code{id}\napplied to an expression, say \\code{id (y + 2)}, you can replace it\nwith the expression itself \\code{(y + 2)}. And this substitution\nworks both ways: you can replace any expression \\code{e} with\n\\code{id e} (refactoring). If a function is defined by pattern\nmatching, you can use each sub-definition independently. For instance,\ngiven the above definition of \\code{fmap} you can replace\n\\code{fmap f Nothing} with \\code{Nothing}, or the other way\naround. Let's see how this works in practice. Let's start with the\npreservation of identity:\n\n\\src{snippet08}\nThere are two cases to consider: \\code{Nothing} and \\code{Just}.\nHere's the first case (I'm using Haskell pseudo-code to transform the\nleft hand side to the right hand side):\n\n\\begin{snip}{haskell}\n  fmap id Nothing\n= { definition of fmap }\n  Nothing\n= { definition of id }\n  id Nothing\n\\end{snip}\nNotice that in the last step I used the definition of \\code{id}\nbackwards. I replaced the expression \\code{Nothing} with\n\\code{id\\ Nothing}. In practice, you carry out such proofs by\n``burning the candle at both ends,'' until you hit the same expression\nin the middle --- here it was \\code{Nothing}. The second case is also\neasy:\n\n\\begin{snip}{haskell}\n  fmap id (Just x)\n= { definition of fmap }\n  Just (id x)\n= { definition of id }\n  Just x\n= { definition of id }\n  id (Just x)\n\\end{snip}\nNow, let's show that \\code{fmap} preserves composition:\n\n\\src{snippet09}\nFirst the \\code{Nothing} case:\n\n\\begin{snip}{haskell}\n  fmap (g . f) Nothing\n= { definition of fmap }\n  Nothing\n= { definition of fmap }\n  fmap g Nothing\n= { definition of fmap }\n  fmap g (fmap f Nothing)\n\\end{snip}\nAnd then the \\code{Just} case:\n\n\\begin{snip}{haskell}\n  fmap (g . f) (Just x)\n= { definition of fmap }\n  Just ((g . f) x)\n= { definition of composition }\n  Just (g (f x))\n= { definition of fmap }\n  fmap g (Just (f x))\n= { definition of fmap }\n  fmap g (fmap f (Just x))\n= { definition of composition }\n  (fmap g . fmap f) (Just x)\n\\end{snip}\nIt's worth stressing that equational reasoning doesn't work for C++\nstyle ``functions'' with side effects. Consider this code:\n\n\\begin{snip}{cpp}\nint square(int x) {\n    return x * x;\n}\n\nint counter() {\n    static int c = 0;\n    return c++;\n}\n\ndouble y = square(counter());\n\\end{snip}\nUsing equational reasoning, you would be able to inline \\code{square}\nto get:\n\n\\begin{snip}{cpp}\ndouble y = counter() * counter();\n\\end{snip}\nThis is definitely not a valid transformation, and it will not produce\nthe same result. Despite that, the C++ compiler will try to use\nequational reasoning if you implement \\code{square} as a macro, with\ndisastrous results.\n\n\\subsection{Optional}\n\nFunctors are easily expressed in Haskell, but they can be defined in any\nlanguage that supports generic programming and higher-order functions.\nLet's consider the C++ analog of \\code{Maybe}, the template type\n\\code{optional}. Here's a sketch of the implementation (the actual\nimplementation is much more complex, dealing with various ways the\nargument may be passed, with copy semantics, and with the resource\nmanagement issues characteristic of C++):\n\n\\begin{snip}{cpp}\ntemplate<typename T>\nclass optional {\n    bool _isValid; // the tag\n    T _v;\npublic:\n    optional()    : _isValid(false) {}        // Nothing\n    optional(T x) : _isValid(true) , _v(x) {} // Just\n    bool isValid() const { return _isValid; }\n    T val() const { return _v; } };\n\\end{snip}\nThis template provides one part of the definition of a functor: the\nmapping of types. It maps any type \\code{T} to a new type\n\\code{optional<T>}. Let's define its action on\nfunctions:\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B>\nstd::function<optional<B>(optional<A>)>\nfmap(std::function<B(A)> f) {\n    return [f](optional<A> opt) {\n        if (!opt.isValid())\n            return optional<B>{};\n        else\n            return optional<B>{ f(opt.val()) };\n    };\n}\n\\end{snip}\nThis is a higher order function, taking a function as an argument and\nreturning a function. Here's the uncurried version of it:\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B>\noptional<B> fmap(std::function<B(A)> f, optional<A> opt) {\n    if (!opt.isValid())\n        return optional<B>{};\n    else\n        return optional<B>{ f(opt.val()) };\n}\n\\end{snip}\nThere is also an option of making \\code{fmap} a template method of\n\\code{optional}. This embarrassment of choices makes abstracting the\nfunctor pattern in C++ a problem. Should functor be an interface to\ninherit from (unfortunately, you can't have template virtual functions)?\nShould it be a curried or an uncurried free template function? Can the\nC++ compiler correctly infer the missing types, or should they be\nspecified explicitly? Consider a situation where the input function\n\\code{f} takes an \\code{int} to a \\code{bool}. How will the\ncompiler figure out the type of \\code{g}:\n\n\\begin{snip}{cpp}\nauto g = fmap(f);\n\\end{snip}\nespecially if, in the future, there are multiple functors overloading\n\\code{fmap}? (We'll see more functors soon.)\n\n\\subsection{Typeclasses}\n\nSo how does Haskell deal with abstracting the functor? It uses the\ntypeclass mechanism. A typeclass defines a family of types that support\na common interface. For instance, the class of objects that support\nequality is defined as follows:\n\n\\src{snippet10}\nThis definition states that type \\code{a} is of the class \\code{Eq}\nif it supports the operator \\code{(==)} that takes two arguments of\ntype \\code{a} and returns a \\code{Bool}. If you want to tell Haskell\nthat a particular type is \\code{Eq}, you have to declare it an\n\\newterm{instance} of this class and provide the implementation of\n\\code{(==)}. For example, given the definition of a 2D \\code{Point}\n(a product type of two \\code{Float}s):\n\n\\src{snippet11}\nyou can define the equality of points:\n\n\\src{snippet12}\nHere I used the operator \\code{(==)} (the one I'm defining) in the\ninfix position between the two patterns \\code{(Pt x y)} and\n\\code{(Pt x' y')}. The body of the function follows the\nsingle equal sign. Once \\code{Point} is declared an instance of\n\\code{Eq}, you can directly compare points for equality. Notice that,\nunlike in C++ or Java, you don't have to specify the \\code{Eq} class\n(or interface) when defining \\code{Point} --- you can do it later in\nclient code. Typeclasses are also Haskell's only mechanism for\noverloading functions (and operators). We will need that for overloading\n\\code{fmap} for different functors. There is one complication, though:\na functor is not defined as a type but as a mapping of types, a type\nconstructor. We need a typeclass that's not a family of types, as was\nthe case with \\code{Eq}, but a family of type constructors.\nFortunately a Haskell typeclass works with type constructors as well as\nwith types. So here's the definition of the \\code{Functor} class:\n\n\\src{snippet13}\nIt stipulates that \\code{f} is a \\code{Functor} if there exists a\nfunction \\code{fmap} with the specified type signature. The lowercase\n\\code{f} is a type variable, similar to type variables \\code{a} and\n\\code{b}. The compiler, however, is able to deduce that it represents\na type constructor rather than a type by looking at its usage: acting on\nother types, as in \\code{f a} and \\code{f b}. Accordingly, when\ndeclaring an instance of \\code{Functor}, you have to give it a type\nconstructor, as is the case with \\code{Maybe}:\n\n\\src{snippet14}\nBy the way, the \\code{Functor} class, as well as its instance\ndefinitions for a lot of simple data types, including \\code{Maybe},\nare part of the standard Prelude library.\n\n\\subsection{Functor in C++}\n\nCan we try the same approach in C++? A type constructor corresponds to a\ntemplate class, like \\code{optional}, so by analogy, we would\nparameterize \\code{fmap} with a \\newterm{template template parameter}\n\\code{F}. This is the syntax for it:\n\n\\begin{snip}{cpp}\ntemplate<template<typename> F, typename A, typename B>\nF<B> fmap(std::function<B(A)>, F<A>);\n\\end{snip}\nWe would like to be able to specialize this template for different\nfunctors. Unfortunately, there is a prohibition against partial\nspecialization of template functions in C++. You can't write:\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B>\noptional<B> fmap<optional>(std::function<B(A)> f, optional<A> opt)\n\\end{snip}\nInstead, we have to fall back on function overloading, which brings us\nback to the original definition of the uncurried \\code{fmap}:\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B>\noptional<B> fmap(std::function<B(A)> f, optional<A> opt) {\n    if (!opt.isValid())\n        return optional<B>{};\n    else\n        return optional<B>{ f(opt.val()) };\n}\n\\end{snip}\nThis definition works, but only because the second argument of\n\\code{fmap} selects the overload. It totally ignores the more generic\ndefinition of \\code{fmap}.\n\n\\subsection{The List Functor}\n\nTo get some intuition as to the role of functors in programming, we need\nto look at more examples. Any type that is parameterized by another type\nis a candidate for a functor. Generic containers are parameterized by\nthe type of the elements they store, so let's look at a very simple\ncontainer, the list:\n\n\\src{snippet15}\nWe have the type constructor \\code{List}, which is a mapping from any\ntype \\code{a} to the type \\code{List a}. To show that \\code{List}\nis a functor we have to define the lifting of functions: Given a\nfunction \\code{a -> b} define a function\n\\code{List a -> List b}:\n\n\\src{snippet16}\nA function acting on \\code{List a} must consider two cases\ncorresponding to the two list constructors. The \\code{Nil} case is\ntrivial --- just return \\code{Nil} --- there isn't much you can do\nwith an empty list. The \\code{Cons} case is a bit tricky, because it\ninvolves recursion. So let's step back for a moment and consider what we\nare trying to do. We have a list of \\code{a}, a function \\code{f}\nthat turns \\code{a} to \\code{b}, and we want to generate a list of\n\\code{b}. The obvious thing is to use \\code{f} to turn each element\nof the list from \\code{a} to \\code{b}. How do we do this in\npractice, given that a (non-empty) list is defined as the \\code{Cons}\nof a head and a tail? We apply \\code{f} to the head and apply the\nlifted (\\code{fmap}ped) \\code{f} to the tail. This is a recursive\ndefinition, because we are defining lifted \\code{f} in terms of lifted\n\\code{f}:\n\n\\src{snippet17}\nNotice that, on the right hand side, \\code{fmap f} is applied to a\nlist that's shorter than the list for which we are defining it --- it's\napplied to its tail. We recurse towards shorter and shorter lists, so we\nare bound to eventually reach the empty list, or \\code{Nil}. But as\nwe've decided earlier, \\code{fmap f} acting on \\code{Nil} returns\n\\code{Nil}, thus terminating the recursion. To get the final result,\nwe combine the new head \\code{(f x)} with the new tail\n\\code{(fmap f t)} using the \\code{Cons} constructor. Putting it\nall together, here's the instance declaration for the list functor:\n\n\\src{snippet18}\nIf you are more comfortable with C++, consider the case of a\n\\code{std::vector}, which could be considered the most generic C++\ncontainer. The implementation of \\code{fmap} for \\code{std::vector}\nis just a thin encapsulation of \\code{std::transform}:\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B>\nstd::vector<B> fmap(std::function<B(A)> f, std::vector<A> v) {\n    std::vector<B> w;\n    std::transform( std::begin(v)\n                  , std::end(v)\n                  , std::back_inserter(w)\n                  , f);\n    return w;\n}\n\\end{snip}\nWe can use it, for instance, to square the elements of a sequence of\nnumbers:\n\n\\begin{snip}{cpp}\nstd::vector<int> v{ 1, 2, 3, 4 };\nauto w = fmap([](int i) { return i*i; }, v);\nstd::copy( std::begin(w)\n         , std::end(w)\n         , std::ostream_iterator(std::cout, \", \"));\n\\end{snip}\nMost C++ containers are functors by virtue of implementing iterators\nthat can be passed to \\code{std::transform}, which is the more\nprimitive cousin of \\code{fmap}. Unfortunately, the simplicity of a\nfunctor is lost under the usual clutter of iterators and temporaries\n(see the implementation of \\code{fmap} above). I'm happy to say that\nthe new proposed C++ range library makes the functorial nature of ranges\nmuch more pronounced.\n\n\\subsection{The Reader Functor}\n\nNow that you might have developed some intuitions --- for instance,\nfunctors being some kind of containers --- let me show you an example\nwhich at first sight looks very different. Consider a mapping of type\n\\code{a} to the type of a function returning \\code{a}. We haven't\nreally talked about function types in depth --- the full categorical\ntreatment is coming --- but we have some understanding of those as\nprogrammers. In Haskell, a function type is constructed using the arrow\ntype constructor \\code{(->)} which takes two types: the\nargument type and the result type. You've already seen it in infix form,\n\\code{a -> b}, but it can equally well be used in prefix\nform, when parenthesized:\n\n\\src{snippet19}\nJust like with regular functions, type functions of more than one\nargument can be partially applied. So when we provide just one type\nargument to the arrow, it still expects another one. That's why:\n\n\\src{snippet20}\nis a type constructor. It needs one more type \\code{b} to produce a\ncomplete type \\code{a -> b}. As it stands, it defines a\nwhole family of type constructors parameterized by \\code{a}. Let's see\nif this is also a family of functors. Dealing with two type parameters\ncan get a bit confusing, so let's do some renaming. Let's call the\nargument type \\code{r} and the result type \\code{a}, in line with\nour previous functor definitions. So our type constructor takes any type\n\\code{a} and maps it into the type \\code{r -> a}. To show\nthat it's a functor, we want to lift a function\n\\code{a -> b} to a function that takes\n\\code{r -> a} and returns \\code{r -> b}. These\nare the types that are formed using the type constructor\n\\code{(->) r} acting on, respectively, \\code{a} and\n\\code{b}. Here's the type signature of \\code{fmap} applied to this\ncase:\n\n\\src{snippet21}\nWe have to solve the following puzzle: given a function\n\\code{f :: a -> b} and a function\n\\code{g :: r -> a}, create a function\n\\code{r -> b}. There is only one way we can compose the two\nfunctions, and the result is exactly what we need. So here's the\nimplementation of our \\code{fmap}:\n\n\\src{snippet22}\nIt just works! If you like terse notation, this definition can be\nreduced further by noticing that composition can be rewritten in prefix\nform:\n\n\\src{snippet23}\nand the arguments can be omitted to yield a direct equality of two\nfunctions:\n\n\\src{snippet24}\nThis combination of the type constructor \\code{(->) r}\nwith the above implementation of \\code{fmap} is called the reader\nfunctor.\n\n\\section{Functors as Containers}\n\nWe've seen some examples of functors in programming languages that\ndefine general-purpose containers, or at least objects that contain some\nvalue of the type they are parameterized over. The reader functor seems\nto be an outlier, because we don't think of functions as data. But we've\nseen that pure functions can be memoized, and function execution can be\nturned into table lookup. Tables are data. Conversely, because of\nHaskell's laziness, a traditional container, like a list, may actually\nbe implemented as a function. Consider, for instance, an infinite list\nof natural numbers, which can be compactly defined as:\n\n\\src{snippet25}\nIn the first line, a pair of square brackets is Haskell's built-in\ntype constructor for lists. In the second line, square brackets are used\nto create a list literal. Obviously, an infinite list like this cannot\nbe stored in memory. The compiler implements it as a function that\ngenerates \\code{Integer}s on demand. Haskell effectively blurs the\ndistinction between data and code. A list could be considered a\nfunction, and a function could be considered a table that maps arguments\nto results. The latter can even be practical if the domain of the\nfunction is finite and not too large. It would not be practical,\nhowever, to implement \\code{strlen} as table lookup, because there are\ninfinitely many different strings. As programmers, we don't like\ninfinities, but in category theory you learn to eat infinities for\nbreakfast. Whether it's a set of all strings or a collection of all\npossible states of the Universe, past, present, and future --- we can\ndeal with it! So I like to think of the functor object (an object of the\ntype generated by an endofunctor) as containing a value or values of the\ntype over which it is parameterized, even if these values are not\nphysically present there. One example of a functor is a C++\n\\code{std::future}, which may at some point contain a value, but it's\nnot guaranteed it will; and if you want to access it, you may block\nwaiting for another thread to finish execution. Another example is a\nHaskell \\code{IO} object, which may contain user input, or the future\nversions of our Universe with ``Hello World!'' displayed on the monitor.\nAccording to this interpretation, a functor object is something that may\ncontain a value or values of the type it's parameterized upon. Or it may\ncontain a recipe for generating those values. We are not at all\nconcerned about being able to access the values --- that's totally\noptional, and outside of the scope of the functor. All we are interested\nin is to be able to manipulate those values using functions. If the\nvalues can be accessed, then we should be able to see the results of\nthis manipulation. If they can't, then all we care about is that the\nmanipulations compose correctly and that the manipulation with an\nidentity function doesn't change anything. Just to show you how much we\ndon't care about being able to access the values inside a functor\nobject, here's a type constructor that ignores completely its argument\n\\code{a}:\n\n\\src{snippet26}\nThe \\code{Const} type constructor takes two types, \\code{c} and\n\\code{a}. Just like we did with the arrow constructor, we are going to\npartially apply it to create a functor. The data constructor (also\ncalled \\code{Const}) takes just one value of type \\code{c}. It has\nno dependence on \\code{a}. The type of \\code{fmap} for this type\nconstructor is:\n\n\\src{snippet27}\nBecause the functor ignores its type argument, the implementation of\n\\code{fmap} is free to ignore its function argument --- the function\nhas nothing to act upon:\n\n\\src{snippet28}\nThis might be a little clearer in C++ (I never thought I would utter\nthose words!), where there is a stronger distinction between type\narguments --- which are compile-time --- and values, which are run-time:\n\n\\begin{snip}{cpp}\ntemplate<typename C, typename A>\nstruct Const {\n    Const(C v) : _v(v) {}\n    C _v;\n};\n\\end{snip}\nThe C++ implementation of \\code{fmap} also ignores the function\nargument and essentially re-casts the \\code{Const} argument without\nchanging its value:\n\n\\begin{snip}{cpp}\ntemplate<typename C, typename A, typename B>\nConst<C, B> fmap(std::function<B(A)> f, Const<C, A> c) {\n    return Const<C, B>{c._v};\n}\n\\end{snip}\nDespite its weirdness, the \\code{Const} functor plays an important\nrole in many constructions. In category theory, it's a special case of\nthe $\\Delta_c$ functor I mentioned earlier --- the endo-functor\ncase of a black hole. We'll be seeing more of it in the future.\n\n\\section{Functor Composition}\n\nIt's not hard to convince yourself that functors between categories\ncompose, just like functions between sets compose. A composition of two\nfunctors, when acting on objects, is just the composition of their\nrespective object mappings; and similarly when acting on morphisms.\nAfter jumping through two functors, identity morphisms end up as\nidentity morphisms, and compositions of morphisms finish up as\ncompositions of morphisms. There's really nothing much to it. In\nparticular, it's easy to compose endofunctors. Remember the function\n\\code{maybeTail}? I'll rewrite it using Haskell's built in\nimplementation of lists:\n\n\\src{snippet29}\n(The empty list constructor that we used to call \\code{Nil} is\nreplaced with the empty pair of square brackets \\code{{[}{]}}. The\n\\code{Cons} constructor is replaced with the infix operator \\code{:}\n(colon).) The result of \\code{maybeTail} is of a type that's a\ncomposition of two functors, \\code{Maybe} and \\code{{[}{]}}, acting\non \\code{a}. Each of these functors is equipped with its own version\nof \\code{fmap}, but what if we want to apply some function \\code{f}\nto the contents of the composite: a \\code{Maybe} list? We have to\nbreak through two layers of functors. We can use \\code{fmap} to break\nthrough the outer \\code{Maybe}. But we can't just send \\code{f}\ninside \\code{Maybe} because \\code{f} doesn't work on lists. We have\nto send \\code{(fmap f)} to operate on the inner list. For instance,\nlet's see how we can square the elements of a \\code{Maybe} list of\nintegers:\n\n\\src{snippet30}\nThe compiler, after analyzing the types, will figure out that, for the\nouter \\code{fmap}, it should use the implementation from the\n\\code{Maybe} instance, and for the inner one, the list functor\nimplementation. It may not be immediately obvious that the above code\nmay be rewritten as:\n\n\\src{snippet31}\nBut remember that \\code{fmap} may be considered a function of just one\nargument:\n\n\\src{snippet32}\nIn our case, the second \\code{fmap} in \\code{(fmap . fmap)} takes\nas its argument:\n\n\\src{snippet33}\nand returns a function of the type:\n\n\\src{snippet34}\nThe first \\code{fmap} then takes that function and returns a function:\n\n\\src{snippet35}\nFinally, that function is applied to \\code{mis}. So the composition of\ntwo functors is a functor whose \\code{fmap} is the composition of the\ncorresponding \\code{fmap}s. Going back to category theory: It's pretty\nobvious that functor composition is associative (the mapping of objects\nis associative, and the mapping of morphisms is associative). And there\nis also a trivial identity functor in every category: it maps every\nobject to itself, and every morphism to itself. So functors have all the\nsame properties as morphisms in some category. But what category would\nthat be? It would have to be a category in which objects are categories\nand morphisms are functors. It's a category of categories. But a\ncategory of \\emph{all} categories would have to include itself, and we\nwould get into the same kinds of paradoxes that made the set of all sets\nimpossible. There is, however, a category of all \\emph{small} categories\ncalled $\\Cat$ (which is big, so it can't be a member of itself). A\nsmall category is one in which objects form a set, as opposed to\nsomething larger than a set. Mind you, in category theory, even an\ninfinite uncountable set is considered ``small.'' I thought I'd mention\nthese things because I find it pretty amazing that we can recognize the\nsame structures repeating themselves at many levels of abstraction.\nWe'll see later that functors form categories as well.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Can we turn the \\code{Maybe} type constructor into a functor by\n        defining:\n\n        \\begin{snip}{haskell}\nfmap _ _ = Nothing\n\\end{snip}\n\n        which ignores both of its arguments? (Hint: Check the functor laws.)\n  \\item\n        Prove functor laws for the reader functor. Hint: it's really simple.\n  \\item\n        Implement the reader functor in your second favorite language (the\n        first being Haskell, of course).\n  \\item\n        Prove the functor laws for the list functor. Assume that the laws are\n        true for the tail part of the list you're applying it to (in other\n        words, use \\emph{induction}).\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet01.hs",
    "content": "class Bifunctor f where \n    bimap :: (a -> c) -> (b -> d) -> f a b -> f c d\n    bimap g h = first g . second h\n    first :: (a -> c) -> f a b -> f c b\n    first g = bimap g id\n    second :: (b -> d) -> f a b -> f a d\n    second = bimap id"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet02.hs",
    "content": "instance Bifunctor (,) where \n    bimap f g (x, y) = (f x, g y)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet03.hs",
    "content": "bimap :: (a -> c) -> (b -> d) -> (a, b) -> (c, d)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet04.hs",
    "content": "instance Bifunctor Either where\n    bimap f _ (Left x) = Left (f x)\n    bimap _ g (Right y) = Right (g y)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet05.hs",
    "content": "data Identity a = Identity a"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet06.hs",
    "content": "instance Functor Identity where\n    fmap f (Identity x) = Identity (f x)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet07.hs",
    "content": "data Maybe a = Nothing | Just a"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet08.hs",
    "content": "type Maybe a = Either (Const () a) (Identity a)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet09.hs",
    "content": "newtype BiComp bf fu gu a b = BiComp (bf (fu a) (gu b))"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet10.hs",
    "content": "instance (Bifunctor bf, Functor fu, Functor gu) =>\n  Bifunctor (BiComp bf fu gu) where\n    bimap f1 f2 (BiComp x) = BiComp (bimap (fmap f1) (fmap f2) x)\n"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet11.hs",
    "content": "bf (fu a) (gu b)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet12.hs",
    "content": "f1 :: a -> a'\nf2 :: b -> b'"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet13.hs",
    "content": "bimap :: (fu a -> fu a') -> (gu b -> gu b')\n  -> bf (fu a) (gu b) -> bf (fu a') (gu b')"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet14.hs",
    "content": "data Tree a = Leaf a | Node (Tree a) (Tree a)\n    deriving Functor"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet15.hs",
    "content": "instance Functor Tree where\n    fmap f (Leaf a) = Leaf (f a)\n    fmap f (Node t t') = Node (fmap f t) (fmap f t')"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet16.hs",
    "content": "type Writer a = (a, String)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet17.hs",
    "content": "(>=>) :: (a -> Writer b) -> (b -> Writer c) -> (a -> Writer c)\nm1 >=> m2 = \\x ->\n    let (y, s1) = m1 x\n        (z, s2) = m2 y \n    in (z, s1 ++ s2)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet18.hs",
    "content": "return :: a -> Writer a\nreturn x = (x, \"\")"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet19.hs",
    "content": "fmap f = id >=> (\\x -> return (f x))"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet20.hs",
    "content": "(->) r"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet21.hs",
    "content": "type Reader r a = r -> a"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet22.hs",
    "content": "instance Functor (Reader r) where\n    fmap f g = f . g"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet23.hs",
    "content": "type Op r a = a -> r"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet24.hs",
    "content": "fmap :: (a -> b) -> (a -> r) -> (b -> r)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet25.hs",
    "content": "class Contravariant f where\n    contramap :: (b -> a) -> (f a -> f b)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet26.hs",
    "content": "instance Contravariant (Op r) where\n    -- (b -> a) -> Op r a -> Op r b\n    contramap f g = g . f"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet27.hs",
    "content": "flip :: (a -> b -> c) -> (b -> a -> c)\nflip f y x = f x y"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet28.hs",
    "content": "contramap = flip (.)"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet29.hs",
    "content": "class Profunctor p where\n    dimap :: (a -> b) -> (c -> d) -> p b c -> p a d\n    dimap f g = lmap f . rmap g\n    lmap :: (a -> b) -> p b c -> p a c\n    lmap f = dimap f id\n    rmap :: (b -> c) -> p a b -> p a c\n    rmap = dimap id"
  },
  {
    "path": "src/content/1.8/code/haskell/snippet30.hs",
    "content": "instance Profunctor (->) where\n    dimap ab cd bc = cd . bc . ab\n    lmap = flip (.)\n    rmap = (.)"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet01.ml",
    "content": "(** You can represent bifunctor defintion in two forms and implement\n    just and derive the other from it. *)\nmodule type BifunctorCore = sig\n  type ('a, 'b) t\n\n  val bimap : ('a -> 'c) -> ('b -> 'd) -> ('a, 'b) t -> ('c, 'd) t\nend\n\nmodule type BifunctorExt = sig\n  type ('a, 'b) t\n\n  val first : ('a -> 'c) -> ('a, 'b) t -> ('c, 'b) t\n  val second : ('b -> 'd) -> ('a, 'b) t -> ('a, 'd) t\nend\n\nmodule BifunctorCore_Using_Ext (M : BifunctorExt) : BifunctorCore =\nstruct\n  type ('a, 'b) t = ('a, 'b) M.t\n\n  let bimap g h x = M.first g (M.second h x)\nend\n\nmodule BifunctorExt_Using_Core (M : BifunctorCore) : BifunctorExt =\nstruct\n  type ('a, 'b) t = ('a, 'b) M.t\n\n  let first g x = M.bimap g id x\n  let second h x = M.bimap id h x\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet02.ml",
    "content": "module Bifunctor_Product : BifunctorCore = struct\n  type ('a, 'b) t = 'a * 'b\n\n  let bimap f g (l, r) = f l, g r\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet03.ml",
    "content": "val bimap\n  :  ('a -> 'c)\n  -> ('b -> 'd)\n  -> ('a, 'b) Bifunctor_Product.t\n  -> ('c, 'd) Bifunctor_Product.t\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet04.ml",
    "content": "type ('a, 'b) either =\n  | Left of 'a\n  | Right of 'b\n\nmodule Bifunctor_Either : BifunctorCore = struct\n  type ('a, 'b) t = ('a, 'b) either\n\n  let bimap f g = function\n    | Left a -> Left (f a)\n    | Right b -> Right (g b)\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet05.ml",
    "content": "type 'a id = Id of 'a\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet06.ml",
    "content": "module Identity_Functor : Functor = struct\n  type 'a t = 'a id\n\n  let fmap f (Id a) = Id (f a)\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet07.ml",
    "content": "type 'a option =\n  | None\n  | Some of 'a\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet08.ml",
    "content": "(** OCaml doesn't have a built in Const type *)\ntype ('a, 'b) const = Const of 'a\n\n(** OCaml doesn't have a built in either type *)\ntype ('a, 'b) either =\n  | Left of 'a\n  | Right of 'b (** Either type *)\n\ntype 'a option = ((unit, 'a) const, 'a id) either\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet09.ml",
    "content": "(** OCaml doesn't support higher kinded types. So, we have to use\n    module functors to emulate the behavior higher kinded types.\n    There's less verbose options using type defunctionalization\n    but it's more advanced and obscures the flow of this book *)\nmodule type BiComp = functor\n  (BF : sig\n     type ('a, 'b) t\n   end)\n  (FU : sig\n     type 'a t\n   end)\n  (GU : sig\n     type 'b t\n   end)\n  -> sig\n  type ('a, 'b) bicomp = BiComp of ('a FU.t, 'b GU.t) BF.t\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet10.ml",
    "content": "module BiCompBifunctor\n    (BF : BifunctorCore)\n    (FU : Functor)\n    (GU : Functor) : BifunctorCore = struct\n  type ('a, 'b) t = BiComp of ('a FU.t, 'b GU.t) BF.t\n\n  let bimap f g (BiComp x) =\n    BiComp (BF.bimap (FU.fmap f) (GU.fmap g) x)\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet11.ml",
    "content": "type ('a FU.t, 'b GU.t) BF.t\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet12.ml",
    "content": "val f1 : a -> a'\nval f2 : b -> b'\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet13.ml",
    "content": "val bimap : (a FU.t -> a' FU.t) -> (b GU.t -> b' GU.t) -> (a FU.t, b GU.t) t -> (a' FU.t, b' GU.t) t\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet14.ml",
    "content": "(** Deriving a functor in OCaml is not available as a language\n    extension. You could try experimental library like ocsigen\n    to derive functors.*)\ntype 'a tree =\n  | Leaf of 'a\n  | Node of 'a tree * 'a tree\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet15.ml",
    "content": "module TreeFunctor : Functor = struct\n  type 'a t = 'a tree\n\n  let rec fmap f = function\n    | Leaf a -> Leaf (f a)\n    | Node (l, r) -> Node (fmap f l, fmap f r)\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet16.ml",
    "content": "type 'a writer = 'a * string\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet17.ml",
    "content": "module KleisliComposition = struct\n  let ( >=> )\n      : ('a -> 'b writer) -> ('b -> 'c writer) -> 'a -> 'c writer\n    =\n   fun m1 m2 x ->\n    let y, s1 = m1 x in\n    let z, s2 = m2 y in\n    z, StringLabels.concat ~sep:\"\" [ s1; s2 ]\n ;;\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet18.ml",
    "content": "module KleisliIdentity = struct\n  let return : 'a -> 'a writer = fun a -> a, \"\"\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet19.ml",
    "content": "module KleisliFunctor : Functor = struct\n  type 'a t = 'a writer\n\n  let fmap f =\n    KleisliComposition.( >=> ) id (fun x ->\n        KleisliIdentity.return (f x))\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet20.ml",
    "content": "module PartialArrow (T : sig\n  type r\nend) =\nstruct\n  type 'a t = T.r -> 'a\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet21.ml",
    "content": "type ('r, 'a) reader = 'r -> 'a\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet22.ml",
    "content": "module ReaderFunctor (In : sig\n  type r\nend) : Functor = struct\n  type 'a t = (In.r, 'a) reader\n\n  let fmap f g = compose f g\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet23.ml",
    "content": "type ('r, 'a) op = 'a -> 'r\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet24.ml",
    "content": "val fmap : 'a 'b. ('a -> 'b) -> ('a -> 'r) -> ('b -> 'r)\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet25.ml",
    "content": "module type Contravariant = sig\n  type 'a t\n\n  val contramap : ('b -> 'a) -> 'a t -> 'b t\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet26.ml",
    "content": "module OpContravariant (In : sig\n  type r\nend) : Contravariant = struct\n  type 'a t = (In.r, 'a) op\n\n  let contramap f g = compose g f\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet27.ml",
    "content": "let flip f b a = f a b\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet28.ml",
    "content": "let contramap : ('b -> 'a) -> ('r, 'a) op -> ('r, 'b) op =\n fun f g -> flip compose f g\n;;\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet29.ml",
    "content": "(* Profunctor definition *)\nmodule type Profunctor = sig\n  type ('a, 'b) p\n\n  val dimap : ('a -> 'b) -> ('c -> 'd) -> ('b, 'c) p -> ('a, 'd) p\nend\n\n(* Profunctor alternate definition *)\nmodule type ProfunctorExt = sig\n  type ('a, 'b) p\n\n  val lmap : ('a -> 'b) -> ('b, 'c) p -> ('a, 'c) p\n  val rmap : ('b -> 'c) -> ('a, 'b) p -> ('a, 'c) p\nend\n\n(* Profunctor dimap defined using lmap and rmap *)\nmodule Profunctor_Using_Ext (PF : ProfunctorExt) : Profunctor = struct\n  type ('a, 'b) p = ('a, 'b) PF.p\n\n  let dimap f g = compose (PF.lmap f) (PF.rmap g)\nend\n\n(** Profunctor lmap and rmap defined using dimap *)\nmodule ProfunctorExt_Using_Dimap (PF : Profunctor) : ProfunctorExt =\nstruct\n  type ('a, 'b) p = ('a, 'b) PF.p\n\n  let lmap f = PF.dimap f id\n  let rmap g = PF.dimap id g\nend\n"
  },
  {
    "path": "src/content/1.8/code/ocaml/snippet30.ml",
    "content": "module ProfunctorArrow : Profunctor = struct\n  type ('a, 'b) p = 'a -> 'b\n\n  let dimap f g p = compose g (compose p f)\nend\n\nmodule ProfunctorExtArrow : ProfunctorExt = struct\n  type ('a, 'b) p = 'a -> 'b\n\n  let lmap f p = (flip compose) f p\n  let rmap = compose\nend\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet01.re",
    "content": "/** You can represent bifunctor defintion in two forms\n * and implement just and derive the other from it. */\nmodule type BifunctorCore = {\n  type t('a, 'b);\n\n  let bimap: ('a => 'c, 'b => 'd, t('a, 'b)) => t('c, 'd);\n};\n\nmodule type BifunctorExt = {\n  type t('a, 'b);\n\n  let first: ('a => 'c, t('a, 'b)) => t('c, 'b);\n  let second: ('b => 'd, t('a, 'b)) => t('a, 'd);\n};\n\nmodule BifunctorCore_Using_Ext = (M: BifunctorExt) : BifunctorCore => {\n  type t('a, 'b) = M.t('a, 'b);\n\n  let bimap = (g, h, x) => M.first(g, M.second(h, x));\n};\n\nmodule BifunctorExt_Using_Core = (M: BifunctorCore) : BifunctorExt => {\n  type t('a, 'b) = M.t('a, 'b);\n  \n  let first = (g, x) => M.bimap(g, id, x);\n  let second = (h, x) => M.bimap(id, h, x);\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet02.re",
    "content": "module Bifunctor_Product: BifunctorCore = {\n  type t('a, 'b) = ('a, 'b);\n  \n  let bimap = (f, g, (l, r)) => (f(l), g(r));\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet03.re",
    "content": "let bimap: ('a => 'c, 'b => 'd, Bifunctor_Product.t('a, 'b)) => \n    Bifunctor_Product.t('c, 'd)"
  },
  {
    "path": "src/content/1.8/code/reason/snippet04.re",
    "content": "type either('a, 'b) =\n  | Left('a)\n  | Right('b);\n\nmodule Bifunctor_Either: BifunctorCore = {\n  type t('a, 'b) = either('a, 'b);\n  \n  let bimap = (f, g) =>\n    fun\n    | Left(a) => Left(f(a))\n    | Right(b) => Right(g(b));\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet05.re",
    "content": "type id('a) =\n  | Id('a);\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet06.re",
    "content": "module Identity_Functor: Functor = {\n  type t('a) = id('a);\n  \n  let fmap = (f, Id(a)) => Id(f(a));\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet07.re",
    "content": "type option('a) =\n  | None\n  | Some('a);\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet08.re",
    "content": "/* ReasonML doesn't have a built in Const type */\ntype const('a, 'b) =\n  | Const('a);\n\n/* ReasonML doesn't have a built in either type */\ntype either('a, 'b) =\n  | Left('a)\n  | Right('b);\n\n/* Either type */\ntype option('a) = either(const(unit, 'a), id('a));\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet09.re",
    "content": "/** ReasonML doesn't support higher kinded types. \n * So, we have to use module functors to emulate the behavior higher kinded types. \n * There's less verbose options using type defunctionalization \n * but it's more advanced and obscures the flow of this book */\nmodule type BiComp =\n  (\n    BF: {type t('a, 'b);},\n    FU: {type t('a);}, \n    GU: {type t('b);}\n  ) => {\n    type bicomp('a, 'b) =\n      | BiComp(BF.t(FU.t('a), GU.t('b)));\n  };\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet10.re",
    "content": "module BiCompBifunctor =\n       (\n         BF: BifunctorCore, \n         FU: Functor, \n         GU: Functor\n        ): BifunctorCore => {\n  type t('a, 'b) =\n    | BiComp(BF.t(FU.t('a), GU.t('b)));\n    \n  let bimap = (f, g, BiComp(x)) =>\n    BiComp(BF.bimap(FU.fmap(f), GU.fmap(g), x));\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet11.re",
    "content": "BF.t(FU.t('a), GU.t('b));"
  },
  {
    "path": "src/content/1.8/code/reason/snippet12.re",
    "content": "let f1: a => a'\nlet f2: b => b'"
  },
  {
    "path": "src/content/1.8/code/reason/snippet13.re",
    "content": "let bimap: (FU.t(a) => FU.t(a')) => (GU.t(b) => GU.t(b')) =>\n  (FU.t(a), GU.t(b)) => (FU.t(a'), GU.t(b'))"
  },
  {
    "path": "src/content/1.8/code/reason/snippet14.re",
    "content": "/** Deriving a functor in ReasonML is not available as a \n * language extension. You could try experimental library \n * like ocsigen to derive functors.*/\ntype tree('a) =\n  | Leaf('a)\n  | Node(tree('a), tree('a));\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet15.re",
    "content": "module TreeFunctor: Functor = {\n  type t('a) = tree('a);\n  \n  let rec fmap = f =>\n    fun\n    | Leaf(a) => Leaf(f(a))\n    | Node(l, r) => Node(fmap(f, l), fmap(f, r));\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet16.re",
    "content": "type writer('a) = ('a, string);\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet17.re",
    "content": "module KleisliComposition = {\n  let (>=>): ('a => writer('b), 'b => writer('c), 'a) => writer('c) =\n    (m1, m2, x) => {\n      let (y, s1) = m1(x);\n      let (z, s2) = m2(y);\n      (z, StringLabels.concat(~sep=\"\", [s1, s2]));\n    };\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet18.re",
    "content": "module KleisliIdentity = {\n  let return: 'a => writer('a) = a => (a, \"\");\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet19.re",
    "content": "module KleisliFunctor: Functor = {\n  type t('a) = writer('a);\n  \n  let fmap = f =>\n    KleisliComposition.(>=>)(id, x => KleisliIdentity.return(f(x)));\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet20.re",
    "content": "module PartialArrow = (T: {type r;}) => {\n  type t('a) = T.r => 'a;\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet21.re",
    "content": "type reader('r, 'a) = 'r => 'a;\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet22.re",
    "content": "module ReaderFunctor = (In: {type r;}) : Functor => {\n  type t('a) = reader(In.r, 'a);\n  \n  let fmap = (f, g) => compose(f, g);\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet23.re",
    "content": "type op('r, 'a) = 'a => 'r;\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet24.re",
    "content": "let fmap: 'a, 'b . ('a => 'b) => ('a => 'r) => ('b => 'r)"
  },
  {
    "path": "src/content/1.8/code/reason/snippet25.re",
    "content": "module type Contravariant = {\n  type t('a);\n  \n  let contramap: ('b => 'a, t('a)) => t('b);\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet26.re",
    "content": "module OpContravariant = (In: {type r;}) : Contravariant => {\n  type t('a) = op(In.r, 'a);\n  \n  let contramap = (f, g) => compose(g, f);\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet27.re",
    "content": "let flip = (f, b, a) => f(a, b);\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet28.re",
    "content": "let contramap: ('b => 'a, op('r, 'a)) => op('r, 'b) = (\n  (f, g) => flip(compose, f, g): ('b => 'a, op('r, 'a)) => op('r, 'b)\n);\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet29.re",
    "content": "/* Profunctor definition */\nmodule type Profunctor = {\n  type p('a, 'b);\n\n  let dimap: ('a => 'b, 'c => 'd, p('b, 'c)) => p('a, 'd);\n};\n\n/* Profunctor alternate definition */\nmodule type ProfunctorExt = {\n  type p('a, 'b);\n\n  let lmap: ('a => 'b, p('b, 'c)) => p('a, 'c);\n  let rmap: ('b => 'c, p('a, 'b)) => p('a, 'c);\n};\n\n/* Profunctor dimap defined using lmap and rmap */\nmodule Profunctor_Using_Ext = (PF: ProfunctorExt) : Profunctor => {\n  type p('a, 'b) = PF.p('a, 'b);\n\n  let dimap = (f, g) => compose(PF.lmap(f), PF.rmap(g));\n};\n\n/** Profunctor lmap and rmap defined using dimap */\nmodule ProfunctorExt_Using_Dimap = (PF: Profunctor) : ProfunctorExt => {\n  type p('a, 'b) = PF.p('a, 'b);\n  \n  let lmap = f => PF.dimap(f, id);\n  let rmap = g => PF.dimap(id, g);\n};\n"
  },
  {
    "path": "src/content/1.8/code/reason/snippet30.re",
    "content": "module ProfunctorArrow: Profunctor = {\n  type p('a, 'b) = 'a => 'b;\n\n  let dimap = (f, g, p) => compose(g, compose(p, f));\n};\nmodule ProfunctorExtArrow: ProfunctorExt = {\n  type p('a, 'b) = 'a => 'b;\n  \n  let lmap = (f, p) => (flip(compose))(f, p);\n  let rmap = compose;\n};\n"
  },
  {
    "path": "src/content/1.8/code/scala/snippet01.scala",
    "content": "trait Bifunctor[F[_, _]] {\n  def bimap[A, B, C, D](g: A => C)(h: B => D): F[A, B] => F[C, D] =\n    first(g) compose second(h)\n\n  def first[A, B, C](g: A => C): F[A, B] => F[C, B] =\n    bimap(g)(identity[B])\n\n  def second[A, B, D](h: B => D): F[A, B] => F[A, D] =\n    bimap(identity[A])(h)\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet02.scala",
    "content": "implicit val tuple2Bifunctor = new Bifunctor[Tuple2] {\n  override def bimap[A, B, C, D](f: A => C)(g: B => D): ((A, B)) => (C, D) = {\n    case (x, y) => (f(x), g(y))\n  }\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet03.scala",
    "content": "def bimap[A, B, C, D](f: A => C)(g: B => D): ((A, B)) => (C, D)"
  },
  {
    "path": "src/content/1.8/code/scala/snippet04.scala",
    "content": "implicit val eitherBifunctor = new Bifunctor[Either] {\n  override def bimap[A, B, C, D](f: A => C)(g: B => D): Either[A, B] => Either[C, D] = {\n    case Left(x) => Left(f(x))\n    case Right(y) => Right(g(y))\n  }\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet05.scala",
    "content": "type Id[A] = A"
  },
  {
    "path": "src/content/1.8/code/scala/snippet06.scala",
    "content": "implicit val identityFunctor = new Functor[Id] {\n  def fmap[A, B](f: A => B)(x: Id[A]): Id[B] =\n    f(x)\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet07.scala",
    "content": "sealed trait Option[+A]\ncase object None extends Option[Nothing]\ncase class Some[A](a: A) extends Option[A]"
  },
  {
    "path": "src/content/1.8/code/scala/snippet08.scala",
    "content": "type Option[A] = Either[Const[Unit, A], Id[A]]"
  },
  {
    "path": "src/content/1.8/code/scala/snippet09.scala",
    "content": "case class BiComp[BF[_, _], FU[_], GU[_], A, B](v: BF[FU[A], GU[B]])"
  },
  {
    "path": "src/content/1.8/code/scala/snippet10.scala",
    "content": "implicit def bicompBiFunctor[\n    BF[_, _], FU[_], GU[_]](\n    implicit BF: Bifunctor[BF],\n    FU: Functor[FU], GU: Functor[GU]) = {\n  // partially-applied type BiComp\n  type BiCompAB[A, B] = BiComp[BF, FU, GU, A, B]\n  new Bifunctor[BiCompAB] {\n    override def bimap[A, B, C, D](f1: A => C)(f2: B => D): BiCompAB[A, B] => BiCompAB[C, D] = {\n      case BiComp(x) =>\n        BiComp(\n          BF.bimap(FU.fmap(f1))(GU.fmap(f2))(x)\n        )\n    }\n  }\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet11.scala",
    "content": "BF[FU[A], GU[B]]"
  },
  {
    "path": "src/content/1.8/code/scala/snippet12.scala",
    "content": "def f1: A => A1\ndef f2: B => B1"
  },
  {
    "path": "src/content/1.8/code/scala/snippet13.scala",
    "content": "def bimap: (FU[A] => FU[A1]) => (GU[B] => GU[B1]) => BiComp[BF, FU, GU, A, B] => BiComp[BF, FU, GU, A1, B1]"
  },
  {
    "path": "src/content/1.8/code/scala/snippet14.scala",
    "content": "sealed trait Tree[+A]\ncase class Leaf[A](a: A) extends Tree[A]\ncase class Node[A](l: Tree[A], r: Tree[A]) extends Tree[A]\n// implicit def treeFunctor = ???"
  },
  {
    "path": "src/content/1.8/code/scala/snippet15.scala",
    "content": "implicit val treeFunctor = new Functor[Tree] {\n  def fmap[A, B](f: A => B)(fa: Tree[A]): Tree[B] = fa match {\n    case Leaf(a) => Leaf(f(a))\n    case Node(t, t1) => Node(fmap(f)(t), fmap(f)(t1))\n  }\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet16.scala",
    "content": "type Writer[A] = (A, String)"
  },
  {
    "path": "src/content/1.8/code/scala/snippet17.scala",
    "content": "object kleisli {\n  //allows us to use >=> as an infix operator\n  implicit class KleisliOps[A, B](m1: A => Writer[B]) {\n    def >=>[C](m2: B => Writer[C]): A => Writer[C] =\n      x => {\n        val (y, s1) = m1(x)\n        val (z, s2) = m2(y)\n        (z, s1 + s2)\n      }\n  }\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet18.scala",
    "content": "// return is a keyword in Scala\ndef pure[A](x: A): Writer[A] = (x, \"\")"
  },
  {
    "path": "src/content/1.8/code/scala/snippet19.scala",
    "content": "import kleisli._\ndef fmap[A, B](f: A => B): Writer[A] => Writer[B] =\n  identity[Writer[A]] _ >=> (x => pure(f(x)))"
  },
  {
    "path": "src/content/1.8/code/scala/snippet20.scala",
    "content": "// with Kind Projector plugin\nFunction1[R, ?] or R => ?"
  },
  {
    "path": "src/content/1.8/code/scala/snippet21.scala",
    "content": "type Reader[R, A] = R => A"
  },
  {
    "path": "src/content/1.8/code/scala/snippet22.scala",
    "content": "implicit def readerFunctor[R] = new Functor[Reader[R, ?]] {\n  def fmap[A, B](f: A => B)(g: Reader[R, A]): Reader[R, B] =\n    f compose g\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet23.scala",
    "content": "type Op[R, A] = A => R"
  },
  {
    "path": "src/content/1.8/code/scala/snippet24.scala",
    "content": "def fmap[A, B]: (A => B) => (A => R) => (B => R)"
  },
  {
    "path": "src/content/1.8/code/scala/snippet25.scala",
    "content": "trait Contravariant[F[_]] {\n  def contramap[A, B](f: B => A)(fa: F[A]): F[B]\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet26.scala",
    "content": "implicit def opContravariant[R] = new Contravariant[R, ?] {\n  def contramap[A, B](f: B => A)(g: Op[R, A]): Op[R, B] =\n    g compose f\n}"
  },
  {
    "path": "src/content/1.8/code/scala/snippet27.scala",
    "content": "def flip[A, B, C]: (A => B => C) => (B => A => C) =\n  f => y => x => f(x)(y)"
  },
  {
    "path": "src/content/1.8/code/scala/snippet28.scala",
    "content": "def compose[A, B, C]: (A => B) => (C => A) => C => B =\n  f => g => c => f(g(c))\n\ndef contramap[A, B, R](f: B => A)(g: Op[R, A]): Op[R, B] =\n  flip(compose[A, R, B])(f)(g)\n  // or just: (f andThen g)"
  },
  {
    "path": "src/content/1.8/code/scala/snippet29.scala",
    "content": "trait Profunctor[F[_, _]] {\n  def dimap[A, B, C, D]: (A => B) => (C => D) => F[B, C] => F[A, D] = f => g =>\n    lmap(f) compose rmap[B, C, D](g)\n\n  def lmap[A, B, C]: (A => B) => F[B, C] => F[A, C] = f =>\n    dimap(f)(identity[C])\n\n  def rmap[A, B, C]: (B => C) => F[A, B] => F[A, C] =\n    dimap[A, A, B, C](identity[A])\n}\n"
  },
  {
    "path": "src/content/1.8/code/scala/snippet30.scala",
    "content": "implicit val function1Profunctor = new Profunctor[Function1] {\n  override def bimap[A, B, C, D]: (A => B) => (C => D) => (B => C) => (A => D) = ab => cd => bc =>\n    cd compose bc compose ab\n\n  override def lmap[A, B, C]: (A => B) => (B => C) => (A => C) =\n    flip(compose)\n\n  override def rmap[A, B, C]: (B => C) => (A => B) => (A => C) =\n    compose\n}"
  },
  {
    "path": "src/content/1.8/functoriality.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{N}{ow that you know} what a functor is, and have seen a few examples, let's\nsee how we can build larger functors from smaller ones. In particular\nit's interesting to see which type constructors (which correspond to\nmappings between objects in a category) can be extended to functors\n(which include mappings between morphisms).\n\n\\section{Bifunctors}\n\nSince functors are morphisms in $\\Cat$ (the category of categories),\na lot of intuitions about morphisms --- and functions in particular ---\napply to functors as well. For instance, just like you can have a\nfunction of two arguments, you can have a functor of two arguments, or a\n\\newterm{bifunctor}. On objects, a bifunctor maps every pair of objects,\none from category $\\cat{C}$, and one from category $\\cat{D}$, to an object in category\n$\\cat{E}$. Notice that this is just saying that it's a mapping from a\n\\newterm{Cartesian product} of categories $\\cat{C}\\times{}\\cat{D}$ to $\\cat{E}$.\n\n\\begin{figure}[H]\n  \\centering\\includegraphics[width=0.3\\textwidth]{images/bifunctor.jpg}\n\\end{figure}\n\n\\noindent\nThat's pretty straightforward. But functoriality means that a bifunctor\nhas to map morphisms as well. This time, though, it must map a pair of\nmorphisms, one from $\\cat{C}$ and one from $\\cat{D}$, to a morphism in $\\cat{E}$.\n\nAgain, a pair of morphisms is just a single morphism in the product\ncategory $\\cat{C}\\times{}\\cat{D}$. We define a morphism in a Cartesian product of categories\nas a pair of morphisms which goes from one pair of objects to another\npair of objects. These pairs of morphisms can be composed in the obvious\nway:\n\\[(f, g) \\circ (f', g') = (f \\circ f', g \\circ g')\\]\nThe composition is associative and it has an identity --- a pair of\nidentity morphisms $(\\id, \\id)$. So a Cartesian product of categories\nis indeed a category.\n\nAn easier way to think about bifunctors would be to consider them functors in\neach argument separately. So instead of translating functorial laws ---\nassociativity and identity preservation --- from functors to bifunctors,\nit would be enough to check them separately for each argument. However, in general,\nseparate functoriality is not enough to prove joint functoriality. Categories in which\njoint functoriality fails are called \\newterm{premonoidal}.\n\nLet's define a bifunctor in Haskell. In this case all three categories\nare the same: the category of Haskell types. A bifunctor is a type\nconstructor that takes two type arguments. Here's the definition of the\n\\code{Bifunctor} typeclass taken directly from the library\n\\code{Control.Bifunctor}:\n\n\\src{snippet01}\n\n\\begin{figure}[H]\n  \\centering\\includegraphics[width=0.3\\textwidth]{images/bimap.jpg}\n  \\caption{bimap}\n\\end{figure}\n\nThe type variable \\code{f} represents the bifunctor. You can see that\nin all type signatures it's always applied to two type arguments. The\nfirst type signature defines \\code{bimap}: a mapping of two functions\nat once. The result is a lifted function,\n\\code{(f a b -> f c d)}, operating on types\ngenerated by the bifunctor's type constructor. There is a default\nimplementation of \\code{bimap} in terms of \\code{first} and\n\\code{second}. (As mentioned before, this doesn't always work, because\nthe two maps may not commute, that is \\code{first g . second h} may not\nbe the same as \\code{second h . first g}.)\n\n\n\\noindent\nThe two other type signatures, \\code{first} and \\code{second}, are\nthe two \\code{fmap}s witnessing the functoriality of \\code{f} in the\nfirst and the second argument, respectively.\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{minipage}{0.45\\textwidth}\n    \\centering\n    \\includegraphics[width=0.65\\textwidth]{images/first.jpg} % first figure itself\n    \\caption{first}\n  \\end{minipage}\\hfill\n  \\begin{minipage}{0.45\\textwidth}\n    \\centering\n    \\includegraphics[width=0.6\\textwidth]{images/second.jpg} % second figure itself\n    \\caption{second}\n  \\end{minipage}\n\\end{figure}\n\n\\noindent\nThe typeclass definition provides default implementations for both of\nthem in terms of \\code{bimap}.\n\nWhen declaring an instance of \\code{Bifunctor}, you have a choice of\neither implementing \\code{bimap} and accepting the defaults for\n\\code{first} and \\code{second}, or implementing both \\code{first}\nand \\code{second} and accepting the default for \\code{bimap} (of\ncourse, you may implement all three of them, but then it's up to you to\nmake sure they are related to each other in this manner).\n\n\\section{Product and Coproduct Bifunctors}\n\nAn important example of a bifunctor is the categorical product --- a\nproduct of two objects that is defined by a \\hyperref[products-and-coproducts]{universal\n  construction}. If the product exists for any pair of objects, the\nmapping from those objects to the product is bifunctorial. This is true\nin general, and in Haskell in particular. Here's the \\code{Bifunctor}\ninstance for a pair constructor --- the simplest product type:\n\n\\src{snippet02}[b]\nThere isn't much choice: \\code{bimap} simply applies the first\nfunction to the first component, and the second function to the second\ncomponent of a pair. The code pretty much writes itself, given the\ntypes:\n\n\\src{snippet03}\nThe action of the bifunctor here is to make pairs of types, for\ninstance:\n\n\\begin{snip}{haskell}\n(,) a b = (a, b)\n\\end{snip}\nBy duality, a coproduct, if it's defined for every pair of objects in a\ncategory, is also a bifunctor. In Haskell, this is exemplified by the\n\\code{Either} type constructor being an instance of\n\\code{Bifunctor}:\n\n\\src{snippet04}[b]\nThis code also writes itself.\n\nNow, remember when we talked about monoidal categories? A monoidal\ncategory defines a binary operator acting on objects, together with a\nunit object. I mentioned that $\\Set$ is a monoidal category with\nrespect to Cartesian product, with the singleton set as a unit. And it's\nalso a monoidal category with respect to disjoint union, with the empty\nset as a unit. What I haven't mentioned is that one of the requirements\nfor a monoidal category is that the binary operator be a bifunctor. This\nis a very important requirement --- we want the monoidal product to be\ncompatible with the structure of the category, which is defined by\nmorphisms. We are now one step closer to the full definition of a\nmonoidal category (we still need to learn about naturality, before we\ncan get there).\n\n\\section{Functorial Algebraic Data Types}\n\nWe've seen several examples of parameterized data types that turned out\nto be functors --- we were able to define \\code{fmap} for them.\nComplex data types are constructed from simpler data types. In\nparticular, algebraic data types (\\acronym{ADT}s) are created using sums and\nproducts. We have just seen that sums and products are functorial. We\nalso know that functors compose. So if we can show that the basic\nbuilding blocks of \\acronym{ADT}s are functorial, we'll know that parameterized\n\\acronym{ADT}s are functorial too.\n\nSo what are the building blocks of parameterized algebraic data types?\nFirst, there are the items that have no dependency on the type parameter\nof the functor, like \\code{Nothing} in \\code{Maybe}, or \\code{Nil}\nin \\code{List}. They are equivalent to the \\code{Const} functor.\nRemember, the \\code{Const} functor ignores its type parameter (really,\nthe \\emph{second} type parameter, which is the one of interest to us,\nthe first one being kept constant).\n\nThen there are the elements that simply encapsulate the type parameter\nitself, like \\code{Just} in \\code{Maybe}. They are equivalent to the\nidentity functor. I mentioned the identity functor previously, as the\nidentity morphism in \\emph{Cat}, but didn't give its definition in\nHaskell. Here it is:\n\n\\src{snippet05}\n\n\\src{snippet06}\nYou can think of \\code{Identity} as the simplest possible container\nthat always stores just one (immutable) value of type \\code{a}.\n\nEverything else in algebraic data structures is constructed from these\ntwo primitives using products and sums.\n\nWith this new knowledge, let's have a fresh look at the \\code{Maybe}\ntype constructor:\n\n\\src{snippet07}\nIt's a sum of two types, and we now know that the sum is functorial. The\nfirst part, \\code{Nothing} can be represented as a \\code{Const ()}\nacting on \\code{a} (the first type parameter of \\code{Const} is set\nto unit --- later we'll see more interesting uses of \\code{Const}).\nThe second part is just a different name for the identity functor. We\ncould have defined \\code{Maybe}, up to isomorphism, as:\n\n\\src{snippet08}\nSo \\code{Maybe} is the composition of the bifunctor \\code{Either}\nwith two functors, \\code{Const ()} and \\code{Identity}.\n(\\code{Const} is really a bifunctor, but here we always use it\npartially applied.)\n\nWe've already seen that a composition of functors is a functor --- we\ncan easily convince ourselves that the same is true of bifunctors. All\nwe need is to figure out how a composition of a bifunctor with two\nfunctors works on morphisms. Given two morphisms, we simply lift one\nwith one functor and the other with the other functor. We then lift the\nresulting pair of lifted morphisms with the bifunctor.\n\nWe can express this composition in Haskell. Let's define a data type\nthat is parameterized by a bifunctor \\code{bf} (it's a type variable\nthat is a type constructor that takes two types as arguments), two\nfunctors \\code{fu} and \\code{gu} (type constructors that take one\ntype variable each), and two regular types \\code{a} and \\code{b}. We\napply \\code{fu} to \\code{a} and \\code{gu} to \\code{b}, and then\napply \\code{bf} to the resulting two types:\n\n\\src{snippet09}\nThat's the composition on objects, or types. Notice how in Haskell we\napply type constructors to types, just like we apply functions to\narguments. The syntax is the same.\n\nIf you're getting a little lost, try applying \\code{BiComp} to\n\\code{Either}, \\code{Const ()}, \\code{Identity}, \\code{a}, and\n\\code{b}, in this order. You will recover our bare-bone version of\n\\code{Maybe b} (\\code{a} is ignored).\n\nThe new data type \\code{BiComp} is a bifunctor in \\code{a} and\n\\code{b}, but only if \\code{bf} is itself a \\code{Bifunctor} and\n\\code{fu} and \\code{gu} are \\code{Functor}s. The compiler must\nknow that there will be a definition of \\code{bimap} available for\n\\code{bf}, and definitions of \\code{fmap} for \\code{fu} and\n\\code{gu}. In Haskell, this is expressed as a precondition in the\ninstance declaration: a set of class constraints followed by a double\narrow:\n\n\\src{snippet10}[b]\nThe implementation of \\code{bimap} for \\code{BiComp} is given in\nterms of \\code{bimap} for \\code{bf} and the two \\code{fmap}s for\n\\code{fu} and \\code{gu}. The compiler automatically infers all the\ntypes and picks the correct overloaded functions whenever\n\\code{BiComp} is used.\n\nThe \\code{x} in the definition of \\code{bimap} has the type:\n\n\\src{snippet11}\nwhich is quite a mouthful. The outer \\code{bimap} breaks through the\nouter \\code{bf} layer, and the two \\code{fmap}s dig under\n\\code{fu} and \\code{gu}, respectively. If the types of \\code{f1}\nand \\code{f2} are:\n\n\\src{snippet12}\nthen the final result is of the type\n\\code{bf (fu a') (gu b')}:\n\n\\src{snippet13}[b]\nIf you like jigsaw puzzles, these kinds of type manipulations can\nprovide hours of entertainment.\n\nSo it turns out that we didn't have to prove that \\code{Maybe} was a\nfunctor --- this fact followed from the way it was constructed as a sum\nof two functorial primitives.\n\nA perceptive reader might ask the question: If the derivation of the\n\\code{Functor} instance for algebraic data types is so mechanical,\ncan't it be automated and performed by the compiler? Indeed, it can, and\nit is. You need to enable a particular Haskell extension by including\nthis line at the top of your source file:\n\n\\begin{snip}{haskell}\n{-# LANGUAGE DeriveFunctor #-}\n\\end{snip}\nand then add \\code{deriving Functor} to your data structure:\n\n\\begin{snip}{haskell}\ndata Maybe a = Nothing | Just a deriving Functor\n\\end{snip}\nand the corresponding \\code{fmap} will be implemented for you.\n\nThe regularity of algebraic data structures makes it possible to derive\ninstances not only of \\code{Functor} but of several other type\nclasses, including the \\code{Eq} type class I mentioned before. There\nis also the option of teaching the compiler to derive instances of your\nown typeclasses, but that's a bit more advanced. The idea though is the\nsame: You provide the behavior for the basic building blocks and sums\nand products, and let the compiler figure out the rest.\n\n\\section{Functors in C++}\n\nIf you are a C++ programmer, you obviously are on your own as far as\nimplementing functors goes. However, you should be able to recognize\nsome types of algebraic data structures in C++. If such a data structure\nis made into a generic template, you should be able to quickly implement\n\\code{fmap} for it.\n\nLet's have a look at a tree data structure, which we would define in\nHaskell as a recursive sum type:\n\n\\src{snippet14}\nAs I mentioned before, one way of implementing sum types in C++ is\nthrough class hierarchies. It would be natural, in an object-oriented\nlanguage, to implement \\code{fmap} as a virtual function of the base\nclass \\code{Functor} and then override it in all subclasses.\nUnfortunately this is impossible because \\code{fmap} is a template,\nparameterized not only by the type of the object it's acting upon (the\n\\code{this} pointer) but also by the return type of the function\nthat's been applied to it. Virtual functions cannot be templatized in\nC++. We'll implement \\code{fmap} as a generic free function, and we'll\nreplace pattern matching with \\code{dynamic\\_cast}.\n\nThe base class must define at least one virtual function in order to\nsupport dynamic casting, so we'll make the destructor virtual (which is\na good idea in any case):\n\n\\begin{snip}{cpp}\ntemplate<typename T>\nstruct Tree { \n    virtual ~Tree() {}\n};\n\\end{snip}\nThe \\code{Leaf} is just an \\code{Identity} functor in disguise:\n\n\\begin{snip}{cpp}\ntemplate<typename T>\nstruct Leaf : public Tree<T> {\n    T _label;\n    Leaf(T l) : _label(l) {}\n};\n\\end{snip}\nThe \\code{Node} is a product type:\n\n\\begin{snip}{cpp}\ntemplate<typename T>\nstruct Node : public Tree<T> {\n    Tree<T> * _left;\n    Tree<T> * _right;\n    Node(Tree<T> * l, Tree<T> * r) : _left(l), _right(r) {}\n};\n\\end{snip}\nWhen implementing \\code{fmap} we take advantage of dynamic dispatching\non the type of the \\code{Tree}. The \\code{Leaf} case applies the\n\\code{Identity} version of \\code{fmap}, and the \\code{Node} case\nis treated like a bifunctor composed with two copies of the\n\\code{Tree} functor. As a C++ programmer, you're probably not used to\nanalyzing code in these terms, but it's a good exercise in categorical\nthinking.\n\n\\begin{snip}{cpp}\ntemplate<typename A, typename B>\nTree<B> * fmap(std::function<B(A)> f, Tree<A> * t) {\n    Leaf<A> * pl = dynamic_cast <Leaf<A>*>(t);\n    if (pl)\n        return new Leaf<B>(f (pl->_label));\n    Node<A> * pn = dynamic_cast<Node<A>*>(t);\n    if (pn)\n        return new Node<B>( fmap<A>(f, pn->_left)\n                          , fmap<A>(f, pn->_right));\n    return nullptr;\n}\n\\end{snip}\nFor simplicity, I decided to ignore memory and resource management\nissues, but in production code you would probably use smart pointers\n(unique or shared, depending on your policy).\n\nCompare it with the Haskell implementation of \\code{fmap}:\n\n\\src{snippet15}\nThis implementation can also be automatically derived by the compiler.\n\n\\section{The Writer Functor}\n\nI promised that I would come back to the \\hyperref[kleisli-categories]{Kleisli\n  category} I described earlier. Morphisms in that category were\nrepresented as ``embellished'' functions returning the \\code{Writer}\ndata structure.\n\n\\src{snippet16}\nI said that the embellishment was somehow related to endofunctors. And,\nindeed, the \\code{Writer} type constructor is functorial in\n\\code{a}. We don't even have to implement \\code{fmap} for it,\nbecause it's just a simple product type.\n\nBut what's the relation between a Kleisli category and a functor --- in\ngeneral? A Kleisli category, being a category, defines composition and\nidentity. Let me remind you that the composition is given by the fish\noperator:\n\n\\src{snippet17}\nand the identity morphism by a function called \\code{return}:\n\n\\src{snippet18}\nIt turns out that, if you look at the types of these two functions long\nenough (and I mean, \\emph{long} enough), you can find a way to combine\nthem to produce a function with the right type signature to serve as\n\\code{fmap}. Like this:\n\n\\src{snippet19}\nHere, the fish operator combines two functions: one of them is the\nfamiliar \\code{id}, and the other is a lambda that applies\n\\code{return} to the result of acting with \\code{f} on the lambda's\nargument. The hardest part to wrap your brain around is probably the use\nof \\code{id}. Isn't the argument to the fish operator supposed to be a\nfunction that takes a ``normal'' type and returns an embellished type?\nWell, not really. Nobody says that \\code{a} in\n\\code{a -> Writer b} must be a ``normal'' type. It's a\ntype variable, so it can be anything, in particular it can be an\nembellished type, like \\code{Writer b}.\n\nSo \\code{id} will take \\code{Writer a} and turn it into\n\\code{Writer a}. The fish operator will fish out the value of\n\\code{a} and pass it as \\code{x} to the lambda. There, \\code{f}\nwill turn it into a \\code{b} and \\code{return} will embellish it,\nmaking it \\code{Writer b}. Putting it all together, we end up with a\nfunction that takes \\code{Writer a} and returns \\code{Writer b},\nexactly what \\code{fmap} is supposed to produce.\n\nNotice that this argument is very general: you can replace\n\\code{Writer} with any type constructor. As long as it supports a fish\noperator and \\code{return}, you can define \\code{fmap} as well. So\nthe embellishment in the Kleisli category is always a functor. (Not\nevery functor, though, gives rise to a Kleisli category.)\n\nYou might wonder if the \\code{fmap} we have just defined is the same\n\\code{fmap} the compiler would have derived for us with\n\\code{deriving Functor}. Interestingly enough, it is. This is due to\nthe way Haskell implements polymorphic functions. It's called\n\\newterm{parametric polymorphism}, and it's a source of so called\n\\newterm{theorems for free}. One of those theorems says that, if there is\nan implementation of \\code{fmap} for a given type constructor, one\nthat preserves identity, then it must be unique.\n\n\\section{Covariant and Contravariant Functors}\n\nNow that we've reviewed the writer functor, let's go back to the reader\nfunctor. It was based on the partially applied function-arrow type\nconstructor:\n\n\\src{snippet20}\nWe can rewrite it as a type synonym:\n\n\\src{snippet21}\nfor which the \\code{Functor} instance, as we've seen before, reads:\n\n\\src{snippet22}\nBut just like the pair type constructor, or the \\code{Either} type\nconstructor, the function type constructor takes two type arguments. The\npair and \\code{Either} were functorial in both arguments --- they were\nbifunctors. Is the function constructor a bifunctor too?\n\nLet's try to make it functorial in the first argument. We'll start with\na type synonym --- it's just like the \\code{Reader} but with the\narguments flipped:\n\n\\src{snippet23}\nThis time we fix the return type, \\code{r}, and vary the argument\ntype, \\code{a}. Let's see if we can somehow match the types in order\nto implement \\code{fmap}, which would have the following type\nsignature:\n\n\\src{snippet24}\nWith just two functions taking \\code{a} and returning, respectively,\n\\code{b} and \\code{r}, there is simply no way to build a function\ntaking \\code{b} and returning \\code{r}! It would be different if we\ncould somehow invert the first function, so that it took \\code{b} and\nreturned \\code{a} instead. We can't invert an arbitrary function, but\nwe can go to the opposite category.\n\nA short recap: For every category $\\cat{C}$ there is a dual category\n$\\cat{C}^\\mathit{op}$. It's a category with the same objects as\n$\\cat{C}$, but with all the arrows reversed.\n\nConsider a functor that goes between $\\cat{C}^\\mathit{op}$ and\nsome other category $\\cat{D}$:\n\\[F \\Colon \\cat{C}^\\mathit{op} \\to \\cat{D}\\]\nSuch a functor maps a morphism $f^\\mathit{op} \\Colon a \\to b$ in\n$\\cat{C}^\\mathit{op}$ to the morphism $F f^\\mathit{op} \\Colon F a \\to F b$ in $\\cat{D}$. But the morphism\n$f^\\mathit{op}$ secretly corresponds to some morphism\n$f \\Colon b \\to a$ in the original category $\\cat{C}$. Notice the\ninversion.\n\nNow, $F$ is a regular functor, but there is another mapping we can\ndefine based on $F$, which is not a functor --- let's call it\n$G$. It's a mapping from $\\cat{C}$ to $\\cat{D}$. It maps objects the\nsame way $F$ does, but when it comes to mapping morphisms, it\nreverses them. It takes a morphism $f \\Colon b \\to a$ in $\\cat{C}$, maps\nit first to the opposite morphism $f^\\mathit{op} \\Colon a \\to b$\nand then uses the functor $F$ on it, to get $F f^\\mathit{op} \\Colon F a \\to F b$.\n\nConsidering that $F a$ is the same as $G a$ and $F b$ is\nthe same as $G b$, the whole trip can be described as: $G f \\Colon (b \\to a) \\to (G a \\to G b)$\nIt's a ``functor with a twist.'' A mapping of categories that inverts\nthe direction of morphisms in this manner is called a\n\\emph{contravariant functor}. Notice that a contravariant functor is\njust a regular functor from the opposite category. The regular functors,\nby the way --- the kind we've been studying thus far --- are called\n\\emph{covariant} functors.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=40mm]{images/contravariant.jpg}\n\\end{figure}\n\n\\noindent\nHere's the typeclass defining a contravariant functor (really, a\ncontravariant \\emph{endo}functor) in Haskell:\n\n\\src{snippet25}\nOur type constructor \\code{Op} is an instance of it:\n\n\\src{snippet26}\nNotice that the function \\code{f} inserts itself \\emph{before} (that\nis, to the right of) the contents of \\code{Op} --- the function\n\\code{g}.\n\nThe definition of \\code{contramap} for \\code{Op} may be made even\nterser, if you notice that it's just the function composition operator\nwith the arguments flipped. There is a special function for flipping\narguments, called \\code{flip}:\n\n\\src{snippet27}\nWith it, we get:\n\n\\src{snippet28}\n\n\\section{Profunctors}\n\nWe've seen that the function-arrow operator is contravariant in its\nfirst argument and covariant in the second. Is there a name for such a\nbeast? It turns out that, if the target category is $\\Set$, such a\nbeast is called a \\newterm{profunctor}. Because a contravariant functor is\nequivalent to a covariant functor from the opposite category, a\nprofunctor is defined as:\n\\[\\cat{C}^\\mathit{op} \\times \\cat{D} \\to \\Set\\]\nSince, to first approximation, Haskell types are sets, we apply the name\n\\code{Profunctor} to a type constructor \\code{p} of two arguments,\nwhich is contra-functorial in the first argument and functorial in the\nsecond. Here's the appropriate typeclass taken from the\n\\code{Data.Profunctor} library:\n\n\\src{snippet29}[b]\nAll three functions come with default implementations. Just like with\n\\code{Bifunctor}, when declaring an instance of \\code{Profunctor},\nyou have a choice of either implementing \\code{dimap} and accepting\nthe defaults for \\code{lmap} and \\code{rmap}, or implementing both\n\\code{lmap} and \\code{rmap} and accepting the default for\n\\code{dimap}.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/dimap.jpg}\n  \\caption{dimap}\n\\end{figure}\n\n\\noindent\nNow we can assert that the function-arrow operator is an instance of a\n\\code{Profunctor}:\n\n\\src{snippet30}[b]\nProfunctors have their application in the Haskell lens library. We'll\nsee them again when we talk about ends and coends.\n\n\\section{The Hom-Functor}\n\nThe above examples are the reflection of a more general statement that\nthe mapping that takes a pair of objects $a$ and $b$ and\nassigns to it the set of morphisms between them, the hom-set\n$\\cat{C}(a, b)$, is a functor. It is a functor from the product\ncategory $\\cat{C}^\\mathit{op}\\times{}\\cat{C}$ to the category of sets, $\\Set$.\n\nLet's define its action on morphisms. A morphism in\n$\\cat{C}^\\mathit{op}\\times{}\\cat{C}$ is a pair of morphisms from $\\cat{C}$:\n\\begin{gather*}\n  f \\Colon a' \\to a \\\\\n  g \\Colon b \\to b'\n\\end{gather*}\nThe lifting of this pair must be a morphism (a function) from the set\n$\\cat{C}(a, b)$ to the set $\\cat{C}(a', b')$. Just pick\nany element $h$ of $\\cat{C}(a, b)$ (it's a morphism from\n$a$ to $b$) and assign to it:\n\\[g \\circ h \\circ f\\]\nwhich is an element of $\\cat{C}(a', b')$.\n\nAs you can see, the hom-functor is a special case of a profunctor.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Show that the data type:\n\n        \\begin{snip}{haskell}\ndata Pair a b = Pair a b\n\\end{snip}\n\n        is a bifunctor. For additional credit implement all three methods of\n        \\code{Bifunctor} and use equational reasoning to show that these\n        definitions are compatible with the default implementations whenever\n        they can be applied.\n  \\item\n        Show the isomorphism between the standard definition of \\code{Maybe}\n        and this desugaring:\n\n        \\begin{snip}{haskell}\ntype Maybe' a = Either (Const () a) (Identity a)\n\\end{snip}\n\n        Hint: Define two mappings between the two implementations. For\n        additional credit, show that they are the inverse of each other using\n        equational reasoning.\n  \\item\n        Let's try another data structure. I call it a \\code{PreList} because\n        it's a precursor to a \\code{List}. It replaces recursion with a type\n        parameter \\code{b}.\n\n        \\begin{snip}{haskell}\ndata PreList a b = Nil | Cons a b\n\\end{snip}\n\n        You could recover our earlier definition of a \\code{List} by\n        recursively applying \\code{PreList} to itself (we'll see how it's\n        done when we talk about fixed points).\n\n        Show that \\code{PreList} is an instance of \\code{Bifunctor}.\n  \\item\n        Show that the following data types define bifunctors in \\code{a} and\n        \\code{b}:\n\n        \\begin{snip}{haskell}\ndata K2 c a b = K2 c\n\ndata Fst a b = Fst a\n\ndata Snd a b = Snd b\n\\end{snip}\n\n        For additional credit, check your solutions against Conor McBride's\n        paper \\urlref{http://strictlypositive.org/CJ.pdf}{Clowns to the Left of\n          me, Jokers to the Right}.\n  \\item\n        Define a bifunctor in a language other than Haskell. Implement\n        \\code{bimap} for a generic pair in that language.\n  \\item\n        Should \\code{std::map} be considered a bifunctor or a profunctor in\n        the two template arguments \\code{Key} and \\code{T}? How would you\n        redesign this data type to make it so?\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet01.hs",
    "content": "a -> (b -> c)"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet02.hs",
    "content": "a -> b -> c"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet03.hs",
    "content": "catstr :: String -> String -> String\ncatstr s s' = s ++ s'"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet04.hs",
    "content": "catstr' s = \\s' -> s ++ s'"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet05.hs",
    "content": "greet :: String -> String\ngreet = catstr \"Hello \""
  },
  {
    "path": "src/content/1.9/code/haskell/snippet06.hs",
    "content": "(a, b) -> c"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet07.hs",
    "content": "curry :: ((a, b) -> c) -> (a -> b -> c)\ncurry f a b = f (a, b)"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet08.hs",
    "content": "uncurry :: (a -> b -> c) -> ((a, b) -> c)\nuncurry f (a, b) = f a b"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet09.hs",
    "content": "factorizer :: ((a, b) -> c) -> (a -> (b -> c))\nfactorizer g = \\a -> (\\b -> g (a, b))"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet10.hs",
    "content": "f :: Either Int Double -> String"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet11.hs",
    "content": "f (Left n) =\n  if n < 0\n    then \"Negative int\"\n    else \"Positive int\"\nf (Right x) =\n  if x < 0.0\n    then \"Negative double\"\n    else \"Positive double\"\n"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet12.hs",
    "content": "eval :: ((a -> b), a) -> b"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet13.hs",
    "content": "eval :: ((a -> b), a) -> b\neval (f, x) = f x"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet14.hs",
    "content": "Either a b -> a"
  },
  {
    "path": "src/content/1.9/code/haskell/snippet15.hs",
    "content": "absurd :: Void -> a"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet01.ml",
    "content": "'a -> ('b -> 'c)\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet02.ml",
    "content": "'a -> 'b -> 'c\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet03.ml",
    "content": "let catstr s s' = String.concat ~sep:\"\" [ s; s' ]\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet04.ml",
    "content": "let catstr s s' = String.concat ~sep:\"\" [ s; s' ]\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet05.ml",
    "content": "let greet = catstr \"Hello\"\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet06.ml",
    "content": "'a * 'b -> 'a\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet07.ml",
    "content": "let curry f a b = f (a, b)\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet08.ml",
    "content": "let uncurry f p = f (fst p) (snd p)\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet09.ml",
    "content": "let factorizer g a b = g (a, b)\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet10.ml",
    "content": "module type Exponential_Of_Sums_Example = sig\n  val f : (int, float) either -> string\nend\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet11.ml",
    "content": "module Exp_Sum_Impl : Exponential_Of_Sums_Example = struct\n  let f = function\n    | Left n -> if n < 0 then \"Negative int\" else \"Positive int\"\n    | Right x ->\n      if Float.compare x 0.4 < 0\n      then \"Negative double\"\n      else \"Positive double\"\n  ;;\nend\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet12.ml",
    "content": "val eval : (('a -> 'b), 'a) -> 'b \n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet13.ml",
    "content": "let eval (f, a) = f a\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet14.ml",
    "content": "('a, 'b) either -> 'a\n"
  },
  {
    "path": "src/content/1.9/code/ocaml/snippet15.ml",
    "content": "val absurd : void -> 'a\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet01.re",
    "content": "'a => ('b => 'c)\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet02.re",
    "content": "'a => 'b => 'c\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet03.re",
    "content": "let catstr = (s, s') => String.concat(~sep=\"\", [s, s']);\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet04.re",
    "content": "let catstr = (s, s') => String.concat(~sep=\"\", [s, s']);\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet05.re",
    "content": "let greet = catstr(\"Hello\");\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet06.re",
    "content": "('a, 'b) => 'a"
  },
  {
    "path": "src/content/1.9/code/reason/snippet07.re",
    "content": "let curry = (f, a, b) => f((a, b));\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet08.re",
    "content": "let uncurry = (f, p) => f(fst(p), snd(p));\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet09.re",
    "content": "let factorizer = (g, a, b) => g((a, b));\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet10.re",
    "content": "module type Exponential_Of_Sums_Example = {\n  let f: either(int, float) => string;\n};\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet11.re",
    "content": "module Exp_Sum_Impl: Exponential_Of_Sums_Example = {\n  let f =\n    fun\n    | Left(n) => n < 0 ? \"Negative int\" : \"Positive int\"\n    | Right(x) => x < 0.0 ? \"Negative double\" : \"Positive double\"\n};\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet12.re",
    "content": "let eval: (('a => 'b), 'a) => 'b"
  },
  {
    "path": "src/content/1.9/code/reason/snippet13.re",
    "content": "let eval = ((f, a)) => f(a);\n"
  },
  {
    "path": "src/content/1.9/code/reason/snippet14.re",
    "content": "either('a, 'b) => 'a"
  },
  {
    "path": "src/content/1.9/code/reason/snippet15.re",
    "content": "let absurd: void => 'a"
  },
  {
    "path": "src/content/1.9/code/scala/snippet01.scala",
    "content": "A => (B => C)"
  },
  {
    "path": "src/content/1.9/code/scala/snippet02.scala",
    "content": "A => B => C"
  },
  {
    "path": "src/content/1.9/code/scala/snippet03.scala",
    "content": "val catstr: (String, String) => String =\n  (s, s1) => s ++ s1"
  },
  {
    "path": "src/content/1.9/code/scala/snippet04.scala",
    "content": "val catstrᛌ: String => String => String = \n  s => s1 => s ++ s1"
  },
  {
    "path": "src/content/1.9/code/scala/snippet05.scala",
    "content": "val greet: String => String =\n  catstr(\"Hello \", _)"
  },
  {
    "path": "src/content/1.9/code/scala/snippet06.scala",
    "content": "(A, B) => C"
  },
  {
    "path": "src/content/1.9/code/scala/snippet07.scala",
    "content": "def curry[A, B, C](f: (A, B) => C): A => B => C =\n  a => b => f(a, b)"
  },
  {
    "path": "src/content/1.9/code/scala/snippet08.scala",
    "content": "def uncurry[A, B, C](f: A => B => C): (A, B) => C =\n  (a, b) => f(a)(b)"
  },
  {
    "path": "src/content/1.9/code/scala/snippet09.scala",
    "content": "def factorizer[A, B, C](g: (A, B) => C): A => (B => C) =\n  a => (b => g(a, b))"
  },
  {
    "path": "src/content/1.9/code/scala/snippet10.scala",
    "content": "val f: Either[Int, Double] => String"
  },
  {
    "path": "src/content/1.9/code/scala/snippet11.scala",
    "content": "val f: Either[Int, Double] => String = {\n  case Left(n) => if (n < 0) \"Negative int\" else \"Positive int\"\n  case Right(x) => if (x < 0.0) \"Negative double\" else \"Positive double\"\n}"
  },
  {
    "path": "src/content/1.9/code/scala/snippet12.scala",
    "content": "def eval[A, B]: ((A => B), A) => B"
  },
  {
    "path": "src/content/1.9/code/scala/snippet13.scala",
    "content": "def eval[A, B]: ((A => B), A) => B =\n  (f, x) => f(x)"
  },
  {
    "path": "src/content/1.9/code/scala/snippet14.scala",
    "content": "Either[A, B] => A"
  },
  {
    "path": "src/content/1.9/code/scala/snippet15.scala",
    "content": "def absurd[A]: Nothing => A"
  },
  {
    "path": "src/content/1.9/function-types.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{S}{o far} I've been glossing over the meaning of function types. A function\ntype is different from other types.\n\nTake \\code{Integer}, for instance: It's just a set of integers.\n\\code{Bool} is a two element set. But a function type\n$a\\to b$ is more than that: it's a set of morphisms\nbetween objects $a$ and $b$. A set of morphisms between\ntwo objects in any category is called a hom-set. It just so happens that\nin the category $\\Set$ every hom-set is itself an object in the\nsame category ---because it is, after all, a \\emph{set}.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/set-hom-set.jpg}\n  \\caption{Hom-set in Set is just a set}\n\\end{figure}\n\n\\noindent\nThe same is not true of other categories where hom-sets are external to\na category. They are even called \\emph{external} hom-sets.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/hom-set.jpg}\n  \\caption{Hom-set in category C is an external set}\n\\end{figure}\n\n\\noindent\nIt's the self-referential nature of the category $\\Set$ that makes\nfunction types special. But there is a way, at least in some categories,\nto construct objects that represent hom-sets. Such objects are called\n\\newterm{internal} hom-sets.\n\n\\section{Universal Construction}\n\nLet's forget for a moment that function types are sets and try to\nconstruct a function type, or more generally, an internal hom-set, from\nscratch. As usual, we'll take our cues from the $\\Set$ category,\nbut carefully avoid using any properties of sets, so that the\nconstruction will automatically work for other categories.\n\nA function type may be considered a composite type because of its\nrelationship to the argument type and the result type. We've already\nseen the constructions of composite types --- those that involved\nrelationships between objects. We used universal constructions to define\na \\hyperref[products-and-coproducts]{product\n  and coproduct types}. We can use the same trick to define a\nfunction type. We will need a pattern that involves three objects: the\nfunction type that we are constructing, the argument type, and the\nresult type.\n\nThe obvious pattern that connects these three types is called\n\\newterm{function application} or \\newterm{evaluation}. Given a candidate for\na function type, let's call it $z$ (notice that, if we are not in\nthe category $\\Set$, this is just an object like any other\nobject), and the argument type $a$ (an object), the application\nmaps this pair to the result type $b$ (an object). We have three\nobjects, two of them fixed (the ones representing the argument type and\nthe result type).\n\nWe also have the application, which is a mapping. How do we incorporate\nthis mapping into our pattern? If we were allowed to look inside\nobjects, we could pair a function $f$ (an element of $z$)\nwith an argument $x$ (an element of $a$) and map it to\n$f x$ (the application of $f$ to $x$, which is an\nelement of $b$).\n\n\\begin{figure}[H]\n  \\centering\\includegraphics[width=0.35\\textwidth]{images/functionset.jpg}\n  \\caption{In Set we can pick a function $f$ from a set of functions $z$ and we can\n    pick an argument $x$ from the set (type) $a$. We get an element $f x$ in the\n    set (type) $b$.}\n\\end{figure}\n\n\\noindent\nBut instead of dealing with individual pairs $(f, x)$, we can as\nwell talk about the whole \\emph{product} of the function type $z$\nand the argument type $a$. The product $z\\times{}a$ is an object,\nand we can pick, as our application morphism, an arrow $g$ from\nthat object to $b$. In $\\Set$, $g$ would be the\nfunction that maps every pair $(f, x)$ to $f x$.\n\nSo that's the pattern: a product of two objects $z$ and\n$a$ connected to another object $b$ by a morphism $g$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/functionpattern.jpg}\n  \\caption{A pattern of objects and morphisms that is the starting point of the\n    universal construction}\n\\end{figure}\n\n\\noindent\nIs this pattern specific enough to single out the function type using a\nuniversal construction? Not in every category. But in the categories of\ninterest to us it is. And another question: Would it be possible to\ndefine a function object without first defining a product? There are\ncategories in which there is no product, or there isn't a product for\nall pairs of objects. The answer is no: there is no function type, if\nthere is no product type. We'll come back to this later when we talk\nabout exponentials.\n\nLet's review the universal construction. We start with a pattern of\nobjects and morphisms. That's our imprecise query, and it usually yields\nlots and lots of hits. In particular, in $\\Set$, pretty much\neverything is connected to everything. We can take any object\n$z$, form its product with $a$, and there's going to be a\nfunction from it to $b$ (except when $b$ is an empty set).\n\nThat's when we apply our secret weapon: ranking. This is usually done by\nrequiring that there be a unique mapping between candidate objects --- a\nmapping that somehow factorizes our construction. In our case, we'll\ndecree that $z$ together with the morphism $g$ from\n$z \\times a$ to $b$ is \\emph{better} than some other\n$z'$ with its own application $g'$, if and\nonly if there is a unique mapping $h$ from $z'$ to\n$z$ such that the application of $g'$ factors\nthrough the application of $g$. (Hint: Read this sentence while\nlooking at the picture.)\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/functionranking.jpg}\n  \\caption{Establishing a ranking between candidates for the function object}\n\\end{figure}\n\n\\noindent\nNow here's the tricky part, and the main reason I postponed this\nparticular universal construction till now. Given the morphism\n$h \\Colon z'\\to z$, we want to close the diagram\nthat has both $z'$ and $z$ crossed with $a$.\nWhat we really need, given the mapping $h$ from $z'$\nto $z$, is a mapping from $z' \\times a$ to $z \\times a$.\nAnd now, after discussing the \\hyperref[functoriality]{functoriality\n  of the product}, we know how to do it. Because the product itself is a\nfunctor (more precisely an endo-bi-functor), it's possible to lift pairs\nof morphisms. In other words, we can define not only products of objects\nbut also products of morphisms.\n\nSince we are not touching the second component of the product\n$z' \\times a$, we will lift the pair of morphisms\n$(h, \\id)$, where $\\id$ is an identity on $a$.\n\nSo, here's how we can factor one application, $g$, out of another\napplication $g'$:\n\\[g' = g \\circ (h \\times \\id)\\]\nThe key here is the action of the product on morphisms.\n\nThe third part of the universal construction is selecting the object\nthat is universally the best. Let's call this object $a \\Rightarrow b$ (think\nof this as a symbolic name for one object, not to be confused with a\nHaskell typeclass constraint --- I'll discuss different ways of naming\nit later). This object comes with its own application --- a morphism\nfrom $(a \\Rightarrow b) \\times a$ to $b$ --- which we will call\n$\\mathit{eval}$. The object \\code{$a \\Rightarrow b$} is the best if any other\ncandidate for a function object can be uniquely mapped to it in such a\nway that its application morphism $g$ factorizes through\n$\\mathit{eval}$. This object is better than any other object according to\nour ranking.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/universalfunctionobject.jpg}\n  \\caption{The definition of the universal function object. This is the same\n    diagram as above, but now the object $a \\Rightarrow b$ is \\emph{universal}.}\n\\end{figure}\n\n\\noindent\nFormally:\n\n\\begin{longtable}[]{@{}l@{}}\n  \\toprule\n  \\begin{minipage}[t]{0.97\\columnwidth}\\raggedright\\strut\n    A \\emph{function object} from $a$ to $b$ is an object\n    $a \\Rightarrow b$ together with the morphism\n    \\[\\mathit{eval} \\Colon ((a \\Rightarrow b) \\times a) \\to b\\]\n    such that for any other object $z$ with a morphism\n    \\[g \\Colon z \\times a \\to b\\]\n    there is a unique morphism\n    \\[h \\Colon z \\to (a \\Rightarrow b)\\]\n    that factors $g$ through $\\mathit{eval}$:\n    \\[g = \\mathit{eval} \\circ (h \\times \\id)\\]\n  \\end{minipage}\\tabularnewline\n  \\bottomrule\n\\end{longtable}\n\n\\noindent\nOf course, there is no guarantee that such an object $a \\Rightarrow b$ exists\nfor any pair of objects $a$ and $b$ in a given category.\nBut it always does in $\\Set$. Moreover, in $\\Set$, this\nobject is isomorphic to the hom-set $\\Set(a, b)$.\n\nThis is why, in Haskell, we interpret the function type\n\\code{a -> b} as the categorical function object $a \\Rightarrow b$.\n\n\\section{Currying}\n\nLet's have a second look at all the candidates for the function object.\nThis time, however, let's think of the morphism $g$ as a function\nof two variables, $z$ and $a$.\n\\[g \\Colon z \\times a \\to b\\]\nBeing a morphism from a product comes as close as it gets to being a\nfunction of two variables. In particular, in $\\Set$, $g$ is\na function from pairs of values, one from the set $z$ and one\nfrom the set $a$.\n\nOn the other hand, the universal property tells us that for each such\n$g$ there is a unique morphism $h$ that maps $z$ to\na function object $a \\Rightarrow b$.\n\\[h \\Colon z \\to (a \\Rightarrow b)\\]\nIn $\\Set$, this just means that $h$ is a function that\ntakes one variable of type $z$ and returns a function from\n$a$ to $b$. That makes $h$ a higher order function.\nTherefore the universal construction establishes a one-to-one\ncorrespondence between functions of two variables and functions of one\nvariable returning functions. This correspondence is called\n\\newterm{currying}, and $h$ is called the curried version of $g$.\n\nThis correspondence is one-to-one, because given any $g$ there is\na unique $h$, and given any $h$ you can always recreate\nthe two-argument function $g$ using the formula:\n\\[g = \\mathit{eval} \\circ (h \\times \\id)\\]\nThe function $g$ can be called the \\emph{uncurried} version of $h$.\n\nCurrying is essentially built into the syntax of Haskell. A function\nreturning a function:\n\n\\src{snippet01}\nis often thought of as a function of two variables. That's how we read\nthe un-parenthesized signature:\n\n\\src{snippet02}\nThis interpretation is apparent in the way we define multi-argument\nfunctions. For instance:\n\n\\src{snippet03}\nThe same function can be written as a one-argument function returning a\nfunction --- a lambda:\n\n\\src{snippet04}\nThese two definitions are equivalent, and either can be partially\napplied to just one argument, producing a one-argument function, as in:\n\n\\src{snippet05}\nStrictly speaking, a function of two variables is one that takes a pair\n(a product type):\n\n\\src{snippet06}\nIt's trivial to convert between the two representations, and the two\n(higher-order) functions that do it are called, unsurprisingly,\n\\code{curry} and \\code{uncurry}:\n\n\\src{snippet07}\nand\n\n\\src{snippet08}\nNotice that \\code{curry} is the \\emph{factorizer} for the universal\nconstruction of the function object. This is especially apparent if it's\nrewritten in this form:\n\n\\src{snippet09}\n(As a reminder: A factorizer produces the factorizing function from a\ncandidate.)\n\nIn non-functional languages, like C++, currying is possible but\nnontrivial. You can think of multi-argument functions in C++ as\ncorresponding to Haskell functions taking tuples (although, to confuse\nthings even more, in C++ you can define functions that take an explicit\n\\code{std::tuple}, as well as variadic functions, and functions taking\ninitializer lists).\n\nYou can partially apply a C++ function using the template\n\\code{std::bind}. For instance, given a function of two strings:\n\n\\begin{snip}{cpp}\nstd::string catstr(std::string s1, std::string s2) {\n    return s1 + s2;\n}\n\\end{snip}\nyou can define a function of one string:\n\n\\begin{snip}{cpp}\nusing namespace std::placeholders;\n\nauto greet = std::bind(catstr, \"Hello \", _1);\nstd::cout << greet(\"Haskell Curry\");\n\\end{snip}\nScala, which is more functional than C++ or Java, falls somewhere in\nbetween. If you anticipate that the function you're defining will be\npartially applied, you define it with multiple argument lists:\n\n\\begin{snip}{cpp}\ndef catstr(s1: String)(s2: String) = s1 + s2\n\\end{snip}\nOf course that requires some amount of foresight or prescience on the\npart of a library writer.\n\n\\section{Exponentials}\n\nIn mathematical literature, the function object, or the internal\nhom-object between two objects $a$ and $b$, is often\ncalled the \\newterm{exponential} and denoted by $b^{a}$. Notice that\nthe argument type is in the exponent. This notation might seem strange\nat first, but it makes perfect sense if you think of the relationship\nbetween functions and products. We've already seen that we have to use\nthe product in the universal construction of the internal hom-object,\nbut the connection goes deeper than that.\n\nThis is best seen when you consider functions between finite types ---\ntypes that have a finite number of values, like \\code{Bool},\n\\code{Char}, or even \\code{Int} or \\code{Double}. Such functions,\nat least in principle, can be fully memoized or turned into data\nstructures to be looked up. And this is the essence of the equivalence\nbetween functions, which are morphisms, and function types, which are\nobjects.\n\nFor instance a (pure) function from \\code{Bool} is completely\nspecified by a pair of values: one corresponding to \\code{False}, and\none corresponding to \\code{True}. The set of all possible functions\nfrom \\code{Bool} to, say, \\code{Int} is the set of all pairs of\n\\code{Int}s. This is the same as the product \\code{Int} \\times{} \\code{Int} or,\nbeing a little creative with notation, \\code{Int}\\textsuperscript{2}.\n\nFor another example, let's look at the C++ type \\code{char}, which\ncontains 256 values (Haskell \\code{Char} is larger, because Haskell\nuses Unicode). There are several functions in the part of the\nC++ Standard Library that are usually implemented using lookups.\nFunctions like \\code{isupper} or \\code{isspace} are implemented\nusing tables, which are equivalent to tuples of 256 Boolean values. A\ntuple is a product type, so we are dealing with products of 256\nBooleans: \\code{bool \\times{} bool \\times{} bool \\times{} ... \\times{} bool}. We know from\narithmetics that an iterated product defines a power. If you\n``multiply'' \\code{bool} by itself 256 (or \\code{char}) times, you\nget \\code{bool} to the power of \\code{char}, or \\code{bool}\\textsuperscript{\\code{char}}.\n\nHow many values are there in the type defined as 256-tuples of\n\\code{bool}? Exactly $2^{256}$. This is also the number\nof different functions from \\code{char} to \\code{bool}, each\nfunction corresponding to a unique 256-tuple. You can similarly\ncalculate that the number of functions from \\code{bool} to\n\\code{char} is $256^{2}$, and so on. The exponential\nnotation for function types makes perfect sense in these cases.\n\nWe probably wouldn't want to fully memoize a function from \\code{int}\nor \\code{double}. But the equivalence between functions and data\ntypes, if not always practical, is there. There are also infinite types,\nfor instance lists, strings, or trees. Eager memoization of functions\nfrom those types would require infinite storage. But Haskell is a lazy\nlanguage, so the boundary between lazily evaluated (infinite) data\nstructures and functions is fuzzy. This function vs. data duality\nexplains the identification of Haskell's function type with the\ncategorical exponential object --- which corresponds more to our idea of\n\\emph{data}.\n\n\\section{Cartesian Closed Categories}\n\nAlthough I will continue using the category of sets as a model for types\nand functions, it's worth mentioning that there is a larger family of\ncategories that can be used for that purpose. These categories are\ncalled \\newterm{Cartesian closed}, and $\\Set$ is just one example of\nsuch a category.\n\nA Cartesian closed category must contain:\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        The terminal object,\n  \\item\n        A product of any pair of objects, and\n  \\item\n        An exponential for any pair of objects.\n\\end{enumerate}\nIf you consider an exponential as an iterated product (possibly\ninfinitely many times), then you can think of a Cartesian closed\ncategory as one supporting products of an arbitrary arity. In\nparticular, the terminal object can be thought of as a product of zero\nobjects --- or the zero-th power of an object.\n\nWhat's interesting about Cartesian closed categories from the\nperspective of computer science is that they provide models for the\nsimply typed lambda calculus, which forms the basis of all typed\nprogramming languages.\n\nThe terminal object and the product have their duals: the initial object\nand the coproduct. A Cartesian closed category that also supports those\ntwo, and in which product can be distributed over coproduct\n\\begin{gather*}\n  a \\times (b + c) = a \\times b + a \\times c \\\\\n  (b + c) \\times a = b \\times a + c \\times a\n\\end{gather*}\nis called a \\newterm{bicartesian closed} category. We'll see in the next\nsection that bicartesian closed categories, of which $\\Set$ is a\nprime example, have some interesting properties.\n\n\\section{Exponentials and Algebraic Data Types}\n\nThe interpretation of function types as exponentials fits very well into\nthe scheme of algebraic data types. It turns out that all the basic\nidentities from high-school algebra relating numbers zero and one, sums,\nproducts, and exponentials hold pretty much unchanged in any bicartesian\nclosed category for, respectively, initial and final objects,\ncoproducts, products, and exponentials. We don't have the tools yet to\nprove them (such as adjunctions or the Yoneda lemma), but I'll list them\nhere nevertheless as a source of valuable intuitions.\n\n\\subsection{Zeroth Power}\n\n\\[a^{0} = 1\\]\nIn the categorical interpretation, we replace 0 with the initial object,\n1 with the final object, and equality with isomorphism. The exponential\nis the internal hom-object. This particular exponential represents the\nset of morphisms going from the initial object to an arbitrary object\n$a$. By the definition of the initial object, there is exactly\none such morphism, so the hom-set $\\cat{C}(0, a)$ is a singleton set. A\nsingleton set is the terminal object in $\\Set$, so this identity\ntrivially works in $\\Set$. What we are saying is that it works in\nany bicartesian closed category.\n\nIn Haskell, we replace 0 with \\code{Void}; 1 with the unit type\n\\code{()}; and the exponential with function type. The claim is that\nthe set of functions from \\code{Void} to any type \\code{a} is\nequivalent to the unit type --- which is a singleton. In other words,\nthere is only one function \\code{Void -> a}. We've seen\nthis function before: it's called \\code{absurd}.\n\nThis is a little bit tricky, for two reasons. One is that in Haskell we\ndon't really have uninhabited types --- every type contains the ``result\nof a never ending calculation,'' or the bottom. The second reason is\nthat all implementations of \\code{absurd} are equivalent because, no\nmatter what they do, nobody can ever execute them. There is no value\nthat can be passed to \\code{absurd}. (And if you manage to pass it a\nnever ending calculation, it will never return!)\n\n\\subsection{Powers of One}\n\n\\[1^{a} = 1\\]\nThis identity, when interpreted in $\\Set$, restates the definition\nof the terminal object: There is a unique morphism from any object to\nthe terminal object. In general, the internal hom-object from $a$\nto the terminal object is isomorphic to the terminal object itself.\n\nIn Haskell, there is only one function from any type \\code{a} to unit.\nWe've seen this function before --- it's called \\code{unit}. You can\nalso think of it as the function \\code{const} partially applied to\n\\code{()}.\n\n\\subsection{First Power}\n\n\\[a^{1} = a\\]\nThis is a restatement of the observation that morphisms from the\nterminal object can be used to pick ``elements'' of the object\n\\code{a}. The set of such morphisms is isomorphic to the object\nitself. In $\\Set$, and in Haskell, the isomorphism is between\nelements of the set \\code{a} and functions that pick those elements,\n\\code{() -> a}.\n\n\\subsection{Exponentials of Sums}\n\n\\[a^{b+c} = a^{b} \\times a^{c}\\]\nCategorically, this says that the exponential from a coproduct of two\nobjects is isomorphic to a product of two exponentials. In Haskell, this\nalgebraic identity has a very practical interpretation. It tells us\nthat a function from a sum of two types is equivalent to a pair of\nfunctions from individual types. This is just the case analysis that we\nuse when defining functions on sums. Instead of writing one function\ndefinition with a \\code{case} clause, we usually split it into two\n(or more) functions dealing with each type constructor separately. For\ninstance, take a function from the sum type\n\\code{(Either Int Double)}:\n\n\\src{snippet10}\nIt may be defined as a pair of functions from, respectively,\n\\code{Int} and \\code{Double}:\n\n\\src{snippet11}\nHere, \\code{n} is an \\code{Int} and \\code{x} is a \\code{Double}.\n\n\\subsection{Exponentials of Exponentials}\n\n\\[(a^{b})^{c} = a^{b \\times c}\\]\nThis is just a way of expressing currying purely in terms of exponential\nobjects. A function returning a function is equivalent to a function\nfrom a product (a two-argument function).\n\n\\subsection{Exponentials over Products}\n\n\\[(a \\times b)^{c} = a^{c} \\times b^{c}\\]\nIn Haskell: A function returning a pair is equivalent to a pair of\nfunctions, each producing one element of the pair.\n\nIt's pretty incredible how those simple high-school algebraic identities\ncan be lifted to category theory and have practical application in\nfunctional programming.\n\n\\section{Curry-Howard Isomorphism}\n\nI have already mentioned the correspondence between logic and algebraic\ndata types. The \\code{Void} type and the unit type \\code{()}\ncorrespond to false and true. Product types and sum types correspond to\nlogical conjunction $\\wedge$ (AND) and disjunction $\\vee$ (OR). In this scheme, the\nfunction type we have just defined corresponds to logical implication $\\Rightarrow$.\nIn other words, the type \\code{a -> b} can be read as ``if\na then b.''\n\nAccording to the Curry-Howard isomorphism, every type can be interpreted\nas a proposition --- a statement or a judgment that may be true or\nfalse. Such a proposition is considered true if the type is inhabited\nand false if it isn't. In particular, a logical implication is true if\nthe function type corresponding to it is inhabited, which means that\nthere exists a function of that type. An implementation of a function is\ntherefore a proof of a theorem. Writing programs is equivalent to\nproving theorems. Let's see a few examples.\n\nLet's take the function \\code{eval} we have introduced in the\ndefinition of the function object. Its signature is:\n\n\\src{snippet12}\nIt takes a pair consisting of a function and its argument and produces a\nresult of the appropriate type. It's the Haskell implementation of the\nmorphism:\n\n\\[\\mathit{eval} \\Colon (a \\Rightarrow b) \\times a \\to b\\]\nwhich defines the function type $a \\Rightarrow b$ (or the exponential object\n$b^{a}$). Let's translate this signature to a logical predicate\nusing the Curry-Howard isomorphism:\n\n\\[((a \\Rightarrow b) \\wedge a) \\Rightarrow b\\]\nHere's how you can read this statement: If it's true that $b$\nfollows from $a$, and $a$ is true, then $b$ must be\ntrue. This makes perfect intuitive sense and has been known since\nantiquity as \\newterm{modus ponens}. We can prove this theorem by\nimplementing the function:\n\n\\src{snippet13}\nIf you give me a pair consisting of a function \\code{f} taking\n\\code{a} and returning \\code{b}, and a concrete value \\code{x} of\ntype \\code{a}, I can produce a concrete value of type \\code{b} by\nsimply applying the function \\code{f} to \\code{x}. By implementing\nthis function I have just shown that the type\n\\code{((a -> b), a) -> b} is inhabited.\nTherefore \\newterm{modus ponens} is true in our logic.\n\nHow about a predicate that is blatantly false? For instance: if\n$a$ or $b$ is true then $a$ must be true.\n\n\\[a \\vee b \\Rightarrow a\\]\nThis is obviously wrong because you can choose an $a$ that is\nfalse and a $b$ that is true, and that's a counter-example.\n\nMapping this predicate into a function signature using the Curry-Howard\nisomorphism, we get:\n\n\\src{snippet14}\nTry as you may, you can't implement this function --- you can't produce\na value of type \\code{a} if you are called with the \\code{Right}\nvalue. (Remember, we are talking about \\emph{pure} functions.)\n\nFinally, we come to the meaning of the \\code{absurd} function:\n\n\\src{snippet15}\nConsidering that \\code{Void} translates into false, we get:\n\n\\[\\mathit{false} \\Rightarrow a\\]\nAnything follows from falsehood (\\emph{ex falso quodlibet}). Here's one\npossible proof (implementation) of this statement (function) in Haskell:\n\n\\begin{snip}{haskell}\nabsurd (Void a) = absurd a\n\\end{snip}\nwhere \\code{Void} is defined as:\n\n\\begin{snip}{haskell}\nnewtype Void = Void Void\n\\end{snip}\nAs always, the type \\code{Void} is tricky. This definition makes it\nimpossible to construct a value because in order to construct one, you\nwould need to provide one. Therefore, the function \\code{absurd} can\nnever be called.\n\nThese are all interesting examples, but is there a practical side to\nCurry-Howard isomorphism? Probably not in everyday programming. But\nthere are programming languages like Agda or Rocq\\footnote{Formerly known as Coq}, which take advantage\nof the Curry-Howard isomorphism to prove theorems.\n\nComputers are not only helping mathematicians do their work --- they are\nrevolutionizing the very foundations of mathematics. The latest hot\nresearch topic in that area is called Homotopy Type Theory, and is an\noutgrowth of type theory. It's full of Booleans, integers, products and\ncoproducts, function types, and so on. And, as if to dispel any doubts,\nthe theory is being formulated in Rocq and Agda. Computers are\nrevolutionizing the world in more than one way.\n\n\\section{Bibliography}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Ralf Hinze, Daniel W. H. James,\n        \\urlref{http://www.cs.ox.ac.uk/ralf.hinze/publications/WGP10.pdf}{Reason\n          Isomorphically!}. This paper contains proofs of all those high-school\n        algebraic identities in category theory that I mentioned in this\n        chapter.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/2.1/code/haskell/snippet01.hs",
    "content": "h = g . f"
  },
  {
    "path": "src/content/2.1/code/haskell/snippet02.hs",
    "content": "h x = let y = f x\n      in g y"
  },
  {
    "path": "src/content/2.1/code/ocaml/snippet01.ml",
    "content": "(* Assume g and f are already defined *)\nlet h = compose g f\n"
  },
  {
    "path": "src/content/2.1/code/ocaml/snippet02.ml",
    "content": "let h x =\n  let y = f x in\n  g y\n;;\n"
  },
  {
    "path": "src/content/2.1/code/reason/snippet01.re",
    "content": "/* Assume g and f are already defined */\nlet h = compose(g, f);\n"
  },
  {
    "path": "src/content/2.1/code/reason/snippet02.re",
    "content": "let h = x => {\n  let y = f(x);\n  g(y);\n};\n"
  },
  {
    "path": "src/content/2.1/code/scala/snippet01.scala",
    "content": "val h = g compose f"
  },
  {
    "path": "src/content/2.1/code/scala/snippet02.scala",
    "content": "val h = x => {\n  val y = f(x)\n  g(y)\n}"
  },
  {
    "path": "src/content/2.1/declarative-programming.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{n the first part} of the book I argued that both category theory and\nprogramming are about composability. In programming, you keep\ndecomposing a problem until you reach the level of detail that you can\ndeal with, solve each subproblem in turn, and re-compose the solutions\nbottom-up. There are, roughly speaking, two ways of doing it: by telling\nthe computer what to do, or by telling it how to do it. One is called\ndeclarative and the other imperative.\n\nYou can see this even at the most basic level. Composition itself may be\ndefined declaratively; as in, \\code{h} is a composite of \\code{g}\nafter \\code{f}:\n\n\\src{snippet01}\nor imperatively; as in, call \\code{f} first, remember the result of\nthat call, then call \\code{g} with the result:\n\n\\src{snippet02}\nThe imperative version of a program is usually described as a sequence\nof actions ordered in time. In particular, the call to \\code{g} cannot\nhappen before the execution of \\code{f} completes. At least, that's\nthe conceptual picture --- in a lazy language, with \\emph{call-by-need}\nargument passing, the actual execution may proceed differently.\n\nIn fact, depending on the cleverness of the compiler, there may be\nlittle or no difference between how declarative and imperative code is\nexecuted. But the two methodologies differ, sometimes drastically, in\nthe way we approach problem solving and in the maintainability and\ntestability of the resulting code.\n\nThe main question is: when faced with a problem, do we always have the\nchoice between a declarative and imperative approaches to solving it?\nAnd, if there is a declarative solution, can it always be translated\ninto computer code? The answer to this question is far from obvious and,\nif we could find it, we would probably revolutionize our understanding\nof the universe.\n\n\\begin{wrapfigure}{R}{0pt}\n  \\includegraphics[width=0.5\\textwidth]{images/asteroids.png}\n\\end{wrapfigure}\n\nLet me elaborate. There is a similar duality in physics, which either\npoints at some deep underlying principle, or tells us something about\nhow our minds work. Richard Feynman mentions this duality as an\ninspiration in his own work on quantum electrodynamics.\n\nThere are two forms of expressing most laws of physics. One uses local,\nor infinitesimal, considerations. We look at the state of a system\naround a small neighborhood, and predict how it will evolve within the\nnext instant of time. This is usually expressed using differential\nequations that have to be integrated, or summed up, over a period of\ntime.\n\nNotice how this approach resembles imperative thinking: we reach the\nfinal solution by following a sequence of small steps, each depending on\nthe result of the previous one. In fact, computer simulations of\nphysical systems are routinely implemented by turning differential\nequations into difference equations and iterating them. This is how\nspaceships are animated in the asteroids game. At each time step, the\nposition of a spaceship is changed by adding a small increment, which is\ncalculated by multiplying its velocity by the time delta. The velocity,\nin turn, is changed by a small increment proportional to acceleration,\nwhich is given by force divided by mass.\n\nThese are the direct encodings of the differential equations\ncorresponding to Newton's laws of motion:\n\\begin{align*}\n  F & = m \\frac{dv}{dt} \\\\\n  v & = \\frac{dx}{dt}\n\\end{align*}\nSimilar methods may be applied to more complex problems, like the\npropagation of electromagnetic fields using Maxwell's equations, or even\nthe behavior of quarks and gluons inside a proton using lattice \\acronym{QCD}\n(quantum chromodynamics).\n\nThis local thinking combined with discretization of space and time that\nis encouraged by the use of digital computers found its extreme\nexpression in the heroic attempt by Stephen Wolfram to reduce the\ncomplexity of the whole universe to a system of cellular automata.\n\nThe other approach is global. We look at the initial and the final state\nof the system, and calculate a trajectory that connects them by\nminimizing a certain functional. The simplest example is the Fermat's\nprinciple of least time. It states that light rays propagate along paths\nthat minimize their flight time. In particular, in the absence of\nreflecting or refracting objects, a light ray from point $A$ to point $B$\nwill take the shortest path, which is a straight line. But light\npropagates slower in dense (transparent) materials, like water or glass.\nSo if you pick the starting point in the air, and the ending point under\nwater, it's more advantageous for light to travel longer in the air and\nthen take a shortcut through water. The path of minimum time makes the\nray refract at the boundary of air and water, resulting in Snell's law\nof refraction:\n\\begin{equation*}\n  \\frac{sin(\\theta_1)}{sin(\\theta_2)} = \\frac{v_1}{v_2}\n\\end{equation*}\nwhere $v_1$ is the speed of light in the air and $v_2$ is\nthe speed of light in the water.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/snell.jpg}\n\\end{figure}\n\n\\noindent\nAll of classical mechanics can be derived from the principle of least\naction. The action can be calculated for any trajectory by integrating\nthe Lagrangian, which is the difference between kinetic and potential\nenergy (notice: it's the difference, not the sum --- the sum would be\nthe total energy). When you fire a mortar to hit a given target, the\nprojectile will first go up, where the potential energy due to gravity\nis higher, and spend some time there racking up negative contribution to\nthe action. It will also slow down at the top of the parabola, to\nminimize kinetic energy. Then it will speed up to go quickly through the\narea of low potential energy.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/mortar.jpg}\n\\end{figure}\n\n\\noindent\nFeynman's greatest contribution was to realize that the principle of\nleast action can be generalized to quantum mechanics. There, again, the\nproblem is formulated in terms of initial state and final state. The\nFeynman path integral between those states is used to calculate the\nprobability of transition.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/feynman.jpg}\n\\end{figure}\n\n\\noindent\nThe point is that there is a curious unexplained duality in the way we\ncan describe the laws of physics. We can use the local picture, in which\nthings happen sequentially and in small increments. Or we can use the\nglobal picture, where we declare the initial and final conditions, and\neverything in between just follows.\n\nThe global approach can be also used in programming, for instance when\nimplementing ray tracing. We declare the position of the eye and the\npositions of light sources, and figure out the paths that the light rays\nmay take to connect them. We don't explicitly minimize the time of\nflight for each ray, but we do use Snell's law and the geometry of\nreflection to the same effect.\n\nThe biggest difference between the local and the global approach is in\ntheir treatment of space and, more importantly, time. The local approach\nembraces the immediate gratification of here and now, whereas the global\napproach takes a long-term static view, as if the future had been\npreordained, and we were only analyzing the properties of some eternal\nuniverse.\n\nNowhere is it better illustrated than in the Functional Reactive\nProgramming (\\acronym{FRP}) approach to user interaction. Instead of writing separate\nhandlers for every possible user action, all having access to some\nshared mutable state, \\acronym{FRP} treats external events as an infinite list,\nand applies a series of transformations to it. Conceptually, the list of\nall our future actions is there, available as the input data to our\nprogram. From a program's perspective there's no difference between the\nlist of digits of $\\pi$, a list of pseudo-random numbers, or a list of mouse\npositions coming through computer hardware. In each case, if you want to\nget the $n^\\text{th}$ item, you have to first go through the first $n-1$ items. When\napplied to temporal events, we call this property \\emph{causality}.\n\nSo what does it have to do with category theory? I will argue that\ncategory theory encourages a global approach and therefore supports\ndeclarative programming. First of all, unlike calculus, it has no\nbuilt-in notion of distance, or neighborhood, or time. All we have is\nabstract objects and abstract connections between them. If you can get\nfrom $A$ to $B$ through a series of steps, you can also get there in one\nleap. Moreover, the major tool of category theory is the universal\nconstruction, which is the epitome of a global approach. We've seen it\nin action, for instance, in the definition of the categorical product.\nIt was done by specifying its properties --- a very declarative\napproach. It's an object equipped with two projections, and it's the\nbest such object --- it optimizes a certain property: the property of\nfactorizing the projections of other such objects.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/productranking.jpg}\n\\end{figure}\n\n\\noindent\nCompare this with Fermat's principle of minimum time, or the principle\nof least action.\n\nConversely, contrast this with the traditional definition of a Cartesian\nproduct, which is much more imperative. You describe how to create an\nelement of the product by picking one element from one set and another\nelement from another set. It's a recipe for creating a pair. And there's\nanother for disassembling a pair.\n\nIn almost every programming language, including functional languages\nlike Haskell, product types, coproduct types, and function types are\nbuilt in, rather than being defined by universal constructions; although\nthere have been attempts at creating categorical programming languages\n(see, e.g.,\n\\urlref{http://web.sfc.keio.ac.jp/~hagino/thesis.pdf}{Tatsuya\n  Hagino's thesis}).\n\nWhether used directly or not, categorical definitions justify\npre-existing programming constructs, and give rise to new ones. Most\nimportantly, category theory provides a meta-language for reasoning\nabout computer programs at a declarative level. It also encourages\nreasoning about problem specification before it is cast into code.\n"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet01.hs",
    "content": "p' = p . m\nq' = q . m"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet02.hs",
    "content": "contramap :: (c' -> c) -> (c -> LimD) -> (c' -> LimD) \ncontramap f u = u . f"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet03.hs",
    "content": "f :: a -> b \ng :: a -> b"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet04.hs",
    "content": "p :: c -> a \nq :: c -> b"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet05.hs",
    "content": "q = f . p \nq = g . p"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet06.hs",
    "content": "f . p = g . p"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet07.hs",
    "content": "f (x, y) = 2 * y + x\ng (x, y) = y - x"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet08.hs",
    "content": "p t = (t, (-2) * t)"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet09.hs",
    "content": "f . p' = g . p'"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet10.hs",
    "content": "p'() = (0, 0)"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet11.hs",
    "content": "p' = p . h"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet12.hs",
    "content": "h () = 0"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet13.hs",
    "content": "f :: a -> b\ng :: c -> b"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet14.hs",
    "content": "p :: d -> a\nq :: d -> c\nr :: d -> b"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet15.hs",
    "content": "g . q = f . p"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet16.hs",
    "content": "f x = 1.23"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet17.hs",
    "content": "newtype ToString a = ToString (a -> String) \ninstance Contravariant ToString where \n    contramap f (ToString g) = ToString (g . f)"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet18.hs",
    "content": "ToString (Either b c) ~ (b -> String, c -> String)"
  },
  {
    "path": "src/content/2.2/code/haskell/snippet19.hs",
    "content": "r -> (a, b) ~ (r -> a, r -> b)"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet01.ml",
    "content": "let p1 = compose p m\nlet q1 = compose q m\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet02.ml",
    "content": "let contramap : ('c_prime -> 'c) -> ('c -> 'limD) -> 'c_prime -> 'limD\n  =\n fun f u -> compose u f\n;;\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet03.ml",
    "content": "val f : 'a -> 'b\nval g : 'a -> 'b\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet04.ml",
    "content": "val p : 'c -> 'a\nval q : 'c -> 'b\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet05.ml",
    "content": "q = compose f p\nq = compose g p\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet06.ml",
    "content": "(** Pseudo OCaml expressing function equality **)\ncompose f p = compose g p\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet07.ml",
    "content": "let f (x, y) = (2 * y) + x\nlet g (x, y) = y - x\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet08.ml",
    "content": "let p t = t, -2 * t\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet09.ml",
    "content": "(** Pseudo OCaml expressing function equality **)\ncompose f p' = compose g p'\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet10.ml",
    "content": "let p' () = 0, 0\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet11.ml",
    "content": "let p' = compose p h\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet12.ml",
    "content": "let h () = 0\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet13.ml",
    "content": "val f : 'a -> 'b\nval g : 'c -> 'b\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet14.ml",
    "content": "val p : 'd -> 'a\nval q : 'd -> 'c\nval r : 'd -> 'b\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet15.ml",
    "content": "compose g q = compose f p\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet16.ml",
    "content": "let f x = 1.23\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet17.ml",
    "content": "module type Contravariant = sig\n  type 'a t\n\n  val contramap : ('b -> 'a) -> 'a t -> 'b t\nend\n\ntype 'a tostring = ToString of ('a -> string)\n\nmodule ToStringInstance : Contravariant = struct\n  type 'a t = 'a tostring\n\n  let contramap f (ToString g) = ToString (compose g f)\nend\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet18.ml",
    "content": "('b 'c either) tostring ~ ('b -> string, 'c -> string)\n"
  },
  {
    "path": "src/content/2.2/code/ocaml/snippet19.ml",
    "content": "'r -> ('a, 'b) ~ ('r -> 'a, 'r -> 'b)\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet01.re",
    "content": "let p1 = compose(p, m);\nlet q1 = compose(q, m);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet02.re",
    "content": "let contramap: ('c_prime => 'c, 'c => 'limD, 'c_prime) => 'limD = (\n  (f, u) => compose(u, f): \n    ('c_prime => 'c, 'c => 'limD, 'c_prime) => 'limD\n);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet03.re",
    "content": "let f: 'a => 'b\nlet g: 'a => 'b\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet04.re",
    "content": "let p: 'c => 'a\nlet q: 'c => 'b\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet05.re",
    "content": "q == compose(f, p);\nq == compose(g, p);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet06.re",
    "content": "/* Pseudo ReasonML expressing function equality */\ncompose(f, p) == compose(g, p);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet07.re",
    "content": "let f = ((x, y)) => 2 * y + x;\nlet g = ((x, y)) => y - x;\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet08.re",
    "content": "let p = t => (t, (-2) * t);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet09.re",
    "content": "/* Pseudo ReasonML expressing function equality */\ncompose(f, p') == compose(g, p');\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet10.re",
    "content": "let p' = () => (0, 0);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet11.re",
    "content": "let p' = compose(p, h);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet12.re",
    "content": "let h = () => 0;\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet13.re",
    "content": "let f: 'a => 'b\nlet g: 'c => 'b\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet14.re",
    "content": "let p: 'd => 'a\nlet q: 'd => 'c\nlet r: 'd => 'b\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet15.re",
    "content": "compose(g, q) == compose(f, p);\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet16.re",
    "content": "let f = x => 1.23;\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet17.re",
    "content": "module type Contravariant = {\n  type t('a);\n  let contramap: ('b => 'a, t('a)) => t('b);\n};\n\ntype tostring('a) =\n  | ToString('a => string);\n\nmodule ToStringInstance: Contravariant = {\n  type t('a) = tostring('a);\n  \n  let contramap = (f, ToString(g)) => ToString(compose(g, f));\n};\n"
  },
  {
    "path": "src/content/2.2/code/reason/snippet18.re",
    "content": "toString((either('b, 'c))) ~ (b => string, c => string)"
  },
  {
    "path": "src/content/2.2/code/reason/snippet19.re",
    "content": "'r => ('a, 'b) ~ ('r => 'a, 'r => 'b)"
  },
  {
    "path": "src/content/2.2/code/scala/snippet01.scala",
    "content": "val p1 = p compose m\nval q1 = q compose m"
  },
  {
    "path": "src/content/2.2/code/scala/snippet02.scala",
    "content": "def contramap[C, C1, D[_]](f: C1 => C, u: C => Lim[D]): (C1 => Lim[D]) =\n  u compose f"
  },
  {
    "path": "src/content/2.2/code/scala/snippet03.scala",
    "content": "val f : A => B\nval g : A => B"
  },
  {
    "path": "src/content/2.2/code/scala/snippet04.scala",
    "content": "val p : C => A\nval q : C => B"
  },
  {
    "path": "src/content/2.2/code/scala/snippet05.scala",
    "content": "q == f compose p\nq == g compose p"
  },
  {
    "path": "src/content/2.2/code/scala/snippet06.scala",
    "content": "f compose p == g compose p"
  },
  {
    "path": "src/content/2.2/code/scala/snippet07.scala",
    "content": "def f(x, y) = 2 * y + x\ndef g(x, y) = y - x"
  },
  {
    "path": "src/content/2.2/code/scala/snippet08.scala",
    "content": "def p(t) = (t, (-2) * t)"
  },
  {
    "path": "src/content/2.2/code/scala/snippet09.scala",
    "content": "f compose p1 == g compose p1"
  },
  {
    "path": "src/content/2.2/code/scala/snippet10.scala",
    "content": "def p1 : Unit => (Double, Double) = _ => (0, 0)"
  },
  {
    "path": "src/content/2.2/code/scala/snippet11.scala",
    "content": "val p1 = p compose h"
  },
  {
    "path": "src/content/2.2/code/scala/snippet12.scala",
    "content": "def h(_,_) = 0"
  },
  {
    "path": "src/content/2.2/code/scala/snippet13.scala",
    "content": "val f : A => B\nval g : C => B"
  },
  {
    "path": "src/content/2.2/code/scala/snippet14.scala",
    "content": "val p : D => A\nval q : D => C\nval r : D => B"
  },
  {
    "path": "src/content/2.2/code/scala/snippet15.scala",
    "content": "g compose q == f compose p"
  },
  {
    "path": "src/content/2.2/code/scala/snippet16.scala",
    "content": "f(x) == 1.23"
  },
  {
    "path": "src/content/2.2/code/scala/snippet17.scala",
    "content": "trait Contravariant[F[_]] {\n  def contramap[A, B](fa: F[A])(f: B => A) : F[B]\n}\n\nclass ToString[A](f: A => String) extends AnyVal \n\nimplicit val contravariant = new Contravariant[ToString] {\n  def contramap[A, B](fa: ToString[A])(f: B => A): ToString[B] =\n    ToString(fa.f compose f)\n}"
  },
  {
    "path": "src/content/2.2/code/scala/snippet18.scala",
    "content": "ToString[Either[B, C]] ~ (B => String, C => String)"
  },
  {
    "path": "src/content/2.2/code/scala/snippet19.scala",
    "content": "R => (A, B) ~ (R => A, R => B)"
  },
  {
    "path": "src/content/2.2/limits-and-colimits.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{t seems like in category theory} everything is related to everything and\neverything can be viewed from many angles. Take for instance the\nuniversal construction of the \\hyperref[products-and-coproducts]{product}.\nNow that we know more about \\hyperref[functors]{functors} and\n\\hyperref[natural-transformations]{natural transformations}, can we simplify and, possibly, generalize it? Let us\ntry.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/productpattern.jpg}\n\\end{figure}\n\n\\noindent\nThe construction of a product starts with the selection of two objects\n$a$ and $b$, whose product we want to construct. But what\ndoes it mean to \\emph{select objects}? Can we rephrase this action in\nmore categorical terms? Two objects form a pattern --- a very simple\npattern. We can abstract this pattern into a category --- a very simple\ncategory, but a category nevertheless. It's a category that we'll call\n$\\cat{2}$. It contains just two objects, $1$ and $2$, and no morphisms\nother than the two obligatory identities. Now we can rephrase the\nselection of two objects in $\\cat{C}$ as the act of defining a functor $D$\nfrom the category $\\cat{2}$ to $\\cat{C}$. A functor maps objects to\nobjects, so its image is just two objects (or it could be one, if the\nfunctor collapses objects, which is fine too). It also maps morphisms\n--- in this case it simply maps identity morphisms to identity\nmorphisms.\n\nWhat's great about this approach is that it builds on categorical\nnotions, eschewing the imprecise descriptions like ``selecting\nobjects,'' taken straight from the hunter-gatherer lexicon of our\nancestors. And, incidentally, it is also easily generalized, because\nnothing can stop us from using categories more complex than $\\cat{2}$\nto define our patterns.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/two.jpg}\n\\end{figure}\n\n\\noindent\nBut let's continue. The next step in the definition of a product is the\nselection of the candidate object $c$. Here again, we could\nrephrase the selection in terms of a functor from a singleton category.\nAnd indeed, if we were using Kan extensions, that would be the right\nthing to do. But since we are not ready for Kan extensions yet, there is\nanother trick we can use: a constant functor $\\Delta$ from the same category\n$\\cat{2}$ to $\\cat{C}$. The selection of $c$ in $\\cat{C}$ can be\ndone with $\\Delta_c$. Remember, $\\Delta_c$ maps all\nobjects into $c$ and all morphisms into $\\idarrow[c]$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/twodelta.jpg}\n\\end{figure}\n\n\\noindent\nNow we have two functors, $\\Delta_c$ and $D$ going between\n$\\cat{2}$ and $\\cat{C}$ so it's only natural to ask about natural\ntransformations between them. Since there are only two objects in\n$\\cat{2}$, a natural transformation will have two components. Object $1$\nin $\\cat{2}$ is mapped to $c$ by $\\Delta_c$ and to\n$a$ by $D$. So the component of a natural transformation between\n$\\Delta_c$ and $D$ at $1$ is a morphism from $c$ to\n$a$. We can call it $p$. Similarly, the second component\nis a morphism $q$ from $c$ to $b$ --- the image of\nthe object $2$ in $\\cat{2}$ under $D$. But these are exactly like the two\nprojections we used in our original definition of the product. So\ninstead of talking about selecting objects and projections, we can just\ntalk about picking functors and natural transformations. It so happens\nthat in this simple case the naturality condition for our transformation\nis trivially satisfied, because there are no morphisms (other than the\nidentities) in $\\cat{2}$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/productcone.jpg}\n\\end{figure}\n\n\\noindent\nA generalization of this construction to categories other than\n$\\cat{2}$ --- ones that, for instance, contain non-trivial morphisms\n--- will impose naturality conditions on the transformation between\n$\\Delta_c$ and $D$. We call such a transformation a \\emph{cone},\nbecause the image of $\\Delta$ is the apex of a cone/pyramid whose sides are\nformed by the components of the natural transformation. The image of $D$\nforms the base of the cone.\n\nIn general, to build a cone, we start with a category $\\cat{I}$ that\ndefines the pattern. It's a small, often finite category. We pick a\nfunctor $D$ from $\\cat{I}$ to $\\cat{C}$ and call it (or its image) a\n\\emph{diagram}. We pick some $c$ in $\\cat{C}$ as the apex of our\ncone. We use it to define the constant functor $\\Delta_c$ from\n$\\cat{I}$ to $\\cat{C}$. A natural transformation from $\\Delta_c$\nto $D$ is then our cone. For a finite $\\cat{I}$ it's just a bunch of\nmorphisms connecting $c$ to the diagram: the image of $\\cat{I}$\nunder $D$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/cone.jpg}\n\\end{figure}\n\n\\noindent\nNaturality requires that all triangles (the walls of the pyramid) in\nthis diagram commute. Indeed, take any morphism $f$ in $\\cat{I}$.\nThe functor $D$ maps it to a morphism $D f$ in $\\cat{C}$, a\nmorphism that forms the base of some triangle. The constant functor\n$\\Delta_c$ maps $f$ to the identity morphism on\n$c$. $\\Delta$ squishes the two ends of the morphism into one object, and\nthe naturality square becomes a commuting triangle. The two arms of this\ntriangle are the components of the natural transformation.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/conenaturality.jpg}\n\\end{figure}\n\n\\noindent\nSo that's one cone. What we are interested in is the \\newterm{universal\n  cone} --- just like we picked a universal object for our definition of a\nproduct.\n\nThere are many ways to go about it. For instance, we may define a\n\\emph{category of cones} based on a given functor $D$. Objects in that\ncategory are cones. Not every object $c$ in $\\cat{C}$ can be an\napex of a cone, though, because there may be no natural transformation\nbetween $\\Delta_c$ and $D$.\n\nTo make it a category, we also have to define morphisms between cones.\nThese would be fully determined by morphisms between their apexes. But\nnot just any morphism will do. Remember that, in our construction of the\nproduct, we imposed the condition that the morphisms between candidate\nobjects (the apexes) must be common factors for the projections. For\ninstance:\n\n\\src{snippet01}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/productranking.jpg}\n\\end{figure}\n\nThis condition translates, in the general case, to the condition that\nthe triangles whose one side is the factorizing morphism all commute.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/conecommutativity.jpg}\n  \\caption{The commuting triangle connecting two cones, with the factorizing\n    morphism $h$ (here, the lower cone is the universal one, with\n    $\\Lim[D]$ as its apex)}\n\\end{figure}\n\n\\noindent\nWe'll take those factorizing morphisms as the morphisms in our category\nof cones. It's easy to check that those morphisms indeed compose, and\nthat the identity morphism is a factorizing morphism as well. Cones\ntherefore form a category.\n\nNow we can define the universal cone as the \\emph{terminal object} in\nthe category of cones. The definition of the terminal object states that\nthere is a unique morphism from any other object to that object. In our\ncase it means that there is a unique factorizing morphism from the apex\nof any other cone to the apex of the universal cone. We call this\nuniversal cone the \\emph{limit} of the diagram $D$, $\\Lim[D]$ (in\nthe literature, you'll often see a left arrow pointing towards $I$\nunder the $\\Lim$ sign). Often, as a shorthand, we call the apex of\nthis cone the limit (or the limit object).\n\nThe intuition is that the limit embodies the properties of the whole\ndiagram in a single object. For instance, the limit of our two-object\ndiagram is the product of two objects. The product (together with the\ntwo projections) contains the information about both objects. And being\nuniversal means that it has no extraneous junk.\n\n\\section{Limit as a Natural Isomorphism}\n\nThere is still something unsatisfying about this definition of a limit.\nI mean, it's workable, but we still have this commutativity condition\nfor the triangles that are linking any two cones. It would be so much\nmore elegant if we could replace it with some naturality condition. But\nhow?\n\nWe are no longer dealing with one cone but with a whole collection (in\nfact, a category) of cones. If the limit exists (and --- let's make it\nclear --- there's no guarantee of that), one of those cones is the\nuniversal cone. For every other cone we have a unique factorizing\nmorphism that maps its apex, let's call it $c$, to the apex of\nthe universal cone, which we named $\\Lim[D]$. (In fact, I can skip\nthe word ``other'', because the identity morphism maps the universal\ncone to itself and it trivially factorizes through itself.) Let me\nrepeat the important part: given any cone, there is a unique morphism of\na special kind. We have a mapping of cones to special morphisms, and\nit's a one-to-one mapping.\n\nThis special morphism is a member of the hom-set $\\cat{C}(c, \\Lim[D])$.\nThe other members of this hom-set are less fortunate, in the sense that\nthey don't factorize the mapping of the two cones. What we want is to be able to\npick, for each $c$, one morphism from the set\n$\\cat{C}(c, \\Lim[D])$ --- a morphism that satisfies the particular\ncommutativity condition. Does that sound like defining a natural\ntransformation? It most certainly does!\n\nBut what are the functors that are related by this transformation?\n\nOne functor is the mapping of $c$ to the set\n$\\cat{C}(c, \\Lim[D])$. It's a functor from $\\cat{C}$ to $\\Set$ ---\nit maps objects to sets. In fact it's a contravariant functor. Here's\nhow we define its action on morphisms: Let's take a morphism $f$\nfrom $c'$ to $c$:\n\\[f \\Colon c' \\to c\\]\nOur functor maps $c'$ to the set\n$\\cat{C}(c', \\Lim[D])$. To define the action of this functor on\n$f$ (in other words, to lift $f$), we have to define the\ncorresponding mapping between $\\cat{C}(c, \\Lim[D])$ and\n$\\cat{C}(c', \\Lim[D])$. So let's pick one element $u$ of\n$\\cat{C}(c, \\Lim[D])$ and see if we can map it to some element of\n$\\cat{C}(c', \\Lim[D])$. An element of a hom-set is a morphism, so\nwe have:\n\\[u \\Colon c \\to \\Lim[D]\\]\nWe can precompose $u$ with $f$ to get:\n\\[u \\circ f \\Colon c' \\to \\Lim[D]\\]\nAnd that's an element of $\\cat{C}(c', \\Lim[D])$--- so indeed, we\nhave found a mapping of morphisms:\n\n\\src{snippet02}\nNotice the inversion in the order of $c$ and $c'$\ncharacteristic of a \\emph{contravariant} functor.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/homsetmapping.jpg}\n\\end{figure}\n\n\\noindent\nTo define a natural transformation, we need another functor that's also\na mapping from $\\cat{C}$ to $\\Set$. But this time we'll consider a\nset of cones. Cones are just natural transformations, so we are looking\nat the set of natural transformations $\\mathit{Nat}(\\Delta_c, D)$. The mapping\nfrom $c$ to this particular set of natural transformations is a\n(contravariant) functor. How can we show that? Again, let's define its\naction on a morphism:\n\\[f \\Colon c' \\to c\\]\nThe lifting of $f$ should be a mapping of natural transformations\nbetween two functors that go from $\\cat{I}$ to $\\cat{C}$:\n\\[\\mathit{Nat}(\\Delta_c, D) \\to \\mathit{Nat}(\\Delta_{c'}, D)\\]\nHow do we map natural transformations? Every natural transformation is a\nselection of morphisms --- its components --- one morphism per element\nof $\\cat{I}$. A component of some $\\alpha$ (a member of $\\mathit{Nat}(\\Delta_c, D)$) at\n$a$ (an object in $\\cat{I}$) is a morphism:\n\\[\\alpha_a \\Colon \\Delta_c a \\to D a\\]\nor, using the definition of the constant functor $\\Delta$,\n\\[\\alpha_a \\Colon c \\to D a\\]\nGiven $f$ and $\\alpha$, we have to construct a $\\beta$, a member of\n$\\mathit{Nat}(\\Delta_{c'}, D)$. Its component at $a$ should be a\nmorphism:\n\\[\\beta_a \\Colon c' \\to D a\\]\nWe can easily get the latter ($\\beta_a$) from the former ($\\alpha_a$) by precomposing it with\n$f$:\n\\[\\beta_a = \\alpha_a \\circ f\\]\nIt's relatively easy to show that those components indeed add up to a\nnatural transformation.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/natmapping.jpg}\n\\end{figure}\n\n\\noindent\nGiven our morphism $f$, we have thus built a mapping between two\nnatural transformations, component-wise. This mapping defines\n\\code{contramap} for the functor:\n\\[c \\to \\mathit{Nat}(\\Delta_c, D)\\]\nWhat I have just done is to show you that we have two (contravariant)\nfunctors from $\\cat{C}$ to $\\Set$. I haven't made any assumptions\n--- these functors always exist.\n\nIncidentally, the first of these functors plays an important role in\ncategory theory, and we'll see it again when we talk about Yoneda's\nlemma. There is a name for contravariant functors from any category\n$\\cat{C}$ to $\\Set$: they are called ``presheaves''. This one is\ncalled a \\newterm{representable presheaf}. The second functor is also a\npresheaf.\n\nNow that we have two functors, we can talk about natural transformations\nbetween them. So without further ado, here's the conclusion: A functor\n$D$ from $\\cat{I}$ to $\\cat{C}$ has a limit $\\Lim[D]$ if and\nonly if there is a natural isomorphism between the two functors I have\njust defined:\n\\[\\cat{C}(c, \\Lim[D]) \\simeq \\mathit{Nat}(\\Delta_c, D)\\]\nLet me remind you what a natural isomorphism is. It's a natural\ntransformation whose every component is an isomorphism, that is to say\nan invertible morphism.\n\nI'm not going to go through the proof of this statement. The procedure\nis pretty straightforward if not tedious. When dealing with natural\ntransformations, you usually focus on components, which are morphisms.\nIn this case, since the target of both functors is $\\Set$, the\ncomponents of the natural isomorphism will be functions. These are\nhigher order functions, because they go from the hom-set to the set of\nnatural transformations. Again, you can analyze a function by\nconsidering what it does to its argument: here the argument will be a\nmorphism --- a member of $\\cat{C}(c, \\Lim[D])$ --- and the result will\nbe a natural transformation --- a member of $\\mathit{Nat}(\\Delta_c, D)$, or\nwhat we have called a cone. This natural transformation, in turn, has\nits own components, which are morphisms. So it's morphisms all the way\ndown, and if you can keep track of them, you can prove the statement.\n\nThe most important result is that the naturality condition for this\nisomorphism is exactly the commutativity condition for the mapping of\ncones.\n\nAs a preview of coming attractions, let me mention that the set\n$\\mathit{Nat}(\\Delta_c, D)$ can be thought of as a hom-set in the functor\ncategory; so our natural isomorphism relates two hom-sets, which points\nat an even more general relationship called an adjunction.\n\n\\section{Examples of Limits}\n\nWe've seen that the categorical product is a limit of a diagram\ngenerated by a simple category we called $\\cat{2}$.\n\nThere is an even simpler example of a limit: the terminal object. The\nfirst impulse would be to think of a singleton category as leading to a\nterminal object, but the truth is even starker than that: the terminal\nobject is a limit generated by an empty category. A functor from an\nempty category selects no object, so a cone shrinks to just the apex.\nThe universal cone is the lone apex that has a unique morphism coming to\nit from any other apex. You will recognize this as the definition of the\nterminal object.\n\nThe next interesting limit is called the \\emph{equalizer}. It's a limit\ngenerated by a two-element category with two parallel morphisms going\nbetween them (and, as always, the identity morphisms). This category\nselects a diagram in $\\cat{C}$ consisting of two objects, $a$ and\n$b$, and two morphisms:\n\n\\src{snippet03}\n\nTo build a cone over this diagram, we have to add the apex, $c$\nand two projections:\n\n\\src{snippet04}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/equalizercone.jpg}\n\\end{figure}\n\n\\noindent\nWe have two triangles that must commute:\n\n\\src{snippet05}\n\nThis tells us that $q$ is uniquely determined by one of these\nequations, say, \\code{q = f . p}, and we can omit it from the\npicture. So we are left with just one condition:\n\n\\src{snippet06}\n\nThe way to think about it is that, if we restrict our attention to\n$\\Set$, the image of the function $p$ selects a subset of\n$a$. When restricted to this subset, the functions $f$ and\n$g$ are equal.\n\nFor instance, take $a$ to be the two-dimensional plane\nparameterized by coordinates $x$ and $y$. Take $b$\nto be the real line, and take:\n\n\\src{snippet07}\n\nThe equalizer for these two functions is the set of real numbers (the\napex, $c$) and the function:\n\n\\src{snippet08}\n\nNotice that $(p~t)$ defines a straight line in the\ntwo-dimensional plane. Along this line, the two functions are equal.\n\nOf course, there are other sets $c'$ and functions\n$p'$ that may lead to the equality:\n\n\\src{snippet09}\n\nbut they all uniquely factor out through $p$. For instance, we\ncan take the singleton set $\\cat{()}$ as $c'$ and the\nfunction:\n\n\\src{snippet10}\n\nIt's a good cone, because $f (0, 0) = g (0, 0)$. But it's\nnot universal, because of the unique factorization through $h$:\n\n\\src{snippet11}\n\nwith\n\n\\src{snippet12}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/equilizerlimit.jpg}\n\\end{figure}\n\n\\noindent\nAn equalizer can thus be used to solve equations of the type\n$f~x = g~x$. But it's much more general, because it's defined\nin terms of objects and morphisms rather than algebraically.\n\nAn even more general idea of solving an equation is embodied in another\nlimit --- the pullback. Here, we still have two morphisms that we want\nto equate, but this time their domains are different. We start with a\nthree-object category of the shape:\n$1\\rightarrow2\\leftarrow3$. The diagram corresponding to\nthis category consists of three objects, $a$, $b$, and\n$c$, and two morphisms:\n\n\\src{snippet13}\n\nThis diagram is often called a \\emph{cospan}.\n\nA cone built on top of this diagram consists of the apex, $d$,\nand three morphisms:\n\n\\src{snippet14}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/pullbackcone.jpg}\n\\end{figure}\n\n\\noindent\nCommutativity conditions tell us that $r$ is completely\ndetermined by the other morphisms, and can be omitted from the picture.\nSo we are only left with the following condition:\n\n\\src{snippet15}\nA pullback is a universal cone of this shape.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/pullbacklimit.jpg}\n\\end{figure}\n\n\\noindent\nAgain, if you narrow your focus down to sets, you can think of the\nobject $d$ as consisting of pairs of elements from $a$ and\n$c$ for which $f$ acting on the first component is equal\nto $g$ acting on the second component. If this is still too\ngeneral, consider the special case in which $g$ is a constant\nfunction, say $g~\\_ = 1.23$ (assuming that $b$ is a set\nof real numbers). Then you are really solving the equation:\n\n\\src{snippet16}\n\nIn this case, the choice of $c$ is irrelevant (as long as it's\nnot an empty set), so we can take it to be a singleton set. The set\n$a$ could, for instance, be the set of three-dimensional vectors,\nand $f$ the vector length. Then the pullback is the set of pairs\n$(v, ())$, where $v$ is a vector of length 1.23 (a\nsolution to the equation $\\sqrt{(x^{2}+y^{2}+z^{2})} = 1.23$), and\n$()$ is the dummy element of the singleton set.\n\nBut pullbacks have more general applications, also in programming. For\ninstance, consider C++ classes as a category in which morphism are\narrows that connect subclasses to superclasses. We'll consider\ninheritance a transitive property, so if \\code{C} inherits from \\code{B} and \\code{B}\ninherits from \\code{A} then we'll say that \\code{C} inherits from \\code{A} (after all, you\ncan pass a pointer to \\code{C} where a pointer to \\code{A} is expected). Also, we'll\nassume that \\code{C} inherits from \\code{C}, so we have the identity arrow for every\nclass. This way subclassing is aligned with subtyping. C++ also supports\nmultiple inheritance, so you can construct a diamond inheritance diagram\nwith two classes \\code{B} and \\code{C} inheriting from \\code{A}, and a fourth class \\code{D}\nmultiply inheriting from \\code{B} and \\code{C}. Normally, \\code{D} would get two copies of \\code{A},\nwhich is rarely desirable; but you can use virtual inheritance to have\njust one copy of \\code{A} in \\code{D}.\n\nWhat would it mean to have \\code{D} be a pullback in this diagram? It would\nmean that any class \\code{E} that multiply inherits from \\code{B} and \\code{C} is also a\nsubclass of \\code{D}. This is not directly expressible in C++, where subtyping\nis nominal (the C++ compiler wouldn't infer this kind of class\nrelationship --- it would require ``duck typing''). But we could go\noutside of the subtyping relationship and instead ask whether a cast\nfrom \\code{E} to \\code{D} would be safe or not. This cast would be safe if \\code{D} were the\nbare-bone combination of \\code{B} and \\code{C}, with no additional data and no\noverriding of methods. And, of course, there would be no pullback if\nthere is a name conflict between some methods of \\code{B} and \\code{C}.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.25\\textwidth]{images/classes.jpg}\n\\end{figure}\n\n\\noindent\nThere's also a more advanced use of a pullback in type inference. There\nis often a need to \\emph{unify} types of two expressions. For instance,\nsuppose that the compiler wants to infer the type of a function:\n\n\\begin{snip}{haskell}\ntwice f x = f (f x)\n\\end{snip}\nIt will assign preliminary types to all variables and sub-expressions.\nIn particular, it will assign:\n\n\\begin{snip}{haskell}\nf       :: t0\nx       :: t1\nf x     :: t2\nf (f x) :: t3\n\\end{snip}\nfrom which it will deduce that:\n\n\\begin{snip}{haskell}\ntwice :: t0 -> t1 -> t3\n\\end{snip}\nIt will also come up with a set of constraints resulting from the rules\nof function application:\n\n\\begin{snip}{haskell}\nt0 = t1 -> t2 -- because f is applied to x\nt0 = t2 -> t3 -- because f is applied to (f x)\n\\end{snip}\nThese constraints have to be unified by finding a set of types (or type\nvariables) that, when substituted for the unknown types in both\nexpressions, produce the same type. One such substitution is:\n\n\\begin{snip}{haskell}\nt1 = t2 = t3 = Int\ntwice :: (Int -> Int) -> Int -> Int\n\\end{snip}\nbut, obviously, it's not the most general one. The most general\nsubstitution is obtained using a pullback. I won't go into the details,\nbecause they are beyond the scope of this book, but you can convince\nyourself that the result should be:\n\n\\begin{snip}{haskell}\ntwice :: (t -> t) -> t -> t\n\\end{snip}\nwith \\code{t} a free type variable.\n\n\\section{Colimits}\n\nJust like all constructions in category theory, limits have their dual\nimage in opposite categories. When you invert the direction of all\narrows in a cone, you get a co-cone, and the universal one of those is\ncalled a colimit. Notice that the inversion also affects the factorizing\nmorphism, which now flows from the universal co-cone to any other\nco-cone.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/colimit.jpg}\n  \\caption{Cocone with a factorizing morphism $h$ connecting two apexes.}\n\\end{figure}\n\n\\noindent\nA typical example of a colimit is a coproduct, which corresponds to the\ndiagram generated by $\\cat{2}$, the category we've used in the\ndefinition of the product.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/coproductranking.jpg}\n\\end{figure}\n\n\\noindent\nBoth the product and the coproduct embody the essence of a pair of\nobjects, each in a different way.\n\nJust like the terminal object was a limit, so the initial object is a\ncolimit corresponding to the diagram based on an empty category.\n\nThe dual of the pullback is called the \\emph{pushout}. It's based on a\ndiagram called a span, generated by the category\n$1\\leftarrow2\\rightarrow3$.\n\n\\section{Continuity}\n\nI said previously that functors come close to the idea of continuous\nmappings of categories, in the sense that they never break existing\nconnections (morphisms). The actual definition of a \\emph{continuous\n  functor} $F$ from a category $\\cat{C}$ to $\\cat{C'}$ includes the\nrequirement that the functor preserve limits. Every diagram $D$\nin $\\cat{C}$ can be mapped to a diagram $F \\circ D$ in $\\cat{C'}$ by\nsimply composing two functors. The continuity condition for $F$\nstates that, if the diagram $D$ has a limit $\\Lim[D]$, then\nthe diagram $F \\circ D$ also has a limit, and it is equal to\n$F (\\Lim[D])$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.6\\textwidth]{images/continuity.jpg}\n\\end{figure}\n\n\\noindent\nNotice that, because functors map morphisms to morphisms, and\ncompositions to compositions, an image of a cone is always a cone. A\ncommuting triangle is always mapped to a commuting triangle (functors\npreserve composition). The same is true for the factorizing morphisms:\nthe image of a factorizing morphism is also a factorizing morphism. So\nevery functor is \\emph{almost} continuous. What may go wrong is the\nuniqueness condition. The factorizing morphism in $\\cat{C'}$ might not be\nunique. There may also be other ``better cones'' in $\\cat{C'}$ that were\nnot available in $\\cat{C}$.\n\nA hom-functor is an example of a continuous functor. Recall that the\nhom-functor, $\\cat{C}(a, b)$, is contravariant in the first variable\nand covariant in the second. In other words, it's a functor:\n\\[\\cat{C}^\\mathit{op} \\times \\cat{C} \\to \\Set\\]\nWhen its second argument is fixed, the hom-set functor (which becomes\nthe representable presheaf) maps colimits in $\\cat{C}$ to limits in\n$\\Set$; and when its first argument is fixed, it maps limits to\nlimits.\n\nIn Haskell, a hom-functor is the mapping of any two types to a function\ntype, so it's just a parameterized function type. When we fix the second\nparameter, let's say to \\code{String}, we get the contravariant\nfunctor:\n\n\\src{snippet17}\nContinuity means that when \\code{ToString} is applied to a colimit,\nfor instance a coproduct \\code{Either b c}, it will produce a limit;\nin this case a product of two function types:\n\n\\src{snippet18}\nIndeed, any function of \\code{Either b c} is implemented as a case\nclause with the two cases being serviced by a pair of functions.\n\nSimilarly, when we fix the first argument of the hom-set, we get the\nfamiliar reader functor. Its continuity means that, for instance, any\nfunction returning a product is equivalent to a product of functions; in\nparticular:\n\n\\src{snippet19}\nI know what you're thinking: You don't need category theory to figure\nthese things out. And you're right! Still, I find it amazing that such\nresults can be derived from first principles with no recourse to bits\nand bytes, processor architectures, compiler technologies, or even\nlambda calculus.\n\nIf you're curious where the names ``limit'' and ``continuity'' come\nfrom, they are a generalization of the corresponding notions from\ncalculus. In calculus limits and continuity are defined in terms of open\nneighborhoods. Open sets, which define topology, form a category (a\nposet).\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        How would you describe a pushout in the category of C++ classes?\n  \\item\n        Show that the limit of the identity functor\n        $\\mathbf{Id} \\Colon \\cat{C} \\to \\cat{C}$ is the initial object.\n  \\item\n        Subsets of a given set form a category. A morphism in that category is\n        defined to be an arrow connecting two sets if the first is the subset\n        of the second. What is a pullback of two sets in such a category?\n        What's a pushout? What are the initial and terminal objects?\n  \\item\n        Can you guess what a coequalizer is?\n  \\item\n        Show that, in a category with a terminal object, a pullback towards\n        the terminal object is a product.\n  \\item\n        Similarly, show that a pushout from an initial object (if one exists)\n        is the coproduct.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet01.hs",
    "content": "class Monoid m where\n    mempty :: m\n    mappend :: m -> m -> m"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet02.hs",
    "content": "instance Monoid [a] where\n    mempty = []\n    mappend = (++)"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet03.hs",
    "content": "2 * 3 = 6\n[2] ++ [3] = [2, 3] -- not the same as [6]\n"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet04.hs",
    "content": "h (a * b) = h a * h b"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet05.hs",
    "content": "[2] ++ [3] = [2, 3]"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet06.hs",
    "content": "2 * 3 = 6"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet07.hs",
    "content": "p :: x -> U m"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet08.hs",
    "content": "q :: x -> U n"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet09.hs",
    "content": "h :: m -> n"
  },
  {
    "path": "src/content/2.3/code/haskell/snippet10.hs",
    "content": "q = U h . p"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet01.ml",
    "content": "module type Monoid = sig\n  type m\n\n  val mempty : m\n  val mappend : m -> m -> m\nend\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet02.ml",
    "content": "module ListMonoid (T1 : sig\n  type a\nend) : Monoid with type m = T1.a list = struct\n  type m = T1.a list\n\n  let mempty = []\n  let mappend xs ys = List.append xs ys\nend\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet03.ml",
    "content": "2 * 3 = 6\nList.append [2] [3] = [2; 3]\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet04.ml",
    "content": "let h (a * b) = h a * h b\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet05.ml",
    "content": "List.append [2] [3] = [2; 3]\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet06.ml",
    "content": "2 * 3 = 6\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet07.ml",
    "content": "module type FreeMonoidRep = functor (F : Functor) -> sig\n  type x\n  type m\n\n  val p : x -> m F.t\nend\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet08.ml",
    "content": "module type FreeMonoidRep = functor (F : Functor) -> sig\n  type x\n  type n\n\n  val q : x -> n F.t\nend\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet09.ml",
    "content": "val h : m -> n\n"
  },
  {
    "path": "src/content/2.3/code/ocaml/snippet10.ml",
    "content": "val q = compose uh p\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet01.re",
    "content": "module type Monoid = {\n  type m;\n  \n  let mempty: m;\n  let mappend: (m, m) => m;\n};\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet02.re",
    "content": "module ListMonoid = (T1: {type a;}) : \n    (Monoid with type m = list(T1.a)) => {\n  type m = list(T1.a);\n\n  let mempty = [];\n  let mappend = (xs, ys) => List.append(xs, ys);\n};\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet03.re",
    "content": "2 * 3 == 6\nList.append([2], [3]) == [2, 3];\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet04.re",
    "content": "let h (a * b) = h a * h b"
  },
  {
    "path": "src/content/2.3/code/reason/snippet05.re",
    "content": "List.append([2], [3]) == [2, 3];\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet06.re",
    "content": "2 * 3 == 6;\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet07.re",
    "content": "module type FreeMonoidRep = (F: Functor) => {\n  type x;\n  type m;\n  \n  let p: x => F.t(m);\n};\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet08.re",
    "content": "module type FreeMonoidRep = (F: Functor) => {\n  type x;\n  type n;\n  \n  let q: x => F.t(n);\n};\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet09.re",
    "content": "let h: m => n\n"
  },
  {
    "path": "src/content/2.3/code/reason/snippet10.re",
    "content": "let q: compose(uh p)\n"
  },
  {
    "path": "src/content/2.3/code/scala/snippet01.scala",
    "content": "trait Monoid[M] {\n  def mempty: M\n  def mappend(m1: M, m2: M): M\n}"
  },
  {
    "path": "src/content/2.3/code/scala/snippet02.scala",
    "content": "object Monoid {\n  implicit def listMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] {\n    def mempty: List[A] = List()\n    def mappend(m1: List[A], m2: List[A]): List[A] = m1 ++ m2\n  }\n}"
  },
  {
    "path": "src/content/2.3/code/scala/snippet03.scala",
    "content": "2 * 3 == 6\nList(2) ++ List(3) == List(2, 3)"
  },
  {
    "path": "src/content/2.3/code/scala/snippet04.scala",
    "content": "h(a * b) == h(a) * h(b)"
  },
  {
    "path": "src/content/2.3/code/scala/snippet05.scala",
    "content": "List(2) ++ List(3) == List(2, 3)"
  },
  {
    "path": "src/content/2.3/code/scala/snippet06.scala",
    "content": "2 * 3 == 6"
  },
  {
    "path": "src/content/2.3/code/scala/snippet07.scala",
    "content": "val p: X => U[M]"
  },
  {
    "path": "src/content/2.3/code/scala/snippet08.scala",
    "content": "val q: X => U[N]"
  },
  {
    "path": "src/content/2.3/code/scala/snippet09.scala",
    "content": "val h: M => N"
  },
  {
    "path": "src/content/2.3/code/scala/snippet10.scala",
    "content": "val q = uh compose p"
  },
  {
    "path": "src/content/2.3/free-monoids.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{M}{onoids are an important} concept in both category\ntheory and in programming. Categories correspond to strongly typed languages,\nmonoids to untyped languages. That's because in a monoid you can compose any\ntwo arrows, just as in an untyped language you can compose any two functions\n(of course, you may end up with a runtime error when you execute your\nprogram).\n\nWe've seen that a monoid may be described as a category with a single\nobject, where all logic is encoded in the rules of morphism composition.\nThis categorical model is fully equivalent to the more traditional\nset-theoretical definition of a monoid, where we ``multiply'' two\nelements of a set to get a third element. This process of\n``multiplication'' can be further dissected into first forming a pair of\nelements and then identifying this pair with an existing element ---\ntheir ``product.''\n\nWhat happens when we forgo the second part of multiplication --- the\nidentification of pairs with existing elements? We can, for instance,\nstart with an arbitrary set, form all possible pairs of elements, and\ncall them new elements. Then we'll pair these new elements with all\npossible elements, and so on. This is a chain reaction --- we'll keep\nadding new elements forever. The result, an infinite set, will be\n\\emph{almost} a monoid. But a monoid also needs a unit element and the\nlaw of associativity. No problem, we can add a special unit element and\nidentify some of the pairs --- just enough to support the unit and\nassociativity laws.\n\nLet's see how this works in a simple example. Let's start with a set of\ntwo elements, $\\{a, b\\}$. We'll call them the generators of the\nfree monoid. First, we'll add a special element $e$ to serve as\nthe unit. Next we'll add all the pairs of elements and call them\n``products''. The product of $a$ and $b$ will be the pair\n$(a, b)$. The product of $b$ and $a$ will be the\npair $(b, a)$, the product of $a$ with $a$ will be\n$(a, a)$, the product of $b$ with $b$ will be\n$(b, b)$. We can also form pairs with $e$, like\n$(a, e)$, $(e, b)$, etc., but we'll identify them with\n$a$, $b$, etc. So in this round we'll only add\n$(a, a)$, $(a, b)$ and $(b, a)$ and\n$(b, b)$, and end up with the set\n$\\{e, a, b, (a, a), (a, b), (b, a), (b, b)\\}$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.8\\textwidth]{images/bunnies.jpg}\n\\end{figure}\n\n\\noindent\nIn the next round we'll keep adding elements like:\n$(a, (a, b))$, $((a, b), a)$, etc. At this point we'll\nhave to make sure that associativity holds, so we'll identify\n$(a, (b, a))$ with $((a, b), a)$, etc. In other words,\nwe won't be needing internal parentheses.\n\nYou can guess what the final result of this process will be: we'll\ncreate all possible lists of $a$s and $b$s. In fact, if we\nrepresent $e$ as an empty list, we can see that our\n``multiplication'' is nothing but list concatenation.\n\nThis kind of construction, in which you keep generating all possible\ncombinations of elements, and perform the minimum number of\nidentifications --- just enough to uphold the laws --- is called a free\nconstruction. What we have just done is to construct a \\newterm{free\n  monoid} from the set of generators $\\{a, b\\}$.\n\n\\section{Free Monoid in Haskell}\n\nA two-element set in Haskell is equivalent to the type \\code{Bool},\nand the free monoid generated by this set is equivalent to the type\n\\code{{[}Bool{]}} (list of \\code{Bool}). (I am deliberately ignoring\nproblems with infinite lists.)\n\nA monoid in Haskell is defined by the type class:\n\n\\src{snippet01}\nThis just says that every \\code{Monoid} must have a neutral element,\nwhich is called \\code{mempty}, and a binary function (multiplication)\ncalled \\code{mappend}. The unit and associativity laws cannot be\nexpressed in Haskell and must be verified by the programmer every time a\nmonoid is instantiated.\n\nThe fact that a list of any type forms a monoid is described by this\ninstance definition:\n\n\\src{snippet02}\nIt states that an empty list \\code{{[}{]}} is the unit element, and\nlist concatenation \\code{(++)} is the binary operation.\n\nAs we have seen, a list of type \\code{a} corresponds to a free monoid\nwith the set \\code{a} serving as generators. The set of natural\nnumbers with multiplication is not a free monoid, because we identify\nlots of products. Compare for instance:\n\n\\src{snippet03}\nThat was easy, but the question is, can we perform this free\nconstruction in category theory, where we are not allowed to look inside\nobjects? We'll use our workhorse: the universal construction.\n\nThe second interesting question is, can any monoid be obtained from some\nfree monoid by identifying more than the minimum number of elements\nrequired by the laws? I'll show you that this follows directly from the\nuniversal construction.\n\n\\section{Free Monoid Universal Construction}\n\nIf you recall our previous experiences with universal constructions, you\nmight notice that it's not so much about constructing something as about\nselecting an object that best fits a given pattern. So if we want to use\nthe universal construction to ``construct'' a free monoid, we have to\nconsider a whole bunch of monoids from which to pick one. We need a\nwhole category of monoids to choose from. But do monoids form a category?\n\nLet's first look at monoids as sets equipped with additional structure\ndefined by unit and multiplication. We'll pick as morphisms those\nfunctions that preserve the monoidal structure. Such\nstructure-preserving functions are called \\newterm{homomorphisms}. A monoid\nhomomorphism must map the product of two elements to the product of the\nmapping of the two elements:\n\n\\src{snippet04}\nand it must map unit to unit.\n\nFor instance, consider a homomorphism from lists of integers to\nintegers. If we map \\code{{[}2{]}} to 2 and \\code{{[}3{]}} to 3, we\nhave to map \\code{{[}2, 3{]}} to 6, because concatenation\n\n\\src{snippet05}\nbecomes multiplication\n\n\\src{snippet06}\nNow let's forget about the internal structure of individual monoids, and\nonly look at them as objects with corresponding morphisms. You get a\ncategory $\\cat{Mon}$ of monoids.\n\nOkay, maybe before we forget about internal structure, let us notice an\nimportant property. Every object of $\\cat{Mon}$ can be trivially mapped\nto a set. It's just the set of its elements. This set is called the\n\\newterm{underlying} set. In fact, not only can we map objects of\n$\\cat{Mon}$ to sets, but we can also map morphisms of $\\cat{Mon}$\n(homomorphisms) to functions. Again, this seems sort of trivial, but it\nwill become useful soon. This mapping of objects and morphisms from\n$\\cat{Mon}$ to $\\Set$ is in fact a functor. Since this functor\n``forgets'' the monoidal structure --- once we are inside a plain set,\nwe no longer distinguish the unit element or care about multiplication\n--- it's called a \\newterm{forgetful functor}. Forgetful functors come up\nregularly in category theory.\n\nWe now have two different views of $\\cat{Mon}$. We can treat it just\nlike any other category with objects and morphisms. In that view, we\ndon't see the internal structure of monoids. All we can say about a\nparticular object in $\\cat{Mon}$ is that it connects to itself and to\nother objects through morphisms. The ``multiplication'' table of\nmorphisms --- the composition rules --- are derived from the other view:\nmonoids-as-sets. By going to category theory we haven't lost this view\ncompletely --- we can still access it through our forgetful functor.\n\nTo apply the universal construction, we need to define a special\nproperty that would let us search through the category of monoids and\npick the best candidate for a free monoid. But a free monoid is defined\nby its generators. Different choices of generators produce different\nfree monoids (a list of \\code{Bool} is not the same as a list of\n\\code{Int}). Our construction must start with a set of generators. So\nwe're back to sets!\n\nThat's where the forgetful functor comes into play. We can use it to\nX-ray our monoids. We can identify the generators in the X-ray images of\nthose blobs. Here's how it works:\n\nWe start with a set of generators, $x$. That's a set in\n$\\Set$.\n\nThe pattern we are going to match consists of a monoid $m$ --- an\nobject of $\\cat{Mon}$ --- and a function $p$ in $\\Set$:\n\n\\src{snippet07}\nwhere $U$ is our forgetful functor from $\\cat{Mon}$ to\n$\\Set$. This is a weird heterogeneous pattern --- half in\n$\\cat{Mon}$ and half in $\\Set$.\n\nThe idea is that the function $p$ will identify the set of\ngenerators inside the X-ray image of $m$. It doesn't matter that\nfunctions may be lousy at identifying points inside sets (they may\ncollapse them). It will all be sorted out by the universal construction,\nwhich will pick the best representative of this pattern.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/monoid-pattern.jpg}\n\\end{figure}\n\n\\noindent\nWe also have to define the ranking among candidates. Suppose we have\nanother candidate: a monoid $n$ and a function that identifies\nthe generators in its X-ray image:\n\n\\src{snippet08}\nWe'll say that $m$ is better than $n$ if there is a\nmorphism of monoids (that's a structure-preserving homomorphism):\n\n\\src{snippet09}\nwhose image under $U$ (remember, $U$ is a functor, so it\nmaps morphisms to functions) factorizes through $p$:\n\n\\src{snippet10}\nIf you think of $p$ as selecting the generators in $m$;\nand $q$ as selecting ``the same'' generators in $n$; then\nyou can think of $h$ as mapping these generators between the two\nmonoids. Remember that $h$, by definition, preserves the monoidal\nstructure. It means that a product of two generators in one monoid will\nbe mapped to a product of the corresponding two generators in the second\nmonoid, and so on.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/monoid-ranking.jpg}\n\\end{figure}\n\n\\noindent\nThis ranking may be used to find the best candidate --- the free monoid.\nHere's the definition:\n\n\\begin{quote}\n  We'll say that $m$ (together with the function $p$) is the\n  \\textbf{free monoid} with the generators $x$ if and only if there\n  is a \\emph{unique} morphism $h$ from $m$ to any other\n  monoid $n$ (together with the function $q$) that satisfies\n  the above factorization property.\n\\end{quote}\nIncidentally, this answers our second question. The function\n$U h$ is the one that has the power to collapse multiple\nelements of $U m$ to a single element of $U n$. This\ncollapse corresponds to identifying some elements of the free monoid.\nTherefore any monoid with generators $x$ can be obtained from the\nfree monoid based on $x$ by identifying some of the elements. The\nfree monoid is the one where only the bare minimum of identifications\nhave been made.\n\nWe'll come back to free monoids when we talk about adjunctions.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        You might think (as I did, originally) that the requirement that a\n        homomorphism of monoids preserve the unit is redundant. After all, we\n        know that for all $a$\n\n        \\begin{snip}{text}\nh a * h e = h (a * e) = h a\n\\end{snip}\n        So $h e$ acts like a right unit (and, by analogy, as a left\n        unit). The problem is that $h a$, for all $a$ might\n        only cover a sub-monoid of the target monoid. There may be a ``true''\n        unit outside of the image of $h$. Show that an isomorphism\n        between monoids that preserves multiplication must automatically\n        preserve unit.\n  \\item\n        Consider a monoid homomorphism from lists of integers with\n        concatenation to integers with multiplication. What is the image of\n        the empty list \\code{{[}{]}}? Assume that all singleton lists are\n        mapped to the integers they contain, that is \\code{{[}3{]}} is\n        mapped to 3, etc. What's the image of \\code{{[}1, 2, 3, 4{]}}?\n        How many different lists map to the integer 12? Is there any other\n        homomorphism between the two monoids?\n  \\item\n        What is the free monoid generated by a one-element set? Can you see\n        what it's isomorphic to?\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet01.hs",
    "content": "type Reader a x = a -> x"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet02.hs",
    "content": "instance Functor (Reader a) where\n    fmap f h = f . h"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet03.hs",
    "content": "type Op a x = x -> a"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet04.hs",
    "content": "instance Contravariant (Op a) where\n    contramap f h = h . f"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet05.hs",
    "content": "instance Profunctor (->) where\n    dimap ab cd bc = cd . bc . ab\n    lmap = flip (.)\n    rmap = (.)"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet06.hs",
    "content": "alpha :: forall x. (a -> x) -> F x"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet07.hs",
    "content": "fmap f . alpha = alpha . fmap f"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet08.hs",
    "content": "fmap f (alpha h) = alpha (f . h)"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet09.hs",
    "content": "beta :: forall x. F x -> (a -> x)"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet10.hs",
    "content": "alpha :: forall x. (Int -> x) -> [x]\nalpha h = map h [12]"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet11.hs",
    "content": "map f (map h [12]) = map (f . h) [12]"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet12.hs",
    "content": "beta :: forall x. [x] -> (Int -> x)"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet13.hs",
    "content": "class Representable f where\n    type Rep f :: *\n    tabulate :: (Rep f -> x) -> f x\n    index    :: f x -> Rep f -> x"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet14.hs",
    "content": "data Stream x = Cons x (Stream x)"
  },
  {
    "path": "src/content/2.4/code/haskell/snippet15.hs",
    "content": "instance Representable Stream where\n    type Rep Stream = Integer\n    tabulate f = Cons (f 0) (tabulate (f . (+1)))\n    index (Cons b bs) n = if n == 0 then b else index bs (n - 1)"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet01.ml",
    "content": "type ('a, 'x) reader = 'a -> 'x\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet02.ml",
    "content": "module ReaderFunctor (T : sig\n  type r\nend) : Functor = struct\n  type 'a t = (T.r, 'a) reader\n\n  let fmap f h a = f (h a)\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet03.ml",
    "content": "type ('a, 'x) op = 'x -> 'a\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet04.ml",
    "content": "module OpContravariant (T : sig\n  type r\nend) : Contravariant = struct\n  type 'a t = (T.r, 'a) op\n\n  let contramap f h b = h (f b)\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet05.ml",
    "content": "module ProfunctorArrow : Profunctor = struct\n  type ('a, 'b) p = 'a -> 'b\n\n  let dimap f g p = compose g (compose p f)\n  let lmap f p = (flip compose) f p\n  let rmap = compose\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet06.ml",
    "content": "module type NT_AX_FX = sig\n  type a\n  type 'x t\n\n  val alpha : (a -> 'x) -> 'x t\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet07.ml",
    "content": "compose (F.fmap f) NT.alpha = compose NT.alpha (F.fmap f)\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet08.ml",
    "content": "F.fmap f (N.alpha h) = N.alpha (compose f h)\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet09.ml",
    "content": "module type NT_FX_AX = sig\n  type a\n  type 'x t\n\n  val beta : 'x t -> a -> 'x\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet10.ml",
    "content": "module NT_Impl (F : Functor with type 'a t = 'a list) :\n  NT_AX_FX with type a = int and type 'x t = 'x list = struct\n  type a = int\n  type 'x t = 'x list\n\n  let alpha : 'x. (int -> 'x) -> 'x list = fun h -> F.fmap h [ 12 ]\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet11.ml",
    "content": "F.fmap f (F.fmap h [12]) = F.fmap (compose f h) [12]\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet12.ml",
    "content": "module type NT_ListX_IntX = sig\n  type a = int\n  type 'x t = 'x list\n\n  val beta : 'x t -> a -> 'x\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet13.ml",
    "content": "module type Representable = sig\n  type 'x t\n  type rep (* Representing type 'a' *)\n\n  val tabulate : (rep -> 'x) -> 'x t\n  val index : 'x t -> rep -> 'x\nend\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet14.ml",
    "content": "type 'a stream = Cons of 'a * 'a stream Lazy.t\n"
  },
  {
    "path": "src/content/2.4/code/ocaml/snippet15.ml",
    "content": "module StreamRepresentable : Representable = struct\n  type rep = int\n  type 'x t = 'x stream\n\n  let rec tabulate f = Cons (f 0, lazy (tabulate (compose f succ)))\n\n  let rec index (Cons (b, bs)) n =\n    if n = 0 then b else index (Lazy.force bs) (n - 1)\n  ;;\nend\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet01.re",
    "content": "type reader('a, 'x) = 'a => 'x;\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet02.re",
    "content": "module ReaderFunctor = (T: {type r;}) : Functor => {\n  type t('a) = reader(T.r, 'a);\n  \n  let fmap = (f, h, a) => f(h(a));\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet03.re",
    "content": "type op('a, 'x) = 'x => 'a;\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet04.re",
    "content": "module OpContravariant = (T: {type r;}) : Contravariant => {\n  type t('a) = op(T.r, 'a);\n\n  let contramap = (f, h, b) => h(f(b));\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet05.re",
    "content": "module ProfunctorArrow: Profunctor = {\n  type p('a, 'b) = 'a => 'b;\n  \n  let dimap = (f, g, p) => compose(g, compose(p, f));\n  let lmap = (f, p) => (flip(compose))(f, p);\n  let rmap = compose;\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet06.re",
    "content": "module type NT_AX_FX = {\n  type a;\n  type t('x);\n  \n  let alpha: (a => 'x) => t('x);\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet07.re",
    "content": "compose(F.fmap(f), NT.alpha) == compose(NT.alpha, F.fmap(f));\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet08.re",
    "content": "F.fmap(f, N.alpha(h)) == N.alpha(compose(f, h));\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet09.re",
    "content": "module type NT_FX_AX = {\n  type a;\n  type t('x);\n  \n  let beta: (t('x), a) => 'x;\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet10.re",
    "content": "module NT_Impl = (F: Functor with type t('a) = list('a)): \n    (NT_AX_FX with type a = int and type t('x) = list('x)) => {\n  type a = int;\n  type t('x) = list('x);\n  \n  let alpha: 'x . (int => 'x) => list('x) = h => F.fmap(h, [12]);\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet11.re",
    "content": "F.fmap(f, F.fmap(h, [12])) == F.fmap(compose(f, h), [12]);\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet12.re",
    "content": "module type NT_ListX_IntX = {\n  type a = int;\n  type t('x) = list('x);\n  \n  let beta: (t('x), a) => 'x;\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet13.re",
    "content": "module type Representable = {\n  type t('x);\n  type rep; /* Representing type 'a' */\n  \n  let tabulate: (rep => 'x) => t('x);\n  let index: (t('x), rep) => 'x;\n};\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet14.re",
    "content": "type stream('a) =\n  | Cons('a, Lazy.t(stream('a)));\n"
  },
  {
    "path": "src/content/2.4/code/reason/snippet15.re",
    "content": "module StreamRepresentable: Representable = {\n  type rep = int;\n  type t('x) = stream('x);\n\n  let rec tabulate = f => Cons(f(0), lazy(tabulate(compose(f, succ))));\n\n  let rec index = (Cons(b, bs), n) =>\n    n == 0 ? b : index(Lazy.force(bs), n - 1);\n};\n"
  },
  {
    "path": "src/content/2.4/code/scala/snippet01.scala",
    "content": "type Reader[A, X] = A => X"
  },
  {
    "path": "src/content/2.4/code/scala/snippet02.scala",
    "content": "implicit def readerFunctor[A] = new Functor[Reader[A, ?]] {\n  def fmap[X, B](f: X => B)(h: Reader[A, X]): Reader[A, B] =\n    f compose h\n}\n"
  },
  {
    "path": "src/content/2.4/code/scala/snippet03.scala",
    "content": "type Op[A, X] = X => A"
  },
  {
    "path": "src/content/2.4/code/scala/snippet04.scala",
    "content": "implicit def opContravariant[A] = new Contravariant[Op[A, ?]] {\n  def contramap[X, B](f: B => X)(h: Op[A, X]): Op[A, B] =\n    h compose f\n}"
  },
  {
    "path": "src/content/2.4/code/scala/snippet05.scala",
    "content": "implicit def arrowProfunctor = new Profunctor[Function1] {\n  def dimap[A, B, C, D](ab: A => B)(cd: C => D)(bc: B => C): A => D =\n    cd compose bc compose ab\n\n  def lmap[A, B, C](f: C => A)(ab: A => B): C => B =\n    f andThen ab\n\n  def rmap[A, B, C](f: B => C)(ab: A => B): A => C =\n    f compose ab\n}"
  },
  {
    "path": "src/content/2.4/code/scala/snippet06.scala",
    "content": "// In order to make a universal transformation,\n// another type needs to be introduced.\n// To read more about FunctionK (~>):\n// typelevel.org/cats/datatypes/functionk.html\ntrait ~>[F[_], G[_]] {\n  def apply[B](fa: F[B]): G[B]\n}\n\n// Kind Projector plugin provides\n// a more concise syntax for type lambdas:\ndef alpha[A]: (A => ?) ~> F"
  },
  {
    "path": "src/content/2.4/code/scala/snippet07.scala",
    "content": "(fmap(f) _ compose alpha.apply) == (alpha.apply _ compose fmap(f))"
  },
  {
    "path": "src/content/2.4/code/scala/snippet08.scala",
    "content": "fmap(f)(alpha(h)) == alpha(f compose h)"
  },
  {
    "path": "src/content/2.4/code/scala/snippet09.scala",
    "content": "def beta[A]: F ~> (A => ?)"
  },
  {
    "path": "src/content/2.4/code/scala/snippet10.scala",
    "content": "def alpha: (Int => ?) ~> List = new ~>[Int => ?, List] {\n  def apply[A](fa: Int => A) =\n    List(12).map(fa)\n}"
  },
  {
    "path": "src/content/2.4/code/scala/snippet11.scala",
    "content": "fmap(f)(fmap(h)(List(12))) == fmap(f compose h)(List(12))\n\n// Or using scala stdlib:\nList(12).map(h).map(f) == List(12).map(f compose h)"
  },
  {
    "path": "src/content/2.4/code/scala/snippet12.scala",
    "content": "def beta: List ~> (Int => ?)"
  },
  {
    "path": "src/content/2.4/code/scala/snippet13.scala",
    "content": "trait Representable[F[_]] {\n  type Rep\n  def tabulate[X](f: Rep => X): F[X]\n  def index[X]: F[X] => Rep => X\n}"
  },
  {
    "path": "src/content/2.4/code/scala/snippet14.scala",
    "content": "case class Stream[X](\n  h: () => X,\n  t: () => Stream[X]\n)"
  },
  {
    "path": "src/content/2.4/code/scala/snippet15.scala",
    "content": "implicit val streamRepresentable = new Representable[Stream] {\n  type Rep = Int\n\n  def tabulate[X](f: Rep => X): Stream[X] = \n    Stream[X](() => f(0), () => tabulate(f compose (_ + 1)))\n\n  def index[X]: Stream[X] => Rep => X = {\n    case Stream(b, bs) => \n      n =>\n        if (n == 0) b()\n        else index(bs())(n - 1)\n  }\n}"
  },
  {
    "path": "src/content/2.4/representable-functors.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{t's about time} we had a little talk about sets.\nMathematicians have a love/hate relationship with set theory. It's the\nassembly language of mathematics --- at least it used to be. Category\ntheory tries to step away from set theory, to some extent. For instance,\nit's a known fact that the set of all sets doesn't exist, but the category\nof all sets, $\\Set$, does. So that's good. On the other hand, we assume that\nmorphisms between any two objects in a category form a set. We even\ncalled it a hom-set. To be fair, there is a branch of category theory\nwhere morphisms don't form sets. Instead they are objects in another\ncategory. Those categories that use hom-objects rather than hom-sets,\nare called \\newterm{enriched} categories. In what follows, though, we'll\nstick to categories with good old-fashioned hom-sets.\n\nA set is the closest thing to a featureless blob you can get outside of\ncategorical objects. A set has elements, but you can't say much about\nthese elements. If you have a finite set, you can count the elements.\nYou can kind of count the elements of an infinite set using cardinal\nnumbers. The set of natural numbers, for instance, is smaller than the\nset of real numbers, even though both are infinite. But, maybe\nsurprisingly, a set of rational numbers is the same size as the set of\nnatural numbers.\n\nOther than that, all the information about sets can be encoded in\nfunctions between them --- especially the invertible ones called\nisomorphisms. For all intents and purposes isomorphic sets are\nidentical. Before I summon the wrath of foundational mathematicians, let\nme explain that the distinction between equality and isomorphism is of\nfundamental importance. In fact it is one of the main concerns of the\nlatest branch of mathematics, the Homotopy Type Theory (HoTT). I'm\nmentioning HoTT because it's a pure mathematical theory that takes\ninspiration from computation, and one of its main proponents, Vladimir\nVoevodsky, had a major epiphany while studying the Rocq theorem prover.\nThe interaction between mathematics and programming goes both ways.\n\nThe important lesson about sets is that it's okay to compare sets of\nunlike elements. For instance, we can say that a given set of natural\ntransformations is isomorphic to some set of morphisms, because a set is\njust a set. Isomorphism in this case just means that for every natural\ntransformation from one set there is a unique morphism from the other\nset and vice versa. They can be paired against each other. You can't\ncompare apples with oranges, if they are objects from different\ncategories, but you can compare sets of apples against sets of oranges.\nOften transforming a categorical problem into a set-theoretical problem\ngives us the necessary insight or even lets us prove valuable theorems.\n\n\\section{The Hom Functor}\n\nEvery category comes equipped with a canonical family of mappings to\n$\\Set$. Those mappings are in fact functors, so they preserve the\nstructure of the category. Let's build one such mapping.\n\nLet's fix one object $a$ in $\\cat{C}$ and pick another object\n$x$ also in $\\cat{C}$. The hom-set $\\cat{C}(a, x)$ is a set, an\nobject in $\\Set$. When we vary $x$, keeping $a$\nfixed, $\\cat{C}(a, x)$ will also vary in $\\Set$. Thus we have a\nmapping from $x$ to $\\Set$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.45\\textwidth]{images/hom-set.jpg}\n\\end{figure}\n\n\\noindent\nIf we want to stress the fact that we are considering the hom-set as a\nmapping in its second argument, we use the notation $\\cat{C}(a, -)$\nwith the dash serving as the placeholder for the argument.\n\nThis mapping of objects is easily extended to the mapping of morphisms.\nLet's take a morphism $f$ in $\\cat{C}$ between two arbitrary\nobjects $x$ and $y$. The object $x$ is mapped to\nthe set $\\cat{C}(a, x)$, and the object $y$ is mapped to\n$\\cat{C}(a, y)$, under the mapping we have just defined. If this\nmapping is to be a functor, $f$ must be mapped to a function\nbetween the two sets: $\\cat{C}(a, x) \\to \\cat{C}(a, y)$\n\nLet's define this function point-wise, that is for each argument\nseparately. For the argument we should pick an arbitrary element of\n$\\cat{C}(a, x)$ --- let's call it $h$. Morphisms are\ncomposable, if they match end to end. It so happens that the target of\n$h$ matches the source of $f$, so their composition:\n\\[f \\circ h \\Colon a \\to y\\]\nis a morphism going from $a$ to $y$. It is therefore a\nmember of $\\cat{C}(a, y)$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.45\\textwidth]{images/hom-functor.jpg}\n\\end{figure}\n\n\\noindent\nWe have just found our function from $\\cat{C}(a, x)$ to\n$\\cat{C}(a, y)$, which can serve as the image of $f$. If there\nis no danger of confusion, we'll write this lifted function as: $\\cat{C}(a, f)$\nand its action on a morphism $h$ as:\n\\[\\cat{C}(a, f) h = f \\circ h\\]\nSince this construction works in any category, it must also work in the\ncategory of Haskell types. In Haskell, the hom-functor is better known\nas the \\code{Reader} functor:\n\n\\src{snippet01}\n\n\\src{snippet02}\nNow let's consider what happens if, instead of fixing the source of the\nhom-set, we fix the target. In other words, we're asking the question if\nthe mapping $\\cat{C}(-, a)$ is also a functor. It is, but instead of being covariant, it's\ncontravariant. That's because the same kind of matching of morphisms end\nto end results in postcomposition by $f$; rather than\nprecomposition, as was the case with $\\cat{C}(a, -)$.\n\nWe have already seen this contravariant functor in Haskell. We called it\n\\code{Op}:\n\n\\src{snippet03}\n\n\\src{snippet04}\nFinally, if we let both objects vary, we get a profunctor\n$\\cat{C}(-, =)$, which is contravariant in the first argument and\ncovariant in the second (to underline the fact that the two arguments\nmay vary independently, we use a double dash as the second placeholder).\nWe have seen this profunctor before, when we talked about functoriality:\n\n\\src{snippet05}\nThe important lesson is that this observation holds in any category: the\nmapping of objects to hom-sets is functorial. Since contravariance is\nequivalent to a mapping from the opposite category, we can state this\nfact succinctly as:\n\\[C(-, =) \\Colon \\cat{C}^\\mathit{op} \\times \\cat{C} \\to \\Set\\]\n\n\\section{Representable Functors}\n\nWe've seen that, for every choice of an object $a$ in $\\cat{C}$,\nwe get a functor from $\\cat{C}$ to $\\Set$. This kind of\nstructure-preserving mapping to $\\Set$ is often called a\n\\newterm{representation}. We are representing objects and morphisms of\n$\\cat{C}$ as sets and functions in $\\Set$.\n\nThe functor $\\cat{C}(a, -)$ itself is sometimes called representable.\nMore generally, any functor $F$ that is naturally isomorphic to\nthe hom-functor, for some choice of $a$, is called\n\\newterm{representable}. Such a functor must necessarily be\n$\\Set$-valued, since $\\cat{C}(a, -)$ is.\n\nI said before that we often think of isomorphic sets as identical. More\ngenerally, we think of isomorphic \\emph{objects} in a category as\nidentical. That's because objects have no structure other than their\nrelation to other objects (and themselves) through morphisms.\n\nFor instance, we've previously talked about the category of monoids,\n$\\cat{Mon}$, that was initially modeled with sets. But we were careful\nto pick as morphisms only those functions that preserved the monoidal\nstructure of those sets. So if two objects in $\\cat{Mon}$ are\nisomorphic, meaning there is an invertible morphism between them, they\nhave exactly the same structure. If we peeked at the sets and functions\nthat they were based upon, we'd see that the unit element of one monoid\nwas mapped to the unit element of another, and that a product of two\nelements was mapped to the product of their mappings.\n\nThe same reasoning can be applied to functors. Functors between two\ncategories form a category in which natural transformations play the\nrole of morphisms. So two functors are isomorphic, and can be thought of\nas identical, if there is an invertible natural transformation between\nthem.\n\nLet's analyze the definition of the representable functor from this\nperspective. For $F$ to be representable we require that: There\nbe an object $a$ in $\\cat{C}$; one natural transformation $\\alpha$ from\n$\\cat{C}(a, -)$ to $F$; another natural transformation, $\\beta$, in\nthe opposite direction; and that their composition be the identity\nnatural transformation.\n\nLet's look at the component of $\\alpha$ at some object $x$. It's a\nfunction in $\\Set$:\n\\[\\alpha_x \\Colon \\cat{C}(a, x) \\to F x\\]\nThe naturality condition for this transformation tells us that, for any\nmorphism $f$ from $x$ to $y$, the following diagram\ncommutes:\n\\[F f \\circ \\alpha_x = \\alpha_y \\circ \\cat{C}(a, f)\\]\nIn Haskell, we would replace natural transformations with polymorphic\nfunctions:\n\n\\src{snippet06}\nwith the optional \\code{forall} quantifier. The naturality condition\n\n\\src{snippet07}\nis automatically satisfied due to parametricity (it's one of those\ntheorems for free I mentioned earlier), with the understanding that\n\\code{fmap} on the left is defined by the functor $F$, whereas\nthe one on the right is defined by the reader functor. Since\n\\code{fmap} for reader is just function precomposition, we can be even\nmore explicit. Acting on $h$, an element of $\\cat{C}(a, x)$,\nthe naturality condition simplifies to:\n\n\\src{snippet08}\nThe other transformation, \\code{beta}, goes the opposite way:\n\n\\src{snippet09}\nIt must respect naturality conditions, and it must be the inverse of \\code{alpha}:\n\n\\begin{snip}{text}\nalpha . beta = id = beta . alpha\n\\end{snip}\nWe will see later that a natural transformation from $\\cat{C}(a, -)$\nto any $\\Set$-valued functor always exists as long as $F a$ is\nnon-empty (Yoneda's lemma) but it is not necessarily invertible.\n\nLet me give you an example in Haskell with the list functor and\n\\code{Int} as \\code{a}. Here's a natural transformation that does\nthe job:\n\n\\src{snippet10}\nI have arbitrarily picked the number 12 and created a singleton list\nwith it. I can then \\code{fmap} the function \\code{h} over this list\nand get a list of the type returned by \\code{h}. (There are actually\nas many such transformations as there are list of integers.)\n\nThe naturality condition is equivalent to the composability of\n\\code{map} (the list version of \\code{fmap}):\n\n\\src{snippet11}\nBut if we tried to find the inverse transformation, we would have to go\nfrom a list of arbitrary type \\code{x} to a function returning\n\\code{x}:\n\n\\src{snippet12}\nYou might think of retrieving an \\code{x} from the list, e.g., using\n\\code{head}, but that won't work for an empty list. Notice that there\nis no choice for the type \\code{a} (in place of \\code{Int}) that\nwould work here. So the list functor is not representable.\n\nRemember when we talked about Haskell (endo-) functors being a little\nlike containers? In the same vein we can think of representable functors\nas containers for storing memoized results of function calls (the\nmembers of hom-sets in Haskell are just functions). The representing\nobject, the type $a$ in $\\cat{C}(a, -)$, is thought of as the\nkey type, with which we can access the tabulated values of a function.\nThe transformation we called \\code{alpha} is called \\code{tabulate}, and its\ninverse, \\code{beta}, is called \\code{index}. Here's a (slightly simplified)\n\\code{Representable} class definition:\n\n\\src{snippet13}\nNotice that the representing type, our $a$, which is called\n\\code{Rep f} here, is part of the definition of\n\\code{Representable}. The star just means that \\code{Rep f} is a\ntype (as opposed to a type constructor, or other more exotic kinds).\n\nInfinite lists, or streams, which cannot be empty, are representable.\n\n\\src{snippet14}\nYou can think of them as memoized values of a function taking an\n\\code{Integer} as an argument. (Strictly speaking, I should be using\nnon-negative natural numbers, but I didn't want to complicate the code.)\n\nTo \\code{tabulate} such a function, you create an infinite stream of\nvalues. Of course, this is only possible because Haskell is lazy. The\nvalues are evaluated on demand. You access the memoized values using\n\\code{index}:\n\n\\src{snippet15}\nIt's interesting that you can implement a single memoization scheme to\ncover a whole family of functions with arbitrary return types.\n\nRepresentability for contravariant functors is similarly defined, except\nthat we keep the second argument of $\\cat{C}(-, a)$ fixed. Or,\nequivalently, we may consider functors from $\\cat{C}^\\mathit{op}$\nto $\\Set$, because $\\cat{C}^\\mathit{op}(a, -)$ is the same as\n$\\cat{C}(-, a)$.\n\nThere is an interesting twist to representability. Remember that\nhom-sets can internally be treated as exponential objects, in Cartesian\nclosed categories. The hom-set $\\cat{C}(a, x)$ is equivalent to\n$x^a$, and for a representable functor $F$ we can write: $-^a = F$.\n\nLet's take the logarithm of both sides, just for kicks: $a = \\mathbf{log}F$\n\nOf course, this is a purely formal transformation, but if you know some\nof the properties of logarithms, it is quite helpful. In particular, it\nturns out that functors that are based on product types can be\nrepresented with sum types, and that sum-type functors are not in\ngeneral representable (example: the list functor).\n\nFinally, notice that a representable functor gives us two different\nimplementations of the same thing --- one a function, one a data\nstructure. They have exactly the same content --- the same values are\nretrieved using the same keys. That's the sense of ``sameness'' I was\ntalking about. Two naturally isomorphic functors are identical as far as\ntheir contents are involved. On the other hand, the two representations\nare often implemented differently and may have different performance\ncharacteristics. Memoization is used as a performance enhancement and\nmay lead to substantially reduced run times. Being able to generate\ndifferent representations of the same underlying computation is very\nvaluable in practice. So, surprisingly, even though it's not concerned\nwith performance at all, category theory provides ample opportunities to\nexplore alternative implementations that have practical value.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Show that the hom-functors map identity morphisms in $\\cat{C}$ to\n        corresponding identity functions in $\\Set$.\n  \\item\n        Show that \\code{Maybe} is not representable.\n  \\item\n        Is the \\code{Reader} functor representable?\n  \\item\n        Using \\code{Stream} representation, memoize a function that squares\n        its argument.\n  \\item\n        Show that \\code{tabulate} and \\code{index} for \\code{Stream} are\n        indeed the inverse of each other. (Hint: use induction.)\n  \\item\n        The functor:\n\n        \\begin{snip}{haskell}\nPair a = Pair a a\n\\end{snip}\n        is representable. Can you guess the type that represents it? Implement\n        \\code{tabulate} and \\code{index}.\n\\end{enumerate}\n\n\\section{Bibliography}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        The Catsters video about\n        \\urlref{https://www.youtube.com/watch?v=4QgjKUzyrhM}{representable\n          functors}.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/2.5/code/haskell/snippet01.hs",
    "content": "type Reader a x = a -> x"
  },
  {
    "path": "src/content/2.5/code/haskell/snippet02.hs",
    "content": "instance Functor (Reader a) where\n    fmap f h = f . h"
  },
  {
    "path": "src/content/2.5/code/haskell/snippet03.hs",
    "content": "alpha :: forall x . (a -> x) -> F x"
  },
  {
    "path": "src/content/2.5/code/haskell/snippet04.hs",
    "content": "alpha :: forall x . (a -> x) -> F x"
  },
  {
    "path": "src/content/2.5/code/haskell/snippet05.hs",
    "content": "alpha id :: F a"
  },
  {
    "path": "src/content/2.5/code/haskell/snippet06.hs",
    "content": "fa :: F a"
  },
  {
    "path": "src/content/2.5/code/haskell/snippet07.hs",
    "content": "alpha h = fmap h fa"
  },
  {
    "path": "src/content/2.5/code/ocaml/snippet01.ml",
    "content": "type ('a, 'x) reader = 'a -> 'x\n"
  },
  {
    "path": "src/content/2.5/code/ocaml/snippet02.ml",
    "content": "module ReaderFunctor (T : sig\n  type a\nend) : Functor = struct\n  type 'x t = (T.a, 'x) reader\n\n  let fmap : ('x -> 'y) -> 'x t -> 'y t = fun f r a -> f (r a)\nend\n"
  },
  {
    "path": "src/content/2.5/code/ocaml/snippet03.ml",
    "content": "module type NT_AX_FX = sig\n  type a\n  type 'x t\n\n  val alpha : (a -> 'x) -> 'x t\nend\n"
  },
  {
    "path": "src/content/2.5/code/ocaml/snippet04.ml",
    "content": "val alpha : (a -> 'x) -> 'x t\n"
  },
  {
    "path": "src/content/2.5/code/ocaml/snippet05.ml",
    "content": "alpha id : 'a f\n"
  },
  {
    "path": "src/content/2.5/code/ocaml/snippet06.ml",
    "content": "val fa : 'a f\n"
  },
  {
    "path": "src/content/2.5/code/ocaml/snippet07.ml",
    "content": "alpha h = F.fmap h fa\n"
  },
  {
    "path": "src/content/2.5/code/reason/snippet01.re",
    "content": "type reader('a, 'x) = 'a => 'x;\n"
  },
  {
    "path": "src/content/2.5/code/reason/snippet02.re",
    "content": "module ReaderFunctor = (T: {type a;}) : Functor => {\n  type t('x) = reader(T.a, 'x);\n  \n  let fmap: ('x => 'y, t('x)) => t('y) = (\n    (f, r, a) => f(r(a)): ('x => 'y, t('x)) => t('y)\n  );\n};\n"
  },
  {
    "path": "src/content/2.5/code/reason/snippet03.re",
    "content": "module type NT_AX_FX = {\n  type a;\n  type t('x);\n  \n  let alpha: (a => 'x) => t('x);\n};\n"
  },
  {
    "path": "src/content/2.5/code/reason/snippet04.re",
    "content": "let alpha: (a => 'x) => t('x)\n"
  },
  {
    "path": "src/content/2.5/code/reason/snippet05.re",
    "content": "alpha(id) : f('a)"
  },
  {
    "path": "src/content/2.5/code/reason/snippet06.re",
    "content": "let fa: f('a)\n"
  },
  {
    "path": "src/content/2.5/code/reason/snippet07.re",
    "content": "alpha(h) == F.fmap(h, fa);\n"
  },
  {
    "path": "src/content/2.5/code/scala/snippet01.scala",
    "content": "type Reader[A, X] = A => X"
  },
  {
    "path": "src/content/2.5/code/scala/snippet02.scala",
    "content": "implicit def readerFunctor[A] = new Functor[Reader[A, ?]] {\n  def fmap[X, B](f: X => B)(h: Reader[A, X]): Reader[A, B] =\n    f compose h\n}"
  },
  {
    "path": "src/content/2.5/code/scala/snippet03.scala",
    "content": "// In order to make a universal transformation,\n// another type needs to be introduced.\n// To read more about FunctionK (~>):\n// typelevel.org/cats/datatypes/functionk.html\ntrait ~>[F[_], G[_]] {\n  def apply[B](fa: F[B]): G[B]\n}\n\n// Kind Projector plugin provides\n// a more concise syntax for type lambdas:\ndef alpha[A]: (A => ?) ~> F"
  },
  {
    "path": "src/content/2.5/code/scala/snippet04.scala",
    "content": "def alpha[A]: (A => ?) ~> F"
  },
  {
    "path": "src/content/2.5/code/scala/snippet05.scala",
    "content": "alpha(identity): F[A]"
  },
  {
    "path": "src/content/2.5/code/scala/snippet06.scala",
    "content": "def fa[A]: F[A]"
  },
  {
    "path": "src/content/2.5/code/scala/snippet07.scala",
    "content": "alpha(h) == fmap(h)(fa)"
  },
  {
    "path": "src/content/2.5/the-yoneda-lemma.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{M}{ost constructions in} category theory are generalizations of results\nfrom other more specific areas of mathematics. Things like products,\ncoproducts, monoids, exponentials, etc., have been known long before\ncategory theory. They might have been known under different names in\ndifferent branches of mathematics. A Cartesian product in set theory, a\nmeet in order theory, a conjunction in logic --- they are all specific\nexamples of the abstract idea of a categorical product.\n\nThe Yoneda lemma stands out in this respect as a sweeping statement\nabout categories in general with little or no precedent in other\nbranches of mathematics. Some say that its closest analog is Cayley's\ntheorem in group theory (every group is isomorphic to a permutation\ngroup of some set).\n\nThe setting for the Yoneda lemma is an arbitrary category $\\cat{C}$\ntogether with a functor $F$ from $\\cat{C}$ to $\\Set$. We've\nseen in the previous section that some $\\Set$-valued functors are\nrepresentable, that is isomorphic to a hom-functor. The Yoneda lemma\ntells us that all $\\Set$-valued functors can be obtained from\nhom-functors through natural transformations, and it explicitly\nenumerates all such transformations.\n\nWhen I talked about natural transformations, I mentioned that the\nnaturality condition can be quite restrictive. When you define a\ncomponent of a natural transformation at one object, naturality may be\nstrong enough to ``transport'' this component to another object that is\nconnected to it through a morphism. The more arrows between objects in\nthe source and the target categories there are, the more constraints you\nhave for transporting the components of natural transformations.\n$\\Set$ happens to be a very arrow-rich category.\n\nThe Yoneda lemma tells us that a natural transformation between a\nhom-functor and any other functor $F$ is completely determined by\nspecifying the value of its single component at just one point! The rest\nof the natural transformation just follows from naturality conditions.\n\nSo let's review the naturality condition between the two functors\ninvolved in the Yoneda lemma. The first functor is the hom-functor. It\nmaps any object $x$ in $\\cat{C}$ to the set of morphisms\n$\\cat{C}(a, x)$ --- for $a$ a fixed object in $\\cat{C}$. We've\nalso seen that it maps any morphism $f$ from $x \\to y$ to $\\cat{C}(a, f)$.\n\nThe second functor is an arbitrary $\\Set$-valued functor\n$F$.\n\nLet's call the natural transformation between these two functors\n$\\alpha$. Because we are operating in $\\Set$, the components of\nthe natural transformation, like $\\alpha_x$ or $\\alpha_y$, are just\nregular functions between sets:\n\\begin{gather*}\n  \\alpha_x \\Colon \\cat{C}(a, x) \\to F x \\\\\n  \\alpha_y \\Colon \\cat{C}(a, y) \\to F y\n\\end{gather*}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/yoneda1.png}\n\\end{figure}\n\n\\noindent\nAnd because these are just functions, we can look at their values at\nspecific points. But what's a point in the set $\\cat{C}(a, x)$? Here's\nthe key observation: Every point in the set $\\cat{C}(a, x)$ is also a\nmorphism $h$ from $a$ to $x$.\n\nSo the naturality square for $\\alpha$:\n\\[\\alpha_y \\circ \\cat{C}(a, f) = F f \\circ \\alpha_x\\]\nbecomes, point-wise, when acting on $h$:\n\\[\\alpha_y (\\cat{C}(a, f) h) = (F f) (\\alpha_x h)\\]\nYou might recall from the previous section that the action of the\nhom-functor $\\cat{C}(a,-)$ on a morphism $f$ was defined as\nprecomposition:\n\\[\\cat{C}(a, f) h = f \\circ h\\]\nwhich leads to:\n\\[\\alpha_y (f \\circ h) = (F f) (\\alpha_x h)\\]\nJust how strong this condition is can be seen by specializing it to the\ncase of $x = a$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/yoneda2.png}\n\\end{figure}\n\n\\noindent\nIn that case $h$ becomes a morphism from $a$ to\n$a$. We know that there is at least one such morphism,\n$h = \\id_a$. Let's plug it in:\n\\[\\alpha_y f = (F f) (\\alpha_a \\id_a)\\]\nNotice what has just happened: The left hand side is the action of\n$\\alpha_y$ on an arbitrary element $f$ of $\\cat{C}(a, y)$. And\nit is totally determined by the single value of $\\alpha_a$ at\n$\\id_a$. We can pick any such value and it will generate a natural\ntransformation. Since the values of $\\alpha_a$ are in the set\n$F a$, any point in $F a$ will define some $\\alpha$.\n\nConversely, given any natural transformation $\\alpha$ from\n$\\cat{C}(a, -)$ to $F$, you can evaluate it at $\\id_a$ to\nget a point in $F a$.\n\nWe have just proven the Yoneda lemma:\n\n\\begin{quote}\n  There is a one-to-one correspondence between natural transformations\n  from $\\cat{C}(a, -)$ to $F$ and elements of $F a$.\n\\end{quote}\nin other words,\n\\[\\mathit{Nat}(\\cat{C}(a, -), F) \\cong F a\\]\nOr, if we use the notation $[\\cat{C}, \\Set]$ for the functor\ncategory between $\\cat{C}$ and $\\Set$, the set of natural\ntransformation is just a hom-set in that category, and we can write:\n\\[[\\cat{C}, \\Set](\\cat{C}(a, -), F) \\cong F a\\]\nI'll explain later how this correspondence is in fact a natural\nisomorphism.\n\nNow let's try to get some intuition about this result. The most amazing\nthing is that the whole natural transformation crystallizes from just\none nucleation site: the value we assign to it at $\\id_a$. It\nspreads from that point following the naturality condition. It floods\nthe image of $\\cat{C}$ in $\\Set$. So let's first consider what the\nimage of $\\cat{C}$ is under $\\cat{C}(a, -)$.\n\nLet's start with the image of $a$ itself. Under the hom-functor\n$\\cat{C}(a, -)$, $a$ is mapped to the set $\\cat{C}(a, a)$.\nUnder the functor $F$, on the other hand, it is mapped to the set\n$F a$. The component of the natural transformation $\\alpha_a$\nis some function from $\\cat{C}(a, a)$ to $F a$. Let's focus on\njust one point in the set $\\cat{C}(a, a)$, the point corresponding to\nthe morphism $\\id_a$. To emphasize the fact that it's just a point\nin a set, let's call it $p$. The component $\\alpha_a$ should map\n$p$ to some point $q$ in $F a$. I'll show you that\nany choice of $q$ leads to a unique natural transformation.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/yoneda3.png}\n\\end{figure}\n\n\\noindent\nThe first claim is that the choice of one point $q$ uniquely\ndetermines the rest of the function $\\alpha_a$. Indeed, let's pick any\nother point, $p'$ in $\\cat{C}(a, a)$, corresponding to\nsome morphism $g$ from $a$ to $a$. And here's where\nthe magic of the Yoneda lemma happens: $g$ can be viewed as a\npoint $p'$ in the set $\\cat{C}(a, a)$. At the same time,\nit selects two \\emph{functions} between sets. Indeed, under the\nhom-functor, the morphism $g$ is mapped to a function\n$\\cat{C}(a, g)$; and under $F$ it's mapped to $F g$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/yoneda4.png}\n\\end{figure}\n\n\\noindent\nNow let's consider the action of $\\cat{C}(a, g)$ on our original\n$p$ which, as you remember, corresponds to $\\id_a$. It is\ndefined as precomposition, $g \\circ \\id_a$, which is equal to $g$,\nwhich corresponds to our point $p'$. So the morphism\n$g$ is mapped to a function that, when acting on $p$\nproduces $p'$, which is $g$. We have come full\ncircle!\n\nNow consider the action of $F g$ on $q$. It is some\n$q'$, a point in $F a$. To complete the naturality\nsquare, $p'$ must be mapped to $q'$ under\n$\\alpha_a$. We picked an arbitrary $p'$ (an arbitrary\n$g$) and derived its mapping under $\\alpha_a$. The function\n$\\alpha_a$ is thus completely determined.\n\nThe second claim is that $\\alpha_x$ is uniquely determined for any\nobject $x$ in $\\cat{C}$ that is connected to $a$. The\nreasoning is analogous, except that now we have two more sets,\n$\\cat{C}(a, x)$ and $F x$, and the morphism $g$ from\n$a$ to $x$ is mapped, under the hom-functor, to:\n\\[\\cat{C}(a, g) \\Colon \\cat{C}(a, a) \\to \\cat{C}(a, x)\\]\nand under $F$ to:\n\\[F g \\Colon F a \\to F x\\]\nAgain, $\\cat{C}(a, g)$ acting on our $p$ is given by the\nprecomposition: $g \\circ \\id_a$, which corresponds to a point\n$p'$ in $\\cat{C}(a, x)$. Naturality determines the value\nof $\\alpha_x$ acting on $p'$ to be:\n\\[q' = (F g) q\\]\nSince $p'$ was arbitrary, the whole function $\\alpha_x$ is\nthus determined.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/yoneda5.png}\n\\end{figure}\n\n\\noindent\nWhat if there are objects in $\\cat{C}$ that have no connection to\n$a$? They are all mapped under $\\cat{C}(a, -)$ to a single set\n--- the empty set. Recall that the empty set is the initial object in\nthe category of sets. It means that there is a unique function from this\nset to any other set. We called this function \\code{absurd}. So here,\nagain, we have no choice for the component of the natural\ntransformation: it can only be \\code{absurd}.\n\nOne way of understanding the Yoneda lemma is to realize that natural\ntransformations between $\\Set$-valued functors are just families\nof functions, and functions are in general lossy. A function may\ncollapse information and it may cover only parts of its codomain. The\nonly functions that are not lossy are the ones that are invertible ---\nthe isomorphisms. It follows then that the best structure-preserving\n$\\Set$-valued functors are the representable ones. They are either\nthe hom-functors or the functors that are naturally isomorphic to\nhom-functors. Any other functor $F$ is obtained from a\nhom-functor through a lossy transformation. Such a transformation may\nnot only lose information, but it may also cover only a small part of\nthe image of the functor $F$ in $\\Set$.\n\n\\section{Yoneda in Haskell}\n\nWe have already encountered the hom-functor in Haskell under the guise\nof the reader functor:\n\n\\src{snippet01}\nThe reader maps morphisms (here, functions) by precomposition:\n\n\\src{snippet02}\nThe Yoneda lemma tells us that the reader functor can be naturally\nmapped to any other functor.\n\nA natural transformation is a polymorphic function. So given a functor\n\\code{F}, we have a mapping to it from the reader functor:\n\n\\src{snippet03}\nAs usual, \\code{forall} is optional, but I like to write it explicitly\nto emphasize parametric polymorphism of natural transformations.\n\nThe Yoneda lemma tells us that these natural transformations are in\none-to-one correspondence with the elements of \\code{F a}:\n\n\\begin{snipv}\nforall x . (a -> x) -> F x \\ensuremath{\\cong} F a\n\\end{snipv}\nThe right hand side of this identity is what we would normally consider\na data structure. Remember the interpretation of functors as generalized\ncontainers? \\code{F a} is a container of \\code{a}. But the left\nhand side is a polymorphic function that takes a function as an\nargument. The Yoneda lemma tells us that the two representations are\nequivalent --- they contain the same information.\n\nAnother way of saying this is: Give me a polymorphic function of the\ntype:\n\n\\src{snippet04}\nand I'll produce a container of \\code{a}. The trick is the one we used\nin the proof of the Yoneda lemma: we call this function with \\code{id}\nto get an element of \\code{F a}:\n\n\\src{snippet05}\nThe converse is also true: Given a value of the type \\code{F a}:\n\n\\src{snippet06}\none can define a polymorphic function:\n\n\\src{snippet07}\nof the correct type. You can easily go back and forth between the two\nrepresentations.\n\nThe advantage of having multiple representations is that one might be\neasier to compose than the other, or that one might be more efficient in\nsome applications than the other.\n\nThe simplest illustration of this principle is the code transformation\nthat is often used in compiler construction: the continuation passing\nstyle or \\acronym{CPS}. It's the simplest application of the Yoneda lemma to the\nidentity functor. Replacing \\code{F} with identity produces:\n\n\\begin{snipv}\nforall r . (a -> r) -> r \\ensuremath{\\cong} a\n\\end{snipv}\nThe interpretation of this formula is that any type \\code{a} can be\nreplaced by a function that takes a ``handler'' for \\code{a}. A\nhandler is a function accepting \\code{a} and performing the rest of\nthe computation --- the continuation. (The type \\code{r} usually\nencapsulates some kind of status code.)\n\nThis style of programming is very common in UIs, in asynchronous\nsystems, and in concurrent programming. The drawback of \\acronym{CPS} is that it\ninvolves inversion of control. The code is split between producers and\nconsumers (handlers), and is not easily composable. Anybody who's done\nany amount of nontrivial web programming is familiar with the nightmare\nof spaghetti code from interacting stateful handlers. As we'll see\nlater, judicious use of functors and monads can restore some\ncompositional properties of \\acronym{CPS}.\n\n\\section{Co-Yoneda}\n\nAs usual, we get a bonus construction by inverting the direction of\narrows. The Yoneda lemma can be applied to the opposite category\n$\\cat{C}^\\mathit{op}$ to give us a mapping between contravariant\nfunctors.\n\nEquivalently, we can derive the co-Yoneda lemma by fixing the target\nobject of our hom-functors instead of the source. We get the\ncontravariant hom-functor from $\\cat{C}$ to $\\Set$:\n$\\cat{C}(-, a)$. The contravariant version of the Yoneda lemma\nestablishes one-to-one correspondence between natural transformations\nfrom this functor to any other contravariant functor $F$ and the\nelements of the set $F a$:\n\\[\\mathit{Nat}(\\cat{C}(-, a), F) \\cong F a\\]\nHere's the Haskell version of the co-Yoneda lemma:\n\n\\begin{snipv}\nforall x . (x -> a) -> F x \\ensuremath{\\cong} F a\n\\end{snipv}\nNotice that in some literature it's the contravariant version that's\ncalled the Yoneda lemma.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Show that the two functions \\code{phi} and \\code{psi} that form\n        the Yoneda isomorphism in Haskell are inverses of each other.\n\n        \\begin{snip}{haskell}\nphi :: (forall x . (a -> x) -> F x) -> F a\nphi alpha = alpha id\n\npsi :: F a -> (forall x . (a -> x) -> F x)\npsi fa h = fmap h fa\n\\end{snip}\n  \\item\n        A discrete category is one that has objects but no morphisms other\n        than identity morphisms. How does the Yoneda lemma work for functors\n        from such a category?\n  \\item\n        A list of units \\code{{[}(){]}} contains no other information but\n        its length. So, as a data type, it can be considered an encoding of\n        integers. An empty list encodes zero, a singleton \\code{{[}(){]}} (a\n        value, not a type) encodes one, and so on. Construct another\n        representation of this data type using the Yoneda lemma for the list\n        functor.\n\\end{enumerate}\n\n\\section{Bibliography}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        \\urlref{https://www.youtube.com/watch?v=TLMxHB19khE}{Catsters} video.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/2.6/code/haskell/snippet01.hs",
    "content": "fromY :: (a -> x) -> b -> x\nfromY f b = f (btoa b)"
  },
  {
    "path": "src/content/2.6/code/haskell/snippet02.hs",
    "content": "fromY id :: b -> a"
  },
  {
    "path": "src/content/2.6/code/ocaml/snippet01.ml",
    "content": "module type BtoA = sig\n  type a\n  type b\n\n  val btoa : b -> a\nend\n\n(* Define the Yoneda embedding *)\nmodule Yoneda_Embedding (E : BtoA) = struct\n  let fromY : 'x. (E.a -> 'x) -> E.b -> 'x = fun f b -> f (E.btoa b)\nend\n"
  },
  {
    "path": "src/content/2.6/code/ocaml/snippet02.ml",
    "content": "module YE = Yoneda_Embedding(BtoAImpl)\nYE.fromY id (* output type : BtoA.b -> BtoA.a *)\n"
  },
  {
    "path": "src/content/2.6/code/reason/snippet01.re",
    "content": "module type BtoA = {\n  type a;\n  type b;\n\n  let btoa: b => a;\n};\n\n/* Define the Yoneda embedding */\nmodule Yoneda_Embedding = (E: BtoA) => {\n  let fromY: 'x. (E.a => 'x, E.b) => 'x = (f, b) => f(E.btoa(b));\n};\n"
  },
  {
    "path": "src/content/2.6/code/reason/snippet02.re",
    "content": "module YE = Yoneda_Embedding(BtoAImpl);\nYE.fromY(id) /* output type : BtoA.b => BtoA.a */\n"
  },
  {
    "path": "src/content/2.6/code/scala/snippet01.scala",
    "content": "// In order to make a universal transformation,\n// another type needs to be introduced.\n// To read more about FunctionK (~>):\n// typelevel.org/cats/datatypes/functionk.html\ntrait ~>[F[_], G[_]] {\n  def apply[X](fa: F[X]): G[X]\n}\n\ndef fromY[A, B]: (A => ?) ~> (B => ?) = new ~>[A => ?, B => ?] {\n  def apply[X](f: A => X): B => X =\n    b => f(btoa(b))\n}"
  },
  {
    "path": "src/content/2.6/code/scala/snippet02.scala",
    "content": "fromY(identity): B => A"
  },
  {
    "path": "src/content/2.6/yoneda-embedding.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{W}{e've seen previously} that, when we fix an object $a$ in the\ncategory $\\cat{C}$, the mapping $\\cat{C}(a, -)$ is a (covariant)\nfunctor from $\\cat{C}$ to $\\Set$.\n\\[x \\to \\cat{C}(a, x)\\]\n(The codomain is $\\Set$ because the hom-set $\\cat{C}(a, x)$ is a\n\\emph{set}.) We call this mapping a hom-functor --- we have previously\ndefined its action on morphisms as well.\n\nNow let's vary $a$ in this mapping. We get a new mapping that\nassigns the hom-\\emph{functor} $\\cat{C}(a, -)$ to any $a$.\n\\[a \\to \\cat{C}(a, -)\\]\nIt's a mapping of objects from category $\\cat{C}$ to functors, which are\n\\emph{objects} in the functor category (see the section about functor\ncategories in\n\\hyperref[natural-transformations]{Natural\n  Transformations}). Let's use the notation $[\\cat{C}, \\Set]$ for the\nfunctor category from $\\cat{C}$ to $\\Set$. You may also recall that\nhom-functors are the prototypical\n\\hyperref[representable-functors]{representable\n  functors}.\n\nEvery time we have a mapping of objects between two categories, it's\nnatural to ask if such a mapping is also a functor. In other words\nwhether we can lift a morphism from one category to a morphism in the\nother category. A morphism in $\\cat{C}$ is just an element of\n$\\cat{C}(a, b)$, but a morphism in the functor category\n$[\\cat{C}, \\Set]$ is a natural transformation. So we are looking\nfor a mapping of morphisms to natural transformations.\n\nLet's see if we can find a natural transformation corresponding to a\nmorphism $f \\Colon a \\to b$. First, lets see what\n$a$ and $b$ are mapped to. They are mapped to two\nfunctors: $\\cat{C}(a, -)$ and $\\cat{C}(b, -)$. We need a natural\ntransformation between those two functors.\n\nAnd here's the trick: we use the Yoneda lemma:\n\\[[\\cat{C}, \\Set](\\cat{C}(a, -), F) \\cong F a\\]\nand replace the generic $F$ with the hom-functor\n$\\cat{C}(b, -)$. We get:\n\\[[\\cat{C}, \\Set](\\cat{C}(a, -), \\cat{C}(b, -)) \\cong \\cat{C}(b, a)\\]\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.6\\textwidth]{images/yoneda-embedding.jpg}\n\\end{figure}\n\n\\noindent\nThis is exactly the natural transformation between the two hom-functors\nwe were looking for, but with a little twist: We have a mapping between\na natural transformation and a morphism --- an element of\n$\\cat{C}(b, a)$ --- that goes in the ``wrong'' direction. But that's\nokay; it only means that the functor we are looking at is contravariant.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.65\\textwidth]{images/yoneda-embedding-2.jpg}\n\\end{figure}\n\n\\noindent\nActually, we've got even more than we bargained for. The mapping from\n$\\cat{C}$ to $[\\cat{C}, \\Set]$ is not only a contravariant functor\n--- it is a \\emph{fully faithful} functor. Fullness and faithfulness are\nproperties of functors that describe how they map hom-sets.\n\nA \\emph{faithful} functor is \\newterm{injective} on hom-sets, meaning that\nit maps distinct morphisms to distinct morphisms. In other words, it\ndoesn't coalesce them.\n\nA \\emph{full} functor is \\newterm{surjective} on hom-sets, meaning that it\nmaps one hom-set \\emph{onto} the other hom-set, fully covering the\nlatter.\n\nA fully faithful functor $F$ is a \\newterm{bijection} on hom-sets\n--- a one to one matching of all elements of both sets. For every pair\nof objects $a$ and $b$ in the source category $\\cat{C}$\nthere is a bijection between $\\cat{C}(a, b)$ and\n$\\cat{D}(F a, F b)$, where $\\cat{D}$ is the target category of\n$F$ (in our case, the functor category, $[\\cat{C}, \\Set]$).\nNotice that this doesn't mean that $F$ is a bijection on\n\\emph{objects}. There may be objects in $\\cat{D}$ that are not in the\nimage of $F$, and we can't say anything about hom-sets for those\nobjects.\n\n\\section{The Embedding}\n\nThe (contravariant) functor we have just described, the functor that\nmaps objects in $\\cat{C}$ to functors in $[\\cat{C}, \\Set]$:\n\\[a \\to \\cat{C}(a, -)\\]\ndefines the \\newterm{Yoneda embedding}. It \\emph{embeds} a category\n$\\cat{C}$ (strictly speaking, the category $\\cat{C}^\\mathit{op}$,\nbecause of contravariance) inside the functor category\n$[\\cat{C}, \\Set]$. It not only maps objects in $\\cat{C}$ to\nfunctors, but also faithfully preserves all connections between them.\n\nThis is a very useful result because mathematicians know a lot about the\ncategory of functors, especially functors whose codomain is\n$\\Set$. We can get a lot of insight about an arbitrary category\n$\\cat{C}$ by embedding it in the functor category.\n\nOf course there is a dual version of the Yoneda embedding, sometimes\ncalled the co-Yoneda embedding. Observe that we could have started by\nfixing the target object (rather than the source object) of each\nhom-set, $\\cat{C}(-, a)$. That would give us a contravariant\nhom-functor. Contravariant functors from $\\cat{C}$ to $\\Set$ are\nour familiar presheaves (see, for instance,\n\\hyperref[limits-and-colimits]{Limits\n  and Colimits}). The co-Yoneda embedding defines the embedding of a\ncategory $\\cat{C}$ in the category of presheaves. Its action on morphisms\nis given by:\n\\[[\\cat{C}^\\mathit{op}, \\Set](\\cat{C}(-, a), \\cat{C}(-, b)) \\cong \\cat{C}(a, b)\\]\nAgain, mathematicians know a lot about the category of presheaves, so\nbeing able to embed an arbitrary category in it is a big win.\n\n\\section{Application to Haskell}\n\nIn Haskell, the Yoneda embedding can be represented as the isomorphism\nbetween natural transformations amongst reader functors on the one hand,\nand functions (going in the opposite direction) on the other hand:\n\n\\begin{snipv}\nforall x. (a -> x) -> (b -> x) \\ensuremath{\\cong} b -> a\n\\end{snipv}\n(Remember, the reader functor is equivalent to\n\\code{((->) a)}.)\n\nThe left hand side of this identity is a polymorphic function that,\ngiven a function from \\code{a} to \\code{x} and a value of type\n\\code{b}, can produce a value of type \\code{x} (I'm uncurrying ---\ndropping the parentheses around --- the function\n\\code{b -> x}). The only way this can be done for all\n\\code{x} is if our function knows how to convert a \\code{b} to an\n\\code{a}. It has to secretly have access to a function\n\\code{b -> a}.\n\nGiven such a converter, \\code{btoa}, one can define the left hand\nside, call it \\code{fromY}, as:\n\n\\src{snippet01}\nConversely, given a function \\code{fromY} we can recover the converter\nby calling \\code{fromY} with the identity:\n\n\\src{snippet02}\nThis establishes the bijection between functions of the type\n\\code{fromY} and \\code{btoa}.\n\nAn alternative way of looking at this isomorphism is that it's a \\acronym{CPS}\nencoding of a function from \\code{b} to \\code{a}. The argument\n\\code{a -> x} is a continuation (the handler). The result\nis a function from \\code{b} to \\code{x} which, when called with a\nvalue of type \\code{b}, will execute the continuation precomposed with\nthe function being encoded.\n\nThe Yoneda embedding also explains some of the alternative\nrepresentations of data structures in Haskell. In particular, it\nprovides a \\urlref{https://bartoszmilewski.com/2015/07/13/from-lenses-to-yoneda-embedding/}\n{very useful representation}\nof lenses from the \\code{Control.Lens} library.\n\n\\section{Preorder Example}\n\nThis example was suggested by Robert Harper. It's the application of the\nYoneda embedding to a category defined by a preorder. A preorder is a\nset with an ordering relation between its elements that's traditionally\nwritten as $\\leqslant$ (less than or equal). The ``pre'' in\npreorder is there because we're only requiring the relation to be\ntransitive and reflexive but not necessarily antisymmetric (so it's\npossible to have cycles).\n\nA set with the preorder relation gives rise to a category. The objects\nare the elements of this set. A morphism from object $a$ to\n$b$ either doesn't exist, if the objects cannot be compared or if\nit's not true that $a \\leqslant b$; or it exists if\n$a \\leqslant b$, and it points from $a$ to\n$b$. There is never more than one morphism from one object to\nanother. Therefore any hom-set in such a category is either an empty set\nor a one-element set. Such a category is called \\emph{thin}.\n\nIt's easy to convince yourself that this construction is indeed a\ncategory: The arrows are composable because, if\n$a \\leqslant b$ and $b \\leqslant c$ then\n$a \\leqslant c$; and the composition is associative. We also\nhave the identity arrows because every element is (less than or) equal\nto itself (reflexivity of the underlying relation).\n\nWe can now apply the co-Yoneda embedding to a preorder category. In\nparticular, we're interested in its action on morphisms:\n\\[[\\cat{C}, \\Set](\\cat{C}(-, a), \\cat{C}(-, b)) \\cong \\cat{C}(a, b)\\]\nThe hom-set on the right hand side is non-empty if and only if\n$a \\leqslant b$ --- in which case it's a one-element set.\nConsequently, if $a \\leqslant b$, there exists a single\nnatural transformation on the left. Otherwise there is no natural\ntransformation.\n\nSo what's a natural transformation between hom-functors in a preorder?\nIt should be a family of functions between sets $\\cat{C}(-, a)$ and\n$\\cat{C}(-, b)$. In a preorder, each of these sets can either be empty\nor a singleton. Let's see what kind of functions are there at our\ndisposal.\n\nThere is a function from an empty set to itself (the identity acting on\nan empty set), a function \\code{absurd} from an empty set to a\nsingleton set (it does nothing, since it only needs to be defined for\nelements of an empty set, of which there are none), and a function from\na singleton to itself (the identity acting on a one-element set). The\nonly combination that is forbidden is the mapping from a singleton to an\nempty set (what would the value of such a function be when acting on the\nsingle element?).\n\nSo our natural transformation will never connect a singleton hom-set to\nan empty hom-set. In other words, if $x \\leqslant a$\n(singleton hom-set $\\cat{C}(x, a)$) then $\\cat{C}(x, b)$ cannot be\nempty. A non-empty $\\cat{C}(x, b)$ means that $x$ is less or\nequal to $b$. So the existence of the natural transformation in\nquestion requires that, for every $x$, if\n$x \\leqslant a$ then $x \\leqslant b$.\n\\[\\text{for all } x, x \\leqslant a \\Rightarrow x \\leqslant b\\]\nOn the other hand, co-Yoneda tells us that the existence of this natural\ntransformation is equivalent to $\\cat{C}(a, b)$ being non-empty, or to\n$a \\leqslant b$. Together, we get:\n\\[a \\leqslant b \\text{ if and only if for all } x, x \\leqslant a \\Rightarrow x \\leqslant b\\]\nWe could have arrived at this result directly. The intuition is that, if\n$a \\leqslant b$ then all elements that are below $a$\nmust also be below $b$. Conversely, when you substitute\n$a$ for $x$ on the right hand side, it follows that\n$a \\leqslant b$. But you must admit that arriving at this\nresult through the Yoneda embedding is much more exciting.\n\n\\section{Naturality}\n\nThe Yoneda lemma establishes the isomorphism between the set of natural\ntransformations and an object in $\\Set$. Natural transformations\nare morphisms in the functor category $[\\cat{C}, \\Set]$. The set of\nnatural transformation between any two functors is a hom-set in that\ncategory. The Yoneda lemma is the isomorphism:\n\\[[\\cat{C}, \\Set](\\cat{C}(a, -), F) \\cong F a\\]\nThis isomorphism turns out to be natural in both $F$ and\n$a$. In other words, it's natural in $(F, a)$, a pair\ntaken from the product category  $[\\cat{C}, \\Set] \\times \\cat{C}$. Notice\nthat we are now treating $F$ as an \\newterm{object} in the functor\ncategory.\n\nLet's think for a moment what this means. A natural isomorphism is an\ninvertible \\emph{natural transformation} between two functors. And\nindeed, the right hand side of our isomorphism is a functor. It's a\nfunctor from $[\\cat{C}, \\Set] \\times \\cat{C}$ to $\\Set$. Its action on\na pair $(F, a)$ is a set --- the result of evaluating the\nfunctor $F$ at the object $a$. This is called the\nevaluation functor.\n\nThe left hand side is also a functor that takes $(F, a)$ to a\nset of natural transformations $[\\cat{C}, \\Set](\\cat{C}(a, -), F)$.\n\nTo show that these are really functors, we should also define their\naction on morphisms. But what's a morphism between a pair\n$(F, a)$ and $(G, b)$? It's a pair of morphisms,\n$(\\Phi, f)$; the first being a morphism between functors --- a\nnatural transformation --- the second being a regular morphism in\n$\\cat{C}$.\n\nThe evaluation functor takes this pair $(\\Phi, f)$ and maps it to a\nfunction between two sets, $F a$ and $G b$. We can\neasily construct such a function from the component of $\\Phi$ at\n$a$ (which maps $F a$ to $G a$) and the morphism\n$f$ lifted by $G$:\n\\[(G f) \\circ \\Phi_a\\]\nNotice that, because of naturality of $\\Phi$, this is the same as:\n\\[\\Phi_b \\circ (F f)\\]\nI'm not going to prove the naturality of the whole isomorphism --- after\nyou've established what the functors are, the proof is pretty\nmechanical. It follows from the fact that our isomorphism is built up\nfrom functors and natural transformations. There is simply no way for it\nto go wrong.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Express the co-Yoneda embedding in Haskell.\n  \\item\n        Show that the bijection we established between \\code{fromY} and\n        \\code{btoa} is an isomorphism (the two mappings are the inverse of\n        each other).\n  \\item\n        Work out the Yoneda embedding for a monoid. What functor corresponds\n        to the monoid's single object? What natural transformations correspond\n        to monoid morphisms?\n  \\item\n        What is the application of the \\emph{covariant} Yoneda embedding to\n        preorders? (Question suggested by Gershom Bazerman.)\n  \\item\n        Yoneda embedding can be used to embed an arbitrary functor category\n        $[\\cat{C}, \\cat{D}]$ in the functor category\n        $[[\\cat{C}, \\cat{D}], \\Set]$. Figure out how it works on morphisms\n        (which in this case are natural transformations).\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.1/its-all-about-morphisms.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{f I haven't} convinced you yet that category theory is all about\nmorphisms then I haven't done my job properly. Since the next topic is\nadjunctions, which are defined in terms of isomorphisms of hom-sets, it\nmakes sense to review our intuitions about the building blocks of\nhom-sets. Also, you'll see that adjunctions provide a more general\nlanguage to describe a lot of constructions we've studied before, so it\nmight help to review them too.\n\n\\section{Functors}\n\nTo begin with, you should really think of functors as mappings of\nmorphisms --- the view that's emphasized in the Haskell definition of\nthe \\code{Functor} typeclass, which revolves around \\code{fmap}. Of\ncourse, functors also map objects --- the endpoints of morphisms ---\notherwise we wouldn't be able to talk about preserving composition.\nObjects tell us which pairs of morphisms are composable. The target of\none morphism must be equal to the source of the other --- if they are to\nbe composed. So if we want the composition of morphisms to be mapped to\nthe composition of \\newterm{lifted} morphisms, the mapping of their\nendpoints is pretty much determined.\n\n\\section{Commuting Diagrams}\n\nA lot of properties of morphisms are expressed in terms of commuting\ndiagrams. If a particular morphism can be described as a composition of\nother morphisms in more than one way, then we have a commuting diagram.\n\nIn particular, commuting diagrams form the basis of almost all universal\nconstructions (with the notable exceptions of the initial and terminal\nobjects). We've seen this in the definitions of products, coproducts,\nvarious other (co-)limits, exponential objects, free monoids, etc.\n\nThe product is a simple example of a universal construction. We pick two\nobjects $a$ and $b$ and see if there exists an object\n$c$, together with a pair of morphisms $p$ and $q$,\nthat has the universal property of being their product.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/productranking.jpg}\n\\end{figure}\n\n\\noindent\nA product is a special case of a limit. A limit is defined in terms of\ncones. A general cone is built from commuting diagrams. Commutativity of\nthose diagrams may be replaced with a suitable naturality condition for\nthe mapping of functors. This way commutativity is reduced to the role\nof the assembly language for the higher level language of natural\ntransformations.\n\n\\section{Natural Transformations}\n\nIn general, natural transformations are very convenient whenever we need\na mapping from morphisms to commuting squares. Two opposing sides of a\nnaturality square are the mappings of some morphism $f$ under two\nfunctors $F$ and $G$. The other sides are the components\nof the natural transformation (which are also morphisms).\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/3_naturality.jpg}\n\\end{figure}\n\n\\noindent\nNaturality means that when you move to the ``neighboring'' component (by\nneighboring I mean connected by a morphism), you're not going against\nthe structure of either the category or the functors. It doesn't matter\nwhether you first use a component of the natural transformation to\nbridge the gap between objects, and then jump to its neighbor using the\nfunctor; or the other way around. The two directions are orthogonal. A\nnatural transformation moves you left and right, and the functors move\nyou up and down or back and forth --- so to speak. You can visualize the\n\\emph{image} of a functor as a sheet in the target category. A natural\ntransformation maps one such sheet corresponding to $F$, to another,\ncorresponding to $G$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/sheets.png}\n\\end{figure}\n\n\\noindent\nWe've seen examples of this orthogonality in Haskell. There the action\nof a functor modifies the content of a container without changing its\nshape, while a natural transformation repackages the untouched contents\ninto a different container. The order of these operations doesn't\nmatter.\n\nWe've seen the cones in the definition of a limit replaced by natural\ntransformations. Naturality ensures that the sides of every cone\ncommute. Still, a limit is defined in terms of mappings \\emph{between}\ncones. These mappings must also satisfy commutativity conditions. (For\ninstance, the triangles in the definition of the product must commute.)\n\nThese conditions, too, may be replaced by naturality. You may recall\nthat the \\emph{universal} cone, or the limit, is defined as a natural\ntransformation between the (contravariant) hom-functor:\n\\[F \\Colon c \\to \\cat{C}(c, \\Lim[D])\\]\nand the (also contravariant) functor that maps objects in $\\cat{C}$ to\ncones, which themselves are natural transformations:\n\\[G \\Colon c \\to \\mathit{Nat}(\\Delta_c, D)\\]\nHere, $\\Delta_c$ is the constant functor, and $D$ is the functor\nthat defines the diagram in $\\cat{C}$. Both functors $F$ and\n$G$ have well defined actions on morphisms in $\\cat{C}$. It so\nhappens that this particular natural transformation between $F$\nand $G$ is an \\emph{isomorphism}.\n\n\\section{Natural Isomorphisms}\n\nA natural isomorphism --- which is a natural transformation whose every\ncomponent is reversible --- is category theory's way of saying that\n``two things are the same.'' A component of such a transformation must\nbe an isomorphism between objects --- a morphism that has the inverse.\nIf you visualize functor images as sheets, a natural isomorphism is a\none-to-one invertible mapping between those sheets.\n\n\\section{Hom-Sets}\n\nBut what are morphisms? They do have more structure than objects: unlike\nobjects, morphisms have two ends. But if you fix the source and the\ntarget objects, the morphisms between the two form a boring set (at\nleast for locally small categories). We can give elements of this set\nnames like $f$ or $g$, to distinguish one from another ---\nbut what is it, really, that makes them different?\n\nThe essential difference between morphisms in a given hom-set lies in\nthe way they compose with other morphisms (from abutting hom-sets). If\nthere is a morphism $h$ whose composition (either pre- or post-)\nwith $f$ is different than that with $g$, for instance:\n\\[h \\circ f \\neq h \\circ g\\]\nthen we can directly ``observe'' the difference between $f$ and\n$g$. But even if the difference is not directly observable, we\nmight use functors to zoom in on the hom-set. A functor $F$ may\nmap the two morphisms to distinct morphisms:\n\\[F f \\neq F g\\]\nin a richer category, where the abutting hom-sets provide more\nresolution, e.g.,\n\\[h' \\circ F f \\neq h' \\circ F g\\]\nwhere $h'$ is not in the image of $F$.\n\n\\section{Hom-Set Isomorphisms}\n\nA lot of categorical constructions rely on isomorphisms between\nhom-sets. But since hom-sets are just sets, a plain isomorphism between\nthem doesn't tell you much. For finite sets, an isomorphism just says\nthat they have the same number of elements. If the sets are infinite,\ntheir cardinality must be the same. But any meaningful isomorphism of\nhom-sets must take into account composition. And composition involves\nmore than one hom-set. We need to define isomorphisms that span whole\ncollections of hom-sets, and we need to impose some compatibility\nconditions that interoperate with composition. And a \\newterm{natural}\nisomorphism fits the bill exactly.\n\nBut what's a natural isomorphism of hom-sets? Naturality is a property\nof mappings between functors, not sets. So we are really talking about a\nnatural isomorphism between hom-set-valued functors. These functors are\nmore than just set-valued functors. Their action on morphisms is induced\nby the appropriate hom-functors. Morphisms are canonically mapped by\nhom-functors using either pre- or post-composition (depending on the\ncovariance of the functor).\n\nThe Yoneda embedding is one example of such an isomorphism. It maps\nhom-sets in $\\cat{C}$ to hom-sets in the functor category; and it's\nnatural. One functor in the Yoneda embedding is the hom-functor in\n$\\cat{C}$ and the other maps objects to sets of natural transformations\nbetween hom-sets.\n\nThe definition of a limit is also a natural isomorphism between hom-sets\n(the second one, again, in the functor category):\n\\[\\cat{C}(c, \\Lim[D]) \\simeq \\mathit{Nat}(\\Delta_c, D)\\]\nIt turns out that our construction of an exponential object, or that of\na free monoid, can also be rewritten as a natural isomorphism between\nhom-sets.\n\nThis is no coincidence --- we'll see next that these are just different\nexamples of adjunctions, which are defined as natural isomorphisms of\nhom-sets.\n\n\\section{Asymmetry of Hom-Sets}\n\nThere is one more observation that will help us understand adjunctions.\nHom-sets are, in general, not symmetric. A hom-set $\\cat{C}(a, b)$ is\noften very different from the hom-set $\\cat{C}(b, a)$. The ultimate\ndemonstration of this asymmetry is a partial order viewed as a category.\nIn a partial order, a morphism from $a$ to $b$ exists if\nand only if $a$ is less than or equal to $b$. If\n$a$ and $b$ are different, then there can be no morphism\ngoing the other way, from $b$ to $a$. So if the hom-set\n$\\cat{C}(a, b)$ is non-empty, which in this case means it's a\nsingleton set, then $\\cat{C}(b, a)$ must be empty, unless\n$a = b$. The arrows in this category have a definite flow in\none direction.\n\nA preorder, which is based on a relation that's not necessarily\nantisymmetric, is also ``mostly'' directional, except for occasional\ncycles. It's convenient to think of an arbitrary category as a\ngeneralization of a preorder.\n\nA preorder is a thin category --- all hom-sets are either singletons or\nempty. We can visualize a general category as a ``thick'' preorder.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Consider some degenerate cases of a naturality condition and draw the\n        appropriate diagrams. For instance, what happens if either functor\n        $F$ or $G$ map both objects $a$ and $b$\n        (the ends of $f \\Colon a \\to b$) to the same\n        object, e.g., $F a = F b$ or $G a = G b$?\n        (Notice that you get a cone or a co-cone this way.) Then consider\n        cases where either $F a = G a$ or $F b = G b$.\n        Finally, what if you start with a morphism that loops on itself ---\n        $f \\Colon a \\to a$?\n\\end{enumerate}"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet01.hs",
    "content": "class Profunctor p where\n    dimap :: (c -> a) -> (b -> d) -> p a b -> p c d"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet02.hs",
    "content": "dimap f id pbb :: p a b\n"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet03.hs",
    "content": "dimap id f paa :: p a b\n"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet04.hs",
    "content": "dimap id f . alpha = dimap f id . alpha"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet05.hs",
    "content": "forall a. p a a"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet06.hs",
    "content": "dimap f id . pi = dimap id f . pi"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet07.hs",
    "content": "Profunctor p => (forall c. p c c) -> p a b"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet08.hs",
    "content": "pi :: Profunctor p => forall c. (forall a. p a a) -> p c c\npi e = e"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet09.hs",
    "content": "lambda :: Profunctor p => p a a -> (a -> b) -> p a b\nlambda paa f = dimap id f paa\n\nrho :: Profunctor p => p b b -> (a -> b) -> p a b\nrho pbb f = dimap f id pbb"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet10.hs",
    "content": "type ProdP p = forall a b. (a -> b) -> p a b"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet11.hs",
    "content": "newtype DiaProd p = DiaProd (forall a. p a a)"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet12.hs",
    "content": "lambdaP :: Profunctor p => DiaProd p -> ProdP p\nlambdaP (DiaProd paa) = lambda paa\n\nrhoP :: Profunctor p => DiaProd p -> ProdP p\nrhoP (DiaProd pbb) = rho pbb"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet13.hs",
    "content": "forall a. f a -> g a"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet14.hs",
    "content": "data Coend p = forall a. Coend (p a a)"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet15.hs",
    "content": "data SumP p = forall a b. SumP (b -> a) (p a b)"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet16.hs",
    "content": "lambda, rho :: Profunctor p => SumP p -> DiagSum p\nlambda (SumP f pab) = DiagSum (dimap f id pab)\nrho    (SumP f pab) = DiagSum (dimap id f pab)"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet17.hs",
    "content": "data DiagSum p = forall a. DiagSum (p a a)"
  },
  {
    "path": "src/content/3.10/code/haskell/snippet18.hs",
    "content": "data Procompose q p a b where\n    Procompose :: q a c -> p c b -> Procompose q p a b"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet01.ml",
    "content": "module type Functor = sig\n  type 'a t\n\n  val fmap : ('a -> 'b) -> 'a t -> 'b t\nend\n\nmodule type Profunctor = sig\n  type ('a, 'b) p\n\n  val dimap : ('c -> 'a) -> ('b -> 'd) -> ('a, 'b) p -> ('c, 'd) p\nend\n\nlet id a = a\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet02.ml",
    "content": "let dimap f id (P (b, b)) : ('a, 'b) p\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet03.ml",
    "content": "let dimap id f (P (a, a)) : ('a, 'b) p\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet04.ml",
    "content": "(* There is no compose operator in OCaml *)\n\n;;\ncompose (dimap id f) alpha = compose (dimap f id) alpha\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet05.ml",
    "content": "'a. ('a, 'a) p\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet06.ml",
    "content": ";;\ncompose (dimap f id) pi = compose (dimap id f) pi\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet07.ml",
    "content": "module type Polymorphic_Projection = functor (P : Profunctor) -> sig\n  type rank2_p = { p : 'c. ('c, 'c) P.p }\n\n  val pi : rank2_p -> ('a, 'b) P.p\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet08.ml",
    "content": "module Pi (P : Profunctor) = struct\n  type rank2_p = { p : 'a. ('a, 'a) P.p }\n\n  let pi : rank2_p -> ('c, 'c) P.p = fun e -> e.p\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet09.ml",
    "content": "module EndsEqualizer (P : Profunctor) = struct\n  let lambda : ('a, 'a) P.p -> ('a -> 'b) -> ('a, 'b) P.p =\n   fun paa f -> P.dimap id f paa\n ;;\n\n  let rho : ('b, 'b) P.p -> ('a -> 'b) -> ('a, 'b) P.p =\n   fun pbb f -> P.dimap f id pbb\n ;;\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet10.ml",
    "content": "module type ProdP = sig\n  type ('a, 'b) p\n  type ('a, 'b) prod_p = ('a -> 'b) -> ('a, 'b) p\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet11.ml",
    "content": "module type DiaProd = sig\n  type ('a, 'b) p\n  type 'a diaprod = DiaProd of ('a, 'a) p\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet12.ml",
    "content": "module EndsWithDiaProd\n    (P : Profunctor)\n    (D : DiaProd with type ('a, 'b) p = ('a, 'b) P.p)\n    (PP : ProdP with type ('a, 'b) p = ('a, 'b) P.p) =\nstruct\n  module E = EndsEqualizer (P)\n\n  let lambdaP : 'a D.diaprod -> ('a, 'b) PP.prod_p =\n   fun (DiaProd paa) -> E.lambda paa\n ;;\n\n  let rhoP : 'b D.diaprod -> ('a, 'b) PP.prod_p =\n   fun (DiaProd pbb) -> E.rho pbb\n ;;\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet13.ml",
    "content": "(* Higher rank types can be introduced via records *)\nmodule NT_as_Ends (F : Functor) (G : Functor) = struct\n  type set_of_nt = { nt : 'a. 'a F.t -> 'a G.t }\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet14.ml",
    "content": "module Coend (P : Profunctor) = struct\n  type coend = Coend of { c : 'a. ('a, 'a) P.p }\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet15.ml",
    "content": "module type SumP = sig\n  type a\n  type b\n  type ('a, 'b) p\n\n  val f : b -> a\n  val pab : (a, b) p\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet16.ml",
    "content": "module type DiagSum = sig\n  type a\n  type ('a, 'b) p\n\n  val paa : (a, a) p\nend\n\nmodule CoEndImpl (P : Profunctor) = struct\n  type a\n  type b\n\n  module type Sum_P =\n    SumP\n      with type ('a, 'b) p = ('a, 'b) P.p\n       and type a = a\n       and type b = b\n\n  let lambda (module S : Sum_P) =\n    (module struct\n      type a = S.b\n      type ('a, 'b) p = ('a, 'b) P.p\n\n      let paa = P.dimap S.f id S.pab\n    end : DiagSum)\n  ;;\n\n  let rho (module S : Sum_P) =\n    (module struct\n      type a = S.a\n      type ('a, 'b) p = ('a, 'b) P.p\n\n      let paa = P.dimap id S.f S.pab\n    end : DiagSum)\n  ;;\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet17.ml",
    "content": "module type DiagSum = sig\n  type a\n  type ('a, 'b) p\n\n  val paa : (a, a) p\nend\n"
  },
  {
    "path": "src/content/3.10/code/ocaml/snippet18.ml",
    "content": "module type Procompose = sig\n  type ('a, 'b) p\n  type ('a, 'b) q\n\n  type (_, _) procompose =\n    | Procompose : (('a, 'c) q -> ('c, 'b) p) -> ('a, 'b) procompose\nend\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet01.re",
    "content": "module type Functor = {\n  type t('a);\n\n  let fmap: ('a => 'b, t('a)) => t('b);\n};\n\nmodule type Profunctor = {\n  type p('a, 'b);\n\n  let dimap: ('c => 'a, 'b => 'd, p('a, 'b)) => p('c, 'd);\n};\n\nlet id = a => a;\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet02.re",
    "content": "let dimap(f, id, (P (b, b))) : p('a, 'b);"
  },
  {
    "path": "src/content/3.10/code/reason/snippet03.re",
    "content": "let dimap(id, f, (P (a, a))) : p('a, 'b);"
  },
  {
    "path": "src/content/3.10/code/reason/snippet04.re",
    "content": "/* There is no compose operator in ReasonML */\ncompose(dimap(id, f), alpha) == compose(dimap(f, id), alpha);\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet05.re",
    "content": "'a. p('a, 'a);"
  },
  {
    "path": "src/content/3.10/code/reason/snippet06.re",
    "content": "compose(dimap(f, id), pi) == compose(dimap(id, f), pi);\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet07.re",
    "content": "module type Polymorphic_Projection = (P: Profunctor) => {\n  type rank2_p = {p: 'c. P.p('c, 'c)};\n\n  let pi: rank2_p => P.p('a, 'b);\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet08.re",
    "content": "module Pi = (P: Profunctor) => {\n  type rank2_p = {p: 'a. P.p('a, 'a)};\n\n  let pi: rank2_p => P.p('c, 'c) = (e => e.p: rank2_p => P.p('c, 'c));\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet09.re",
    "content": "module EndsEqualizer = (P: Profunctor) => {\n  let lambda: (P.p('a, 'a), 'a => 'b) => P.p('a, 'b) = (\n    (paa, f) => P.dimap(id, f, paa)\n  );\n\n  let rho: (P.p('b, 'b), 'a => 'b) => P.p('a, 'b) = (\n    (pbb, f) => P.dimap(f, id, pbb)\n  );\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet10.re",
    "content": "module type ProdP = {\n  type p('a, 'b);\n  type prod_p('a, 'b) = ('a => 'b) => p('a, 'b);\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet11.re",
    "content": "module type DiaProd = {\n  type p('a, 'b);\n  type diaprod('a) =\n    | DiaProd(p('a, 'a));\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet12.re",
    "content": "module EndsWithDiaProd = (\n    P: Profunctor,\n    D: DiaProd with type p('a, 'b) = P.p('a, 'b),\n    PP: ProdP with type p('a, 'b) = P.p('a, 'b),\n  ) => {\n  module E = EndsEqualizer(P);\n\n  let lambdaP: D.diaprod('a) => PP.prod_p('a, 'b) = (\n    (DiaProd(paa)) => E.lambda(paa)\n  );\n\n  let rhoP: D.diaprod('b) => PP.prod_p('a, 'b) = (\n    (DiaProd(pbb)) => E.rho(pbb)\n  );\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet13.re",
    "content": "/* Higher rank types can be introduced via records */\nmodule NT_as_Ends = (F: Functor, G: Functor) => {\n  type set_of_nt = {nt: 'a. F.t('a) => G.t('a)};\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet14.re",
    "content": "module Coend = (P: Profunctor) => {\n  type coend =\n    | Coend({c: 'a. P.p('a, 'a)});\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet15.re",
    "content": "module type SumP = {\n  type a;\n  type b;\n  type p('a, 'b);\n\n  let f: b => a;\n  let pab: p(a, b);\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet16.re",
    "content": "module type DiagSum = {\n  type a;\n  type p('a, 'b);\n\n  let paa: p(a, a);\n};\n\nmodule CoEndImpl = (P: Profunctor) => {\n  type a;\n  type b;\n\n  module type Sum_P =\n    SumP with type p('a, 'b) = P.p('a, 'b)\n      and type a = a and type b = b;\n\n  let lambda = (module S: Sum_P): (module DiagSum) =>\n    (module {\n       type a = S.b;\n       type p('a, 'b) = P.p('a, 'b);\n\n       let paa = P.dimap(S.f, id, S.pab);\n     });\n\n  let rho = (module S: Sum_P): (module DiagSum) =>\n    (module {\n       type a = S.a;\n       type p('a, 'b) = P.p('a, 'b);\n\n       let paa = P.dimap(id, S.f, S.pab);\n     });\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet17.re",
    "content": "module type DiagSum = {\n  type a;\n  type p('a, 'b);\n\n  let paa: p(a, a);\n};\n"
  },
  {
    "path": "src/content/3.10/code/reason/snippet18.re",
    "content": "module type Procompose = {\n  type p('a, 'b);\n  type q('a, 'b);\n\n  type procompose(_, _) =\n    | Procompose(q('a, 'c) => p('c, 'b)): procompose('a, 'b);\n};\n"
  },
  {
    "path": "src/content/3.10/code/scala/snippet01.scala",
    "content": "trait Profunctor[P[_, _]] {\n  def dimap[A, B, C, D]\n      (f: C => A)(g: B => D)(pab: P[A, B]): P[C, D]\n}"
  },
  {
    "path": "src/content/3.10/code/scala/snippet02.scala",
    "content": "dimap(f)(identity[B])(pbb): P[A, B]"
  },
  {
    "path": "src/content/3.10/code/scala/snippet03.scala",
    "content": "dimap(identity[A])(f)(paa): P[A, B]"
  },
  {
    "path": "src/content/3.10/code/scala/snippet04.scala",
    "content": "(dimap(identity[A])(f) _ compose alpha) ==\n  (dimap(f)(identity[B] _ compose alpha)"
  },
  {
    "path": "src/content/3.10/code/scala/snippet05.scala",
    "content": "// no Rank-N types in Scala\n// have to introduce a polymorphic function\ntrait PolyFunction1[P[_, _]] {\n  def apply[A](): P[A, A]\n}"
  },
  {
    "path": "src/content/3.10/code/scala/snippet06.scala",
    "content": "(dimap(f)(identity[B]) _ compose pi.apply) ==\n  (dimap(identity[A])(f) _ compose pi.apply)"
  },
  {
    "path": "src/content/3.10/code/scala/snippet07.scala",
    "content": "def side[P[_, _]: Profunctor]: PolyFunction1[P] => P[A, B]"
  },
  {
    "path": "src/content/3.10/code/scala/snippet08.scala",
    "content": "// no Rank-N types in Scala\n// need a higher rank polymorphic function\ntrait PolyFunction2[P[_, _]] {\n  def apply[C](in: PolyFunction1[P]): P[C, C]\n}\n\ndef pi[P[_, _]](implicit P: Profunctor[P]): PolyFunction2[P] =\n  new PolyFunction2[P] {\n    def apply[C](in: PolyFunction1[P]): P[C, C] =\n      in()\n  }"
  },
  {
    "path": "src/content/3.10/code/scala/snippet09.scala",
    "content": "def lambda[A, B, P[_, _]](P: Profunctor[P]): P[A, A] => (A => B) => P[A, B] =\n  paa => f => P.dimap(identity[A])(f)(paa)\n\ndef rho[A, B, P[_, _]](P: Profunctor[P]): P[B, B] => (A => B) => P[A, B] =\n  pbb => f => P.dimap(f)(identity[B])(pbb)"
  },
  {
    "path": "src/content/3.10/code/scala/snippet10.scala",
    "content": "trait ProdP[P[_, _]] {\n  def apply[A, B](f: A => B): P[A, B]\n}"
  },
  {
    "path": "src/content/3.10/code/scala/snippet11.scala",
    "content": "case class DiaProd[P[_, _]](paa: PolyFunction1[P])"
  },
  {
    "path": "src/content/3.10/code/scala/snippet12.scala",
    "content": "def lambdaP[P[_, _]](P: Profunctor[P]): DiaProd[P] => ProdP[P] = {\n  case DiaProd(paa) =>\n    new ProdP[P] {\n      def apply[A, B](f: A => B): P[A, B] =\n        lambda(P)(paa[A])(f)\n    }\n}\n\ndef rhoP[P[_, _]](P: Profunctor[P]): DiaProd[P] => ProdP[P] = {\n  case DiaProd(paa) =>\n    new ProdP[P] {\n      def apply[A, B](f: A => B): P[A, B] =\n        rho(P)(paa[B])(f)\n    }\n}"
  },
  {
    "path": "src/content/3.10/code/scala/snippet13.scala",
    "content": "// Yet another type needs to be introduced.\n// To read more about FunctionK (~>):\n// typelevel.org/cats/datatypes/functionk.html\ntrait ~>[F[_], G[_]] {\n  def apply[B](fa: F[B]): G[B]\n}\n\nF ~> G"
  },
  {
    "path": "src/content/3.10/code/scala/snippet14.scala",
    "content": "trait Coend[P[_, _]] {\n  def paa[A]: P[A, A]\n}"
  },
  {
    "path": "src/content/3.10/code/scala/snippet15.scala",
    "content": "trait SumP[P[_, _]] {\n  def f[A, B]: B => A\n  def pab[A, B]: P[A, B]\n}"
  },
  {
    "path": "src/content/3.10/code/scala/snippet16.scala",
    "content": "def lambda[P[- _, _]](P: Profunctor[P]): SumP[P] => DiagSum[P] =\n  sump => new DiagSum[P] {\n    def paa[A]: P[A, A] =\n      P.dimap(sump.f)(identity[A])(sump.pab)\n  }\n\ndef rho[P[_, _]](P: Profunctor[P]): SumP[P] => DiagSum[P] =\n  sump => new DiagSum[P] {\n    def paa[A]: P[A, A] =\n      P.dimap(identity[A])(sump.f)(sump.pab)\n  }"
  },
  {
    "path": "src/content/3.10/code/scala/snippet17.scala",
    "content": "trait DiagSum[P[_, _]]{\n  def paa[A]: P[A, A]\n}"
  },
  {
    "path": "src/content/3.10/code/scala/snippet18.scala",
    "content": "trait Procompose[Q[_, _], P[_, _], A, B]\n\nobject Procompose{\n  def apply[Q[_, _], P[_, _], A, B, C]\n      (qac: Q[A, C])(pcb: P[C, B]): Procompose[Q, P, A, B] = ???\n}"
  },
  {
    "path": "src/content/3.10/ends-and-coends.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{T}{here are many intuitions} that we may attach to morphisms in a category,\nbut we can all agree that if there is a morphism from the object\n$a$ to the object $b$ then the two objects are in some way\n``related.'' A morphism is, in a sense, the proof of this relation. This\nis clearly visible in any poset category, where a morphism \\emph{is} a\nrelation. In general, there may be many ``proofs'' of the same relation\nbetween two objects. These proofs form a set that we call the hom-set.\nWhen we vary the objects, we get a mapping from pairs of objects to sets\nof ``proofs.'' This mapping is functorial --- contravariant in the first\nargument and covariant in the second. We can look at it as establishing\na global relationship between objects in the category. This relationship\nis described by the hom-functor:\n\\[\\cat{C}(-, =) \\Colon \\cat{C}^\\mathit{op}\\times{}\\cat{C} \\to \\Set\\]\nIn general, any functor like this may be interpreted as establishing a\nrelation between objects in a category. A relation may also involve two\ndifferent categories $\\cat{C}$ and $\\cat{D}$. A functor, which describes\nsuch a relation, has the following signature and is called a profunctor:\n\\[p \\Colon \\cat{D}^\\mathit{op}\\times{}\\cat{C} \\to \\Set\\]\nMathematicians say that it's a profunctor from $\\cat{C}$ to $\\cat{D}$\n(notice the inversion), and use a slashed arrow as a symbol for it:\n\\[\\cat{C} \\nrightarrow \\cat{D}\\]\nYou may think of a profunctor as a \\newterm{proof-relevant relation}\nbetween objects of $\\cat{C}$ and objects of $\\cat{D}$, where the elements\nof the set symbolize proofs of the relation. Whenever $p\\ a\\ b$\nis empty, there is no relation between $a$ and $b$. Keep\nin mind that relations don't have to be symmetric.\n\nAnother useful intuition is the generalization of the idea that an\nendofunctor is a container. A profunctor value of the type\n$p\\ a\\ b$ could then be considered a container of $b$s\nthat are keyed by elements of type $a$. In particular, an element\nof the hom-profunctor is a function from $a$ to $b$.\n\nIn Haskell, a profunctor is defined as a two-argument type constructor\n\\code{p} equipped with the method called \\code{dimap}, which lifts a\npair of functions, the first going in the ``wrong'' direction:\n\n\\src{snippet01}\nThe functoriality of the profunctor tells us that if we have a proof\nthat \\code{a} is related to \\code{b}, then we get the proof that\n\\code{c} is related to \\code{d}, as long as there is a morphism from\n\\code{c} to \\code{a} and another from \\code{b} to \\code{d}. Or,\nwe can think of the first function as translating new keys to the old\nkeys, and the second function as modifying the contents of the\ncontainer.\n\nFor profunctors acting within one category, we can extract quite a lot\nof information from diagonal elements of the type $p\\ a\\ a$. We\ncan prove that $b$ is related to $c$ as long as we have a\npair of morphisms $b \\to a$ and\n$a \\to c$. Even better, we can use a single morphism to\nreach off-diagonal values. For instance, if we have a morphism\n$f \\Colon a \\to b$, we can lift the pair\n$\\langle f, \\idarrow[b] \\rangle$ to go from $p\\ b\\ b$ to\n$p\\ a\\ b$:\n\n\\src{snippet02}\nOr we can lift the pair $\\langle \\idarrow[a], f \\rangle$ to go\nfrom $p\\ a\\ a$ to $p\\ a\\ b$:\n\n\\src{snippet03}\n\n\\section{Dinatural Transformations}\n\nSince profunctors are functors, we can define natural transformations\nbetween them in the standard way. In many cases, though, it's enough to\ndefine the mapping between diagonal elements of two profunctors. Such a\ntransformation is called a dinatural transformation, provided it\nsatisfies the commuting conditions that reflect the two ways we can\nconnect diagonal elements to non-diagonal ones. A dinatural\ntransformation between two profunctors $p$ and $q$, which\nare members of the functor category ${[}\\cat{C}^\\mathit{op}\\times{}\\cat{C}, \\Set{]}$, is a\nfamily of morphisms:\n\\[\\alpha_a \\Colon p\\ a\\ a \\to q\\ a\\ a\\]\nfor which the following diagram commutes, for any $f \\Colon a \\to b$:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/end.jpg}\n\\end{figure}\n\n\\noindent\nNotice that this is strictly weaker than the naturality condition. If\n$\\alpha$ were a natural transformation in\n${[}\\cat{C}^\\mathit{op}\\times{}\\cat{C}, \\Set{]}$, the above diagram could be constructed\nfrom two naturality squares and one functoriality condition (profunctor\n$q$ preserving composition):\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/end-1.jpg}\n\\end{figure}\n\n\\noindent\nNotice that a component of a natural transformation $\\alpha$ in\n${[}\\cat{C}^\\mathit{op}\\times{}\\cat{C}, \\Set{]}$ is indexed by a pair of objects\n$\\alpha_{a b}$. A dinatural transformation, on the other hand, is\nindexed by one object, since it only maps diagonal elements of the\nrespective profunctors.\n\n\\section{Ends}\n\nWe are now ready to advance from ``algebra'' to what could be considered\nthe ``calculus'' of category theory. The calculus of ends (and coends)\nborrows ideas and even some notation from traditional calculus. In\nparticular, the coend may be understood as an infinite sum or an\nintegral, whereas the end is similar to an infinite product. There is\neven something that resembles the Dirac delta function.\n\nAn end is a generalization of a limit, with the functor replaced by a\nprofunctor. Instead of a cone, we have a wedge. The base of a wedge is\nformed by diagonal elements of a profunctor $p$. The apex of the\nwedge is an object (here, a set, since we are considering\n$\\Set$-valued profunctors), and the sides are a family of\nfunctions mapping the apex to the sets in the base. You may think of\nthis family as one polymorphic function --- a function that's\npolymorphic in its return type:\n\\[\\alpha \\Colon \\forall a\\ .\\ \\mathit{apex} \\to p\\ a\\ a\\]\nUnlike in cones, within a wedge we don't have any functions that would\nconnect vertices of the base. However, as we've seen earlier, given any\nmorphism $f \\Colon a \\to b$ in $\\cat{C}$, we can connect both\n$p\\ a\\ a$ and $p\\ b\\ b$ to the common set\n$p\\ a\\ b$. We therefore insist that the following diagram\ncommute:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/end-2.jpg}\n\\end{figure}\n\n\\noindent\nThis is called the \\newterm{wedge condition}. It can be written as:\n\\[p\\ \\idarrow[a]\\ f \\circ \\alpha_a = p\\ f\\ \\idarrow[b] \\circ \\alpha_b\\]\nOr, using Haskell notation:\n\n\\src{snippet04}\nWe can now proceed with the universal construction and define the end of\n$p$ as the universal wedge --- a set $e$ together with a\nfamily of functions $\\pi$ such that for any other wedge with the\napex $e'$ and a family $\\alpha$ there is a unique function\n$h \\Colon e' \\to e$ that makes all triangles commute:\n\\[\\pi_a \\circ h = \\alpha_a\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/end-21.jpg}\n\\end{figure}\n\n\\noindent\nThe symbol for the end is the integral sign, with the ``integration\nvariable'' in the subscript position:\n\\[\\int_c p\\ c\\ c\\]\nComponents of $\\pi$ are called projection maps for the end:\n\\[\\pi_a \\Colon \\int_c p\\ c\\ c \\to p\\ a\\ a\\]\nNote that if $\\cat{C}$ is a discrete category (no morphisms other than\nthe identities) the end is just a global product of all diagonal entries\nof $p$ across the whole category $\\cat{C}$. Later I'll show you\nthat, in the more general case, there is a relationship between the end\nand this product through an equalizer.\n\nIn Haskell, the end formula translates directly to the universal\nquantifier:\n\n\\src{snippet05}\nStrictly speaking, this is just a product of all diagonal elements of\n$p$, but the wedge condition is satisfied automatically due to\n\\urlref{https://bartoszmilewski.com/2017/04/11/profunctor-parametricity/}{parametricity}. For any function\n$f \\Colon a \\to b$, the wedge condition reads:\n\n\\src{snippet06}\nor, with type annotations:\n\n\\begin{snipv}\ndimap f id\\textsubscript{b} . pi\\textsubscript{b} = dimap id\\textsubscript{a} f . pi\\textsubscript{a}\n\\end{snipv}\nwhere both sides of the equation have the type:\n\n\\src{snippet07}\nand \\code{pi} is the polymorphic projection:\n\n\\src{snippet08}\nHere, type inference automatically picks the right component of\n\\code{e}.\n\nJust as we were able to express the whole set of commutation conditions\nfor a cone as one natural transformation, likewise we can group all the\nwedge conditions into one dinatural transformation. For that we need the\ngeneralization of the constant functor $\\Delta_c$ to a constant\nprofunctor that maps all pairs of objects to a single object $c$,\nand all pairs of morphisms to the identity morphism for this object. A\nwedge is a dinatural transformation from that functor to the profunctor\n$p$. Indeed, the dinaturality hexagon shrinks down to the wedge\ndiamond when we realize that $\\Delta_c$ lifts all morphisms to one\nidentity function.\n\nEnds can also be defined for target categories other than $\\Set$,\nbut here we'll only consider $\\Set$-valued profunctors and their\nends.\n\n\\section{Ends as Equalizers}\n\nThe commutation condition in the definition of the end can be written\nusing an equalizer. First, let's define two functions (I'm using Haskell\nnotation, because mathematical notation seems to be less user-friendly\nin this case). These functions correspond to the two converging branches\nof the wedge condition:\n\n\\src{snippet09}[b]\nBoth functions map diagonal elements of the profunctor \\code{p} to\npolymorphic functions of the type:\n\n\\src{snippet10}\nThese functions have different types. However, we can unify their types,\nif we form one big product type, gathering together all diagonal\nelements of \\code{p}:\n\n\\src{snippet11}\nThe functions \\code{lambda} and \\code{rho} induce two mappings from\nthis product type:\n\n\\src{snippet12}\nThe end of \\code{p} is the equalizer of these two functions. Remember\nthat the equalizer picks the largest subset on which two functions are\nequal. In this case it picks the subset of the product of all diagonal\nelements for which the wedge diagrams commute.\n\n\\section{Natural Transformations as Ends}\n\nThe most important example of an end is the set of natural\ntransformations. A natural transformation between two functors\n$F$ and $G$ is a family of morphisms picked from hom-sets\nof the form $\\cat{C}(F a, G a)$. If it weren't for the naturality\ncondition, the set of natural transformations would be just the product\nof all these hom-sets. In fact, in Haskell, it is:\n\n\\src{snippet13}\nThe reason it works in Haskell is because naturality follows from\nparametricity. Outside of Haskell, though, not all diagonal sections\nacross such hom-sets will yield natural transformations. But notice that\nthe mapping:\n\\[\\langle a, b \\rangle \\to \\cat{C}(F a, G b)\\]\nis a profunctor, so it makes sense to study its end. This is the wedge\ncondition:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/end1.jpg}\n\\end{figure}\n\n\\noindent\nLet's just pick one element from the set $\\int_c \\cat{C}(F c, G c)$.\nThe two projections will map this element to two components of a\nparticular transformation, let's call them:\n\\begin{align*}\n  \\tau_a & \\Colon F a \\to G a \\\\\n  \\tau_b & \\Colon F b \\to G b\n\\end{align*}\nIn the left branch, we lift a pair of morphisms\n$\\langle \\idarrow[a], G f \\rangle$ using the hom-functor. You\nmay recall that such lifting is implemented as simultaneous pre- and\npost-composition. When acting on $\\tau_a$ the lifted pair gives us:\n\\[G f \\circ \\tau_a \\circ \\idarrow[a]\\]\nThe other branch of the diagram gives us:\n\\[\\idarrow[b] \\circ \\tau_b \\circ F f\\]\nTheir equality, demanded by the wedge condition, is nothing but the\nnaturality condition for $\\tau$.\n\n\\section{Coends}\nAs expected, the dual to an end is called a coend. It is constructed\nfrom a dual to a wedge called a cowedge (pronounced co-wedge, not\ncow-edge).\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.25\\textwidth]{images/end-31.jpg}\n  \\caption{An edgy cow?}\n\\end{figure}\n\n\\noindent\nThe symbol for a coend is the integral sign with the ``integration\nvariable'' in the superscript position:\n\\[\\int^c p\\ c\\ c\\]\nJust like the end is related to a product, the coend is related to a\ncoproduct, or a sum (in this respect, it resembles an integral, which is\na limit of a sum). Rather than having projections, we have injections\ngoing from the diagonal elements of the profunctor down to the coend. If\nit weren't for the cowedge conditions, we could say that the coend of\nthe profunctor $p$ is either $p\\ a\\ a$, or\n$p\\ b\\ b$, or $p\\ c\\ c$, and so on. Or we could say that\nthere exists such an $a$ for which the coend is just the set\n$p\\ a\\ a$. The universal quantifier that we used in the\ndefinition of the end turns into an existential quantifier for the\ncoend.\n\nThis is why, in pseudo-Haskell, we would define the coend as:\n\n\\begin{snip}{text}\nexists a. p a a\n\\end{snip}\nThe standard way of encoding existential quantifiers in Haskell is to\nuse universally quantified data constructors. We can thus define:\n\n\\src{snippet14}\nThe logic behind this is that it should be possible to construct a coend\nusing a value of any of the family of types $p\\ a\\ a$, no matter\nwhat $a$ we chose.\n\nJust like an end can be defined using an equalizer, a coend can be\ndescribed using a \\newterm{coequalizer}. All the cowedge conditions can be\nsummarized by taking one gigantic coproduct of $p\\ a\\ b$ for all\npossible functions $b \\to a$. In Haskell, that would be\nexpressed as an existential type:\n\n\\src{snippet15}\nThere are two ways of evaluating this sum type, by lifting the function\nusing \\code{dimap} and applying it to the profunctor $p$:\n\n\\src{snippet16}\nwhere \\code{DiagSum} is the sum of diagonal elements of $p$:\n\n\\src{snippet17}\nThe coequalizer of these two functions is the coend. A coequalizer is\nobtained from \\code{DiagSum p} by identifying values that are\nobtained by applying \\code{lambda} or \\code{rho} to the same\nargument. Here, the argument is a pair consisting of a function\n$b \\to a$ and an element of $p\\ a\\ b$. The\napplication of \\code{lambda} and \\code{rho} produces two potentially\ndifferent values of the type \\code{DiagSum p}. In the coend, these\ntwo values are identified, making the cowedge condition automatically\nsatisfied.\n\nThe process of identification of related elements in a set is formally\nknown as taking a quotient. To define a quotient we need an\n\\newterm{equivalence relation} $\\sim$, a relation that\nis reflexive, symmetric, and transitive:\n\\begin{align*}\n   & a \\sim a                                                         \\\\\n   & \\text{if}\\ a \\sim b\\ \\text{then}\\ b \\sim a                       \\\\\n   & \\text{if}\\ a \\sim b\\ \\text{and}\\ b \\sim c\\ \\text{then}\\ a \\sim c\n\\end{align*}\nSuch a relation splits the set into equivalence classes. Each class\nconsists of elements that are related to each other. We form a quotient\nset by picking one representative from each class. A classic example is\nthe definition of rational numbers as pairs of whole numbers, second of\nwhich is non-zero, with the following equivalence relation:\n\\[(a, b) \\sim (c, d)\\ \\text{iff}\\ a * d = b * c\\]\nIt's easy to check that this is an equivalence relation. A pair\n$(a, b)$ is interpreted as a fraction $\\frac{a}{b}$, and\nfractions whose numerator and denominator have a common divisor are identified. A rational number\nis an equivalence class of such fractions.\n\nYou might recall from our earlier discussion of limits and colimits that\nthe hom-functor is continuous, that is, it preserves limits. Dually, the\ncontravariant hom-functor turns colimits into limits. These properties\ncan be generalized to ends and coends, which are a generalization of\nlimits and colimits, respectively. In particular, we get a very useful\nidentity for converting coends to ends:\n\\[\\Set(\\int^x p\\ x\\ x, c) \\cong \\int_x \\Set(p\\ x\\ x, c)\\]\nLet's have a look at it in pseudo-Haskell:\n\n\\begin{snipv}\n(exists x. p x x) -> c \\ensuremath{\\cong} forall x. p x x -> c\n\\end{snipv}\nIt tells us that a function that takes an existential type is equivalent\nto a polymorphic function. This makes perfect sense, because such a\nfunction must be prepared to handle any one of the types that may be\nencoded in the existential type. It's the same principle that tells us\nthat a function that accepts a sum type must be implemented as a case\nclause, with a tuple of handlers, one for every type present in the\nsum. Here, the sum type is replaced by a coend, and a family of handlers\nbecomes an end, or a polymorphic function.\n\n\\section{Ninja Yoneda Lemma}\n\nThe set of natural transformations that appears in the Yoneda lemma may\nbe encoded using an end, resulting in the following formulation:\n\\[\\int_z \\Set(\\cat{C}(a, z), F z) \\cong F a\\]\nThere is also a dual formula:\n\\[\\int^z \\cat{C}(z, a)\\times{}F z \\cong F a\\]\nThis identity is strongly reminiscent of the formula for the Dirac delta\nfunction (a function $\\delta(a - z)$, or rather a distribution, that\nhas an infinite peak at $a = z$). Here, the hom-functor plays\nthe role of the delta function.\n\nTogether these two identities are sometimes called the Ninja Yoneda\nlemma.\n\nTo prove the second formula, we will use the consequence of the Yoneda\nembedding, which states that two objects are isomorphic if and only if\ntheir hom-functors are isomorphic. In other words $a \\cong b$ if\nand only if there is a natural transformation of the type:\n\\[[\\cat{C}, \\Set](\\cat{C}(a, -), \\cat{C}(b, =))\\]\nthat is an isomorphism.\n\nWe start by inserting the left-hand side of the identity we want to\nprove inside a hom-functor that's going to some arbitrary object\n$c$:\n\\[\\Set(\\int^z \\cat{C}(z, a)\\times{}F z, c)\\]\nUsing the continuity argument, we can replace the coend with the end:\n\\[\\int_z \\Set(\\cat{C}(z, a)\\times{}F z, c)\\]\nWe can now take advantage of the adjunction between the product and the\nexponential:\n\\[\\int_z \\Set(\\cat{C}(z, a), c^{(F z)})\\]\nWe can ``perform the integration'' by using the Yoneda lemma to get:\n\\[c^{(F a)}\\]\n(Notice that we used the contravariant version of the Yoneda lemma,\nsince the functor $c^{(F z)}$ is contravariant in $z$.)\nThis exponential object is isomorphic to the hom-set:\n\\[\\Set(F a, c)\\]\nFinally, we take advantage of the Yoneda embedding to arrive at the\nisomorphism:\n\\[\\int^z \\cat{C}(z, a)\\times{}F z \\cong F a\\]\n\n\\section{Profunctor Composition}\n\nLet's explore further the idea that a profunctor describes a relation\n--- more precisely, a proof-relevant relation, meaning that the set\n$p\\ a\\ b$ represents the set of proofs that $a$ is related\nto $b$. If we have two relations $p$ and $q$ we can\ntry to compose them. We'll say that $a$ is related to $b$\nthrough the composition of $q$ after $p$ if there exist an\nintermediary object $c$ such that both $q\\ b\\ c$ and\n$p\\ c\\ a$ are non-empty. The proofs of this new relation are all\npairs of proofs of individual relations. Therefore, with the\nunderstanding that the existential quantifier corresponds to a coend,\nand the Cartesian product of two sets corresponds to ``pairs of\nproofs,'' we can define composition of profunctors using the following\nformula:\n\\[(q \\circ p)\\ a\\ b = \\int^c p\\ c\\ a\\times{}q\\ b\\ c\\]\nHere's the equivalent Haskell definition from\n\\code{Data.Profunctor.Composition}, after some renaming:\n\n\\src{snippet18}\nThis is using generalized algebraic data type, or \\acronym{GADT} syntax, in which\na free type variable (here \\code{c}) is automatically existentially\nquantified. The (uncurried) data constructor \\code{Procompose} is\nthus equivalent to:\n\n\\begin{snip}{text}\nexists c. (q a c, p c b)\n\\end{snip}\nThe unit of so defined composition is the hom-functor --- this\nimmediately follows from the Ninja Yoneda lemma. It makes sense,\ntherefore, to ask the question if there is a category in which\nprofunctors serve as morphisms. The answer is positive, with the caveat\nthat both associativity and identity laws for profunctor composition\nhold only up to natural isomorphism. Such a category, where laws are\nvalid up to isomorphism, is called a bicategory (which is more general\nthan a $\\cat{2}$-category). So we have a bicategory $\\cat{Prof}$, in which\nobjects are categories, morphisms are profunctors, and morphisms between\nmorphisms (a.k.a., two-cells) are natural transformations. In fact, one\ncan go even further, because beside profunctors, we also have regular\nfunctors as morphisms between categories. A category which has two types\nof morphisms is called a double category.\n\nProfunctors play an important role in the Haskell lens library and in\nthe arrow library.\n"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet01.hs",
    "content": "newtype Ran k d a = Ran (forall i. (a -> k i) -> d i)"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet02.hs",
    "content": "f :: String -> Tree Int"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet03.hs",
    "content": "forall i. (a -> k i) -> i"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet04.hs",
    "content": "type Lst a = forall i. Monoid i => (a -> i) -> i"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet05.hs",
    "content": "toLst :: [a] -> Lst a\ntoLst as = \\f -> foldMap f as\n\nfromLst :: Lst a -> [a]\nfromLst f = f (\\a -> [a])"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet06.hs",
    "content": "data Lan k d a = forall i. Lan (k i -> a) (d i)"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet07.hs",
    "content": "type Exp a b = Lan ((,) a) Identity b\n"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet08.hs",
    "content": "toExp :: (a -> b) -> Exp a b\ntoExp f = Lan (f . fst) (Identity ())\n\nfromExp :: Exp a b -> (a -> b)\nfromExp (Lan f (Identity x)) = \\a -> f (a, x)\n"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet09.hs",
    "content": "data FreeF f a = forall i. FMap (i -> a) (f i)"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet10.hs",
    "content": "instance Functor (FreeF f) where\n    fmap g (FMap h fi) = FMap (g . h) fi"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet11.hs",
    "content": "newtype FreeF f a = FreeF (forall i. (a -> i) -> f i)"
  },
  {
    "path": "src/content/3.11/code/haskell/snippet12.hs",
    "content": "instance Functor (FreeF f) where\n    fmap g (FreeF r) = FreeF (\\bi -> r (bi . g))"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet01.ml",
    "content": "module type Ran = sig\n  type 'a k\n  type 'a d\n  type 'a ran = Ran of { r : 'i. ('a -> 'i k) -> 'i d }\nend\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet02.ml",
    "content": "val f : string -> int tree\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet03.ml",
    "content": "(* Higher rank polymorphic functions can be achieved using records *)\n{ r : 'i. (a -> 'i k) -> 'i }\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet04.ml",
    "content": "module type Lst = sig\n  type a\n  type m\n\n  module M : Monoid with type m = m\n\n  type lst = (a -> M.m) -> M.m\n\n  val f : lst\nend\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet05.ml",
    "content": "let fold_map (type i) (module M : Monoid with type m = i) xs f =\n  List.fold_left (fun acc a -> M.mappend acc (f a)) M.mempty xs\n;;\n\nlet to_lst (type x) (xs : x list) =\n  let module LM : Monoid with type m = x list =\n    ListMonoid (struct\n      type a = x\n    end)\n  in\n  (module struct\n    type a = x\n    type m = x list\n\n    module M = LM\n\n    type lst = (a -> LM.m) -> LM.m\n\n    let f g = fold_map (module LM) xs g\n  end : Lst\n    with type a = x)\n;;\n\nlet from_lst\n    (type x)\n    (module LstImpl : Lst with type a = x and type m = x list)\n  =\n  LstImpl.f (fun x -> [ x ])\n;;\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet06.ml",
    "content": "module type Lan = sig\n  type 'a k\n  type 'a d\n  type a\n  type i\n\n  val fk : i k -> a\n  val di : i d\nend\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet07.ml",
    "content": "module type Exp = sig\n  type a\n  type b\n  type 'a d = I of 'a\n  type 'a k = 'a * a\n\n  include\n    Lan with type 'a k := a * 'a and type 'a d := 'a d and type a := b\nend\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet08.ml",
    "content": "let to_exp (type a' b') f =\n  (module struct\n    type a = a'\n    type b = b'\n    type 'a d = I of 'a\n    type 'a k = 'a * a\n    type i = unit\n\n    let fk (a, _) = f a\n    let di = I ()\n  end : Exp\n    with type a = a'\n     and type b = b')\n;;\n\nlet from_exp\n    (type a' b')\n    (module E : Exp with type a = a' and type b = b')\n    a\n  =\n  let (I i) = E.di in\n  E.fk (a, i)\n;;\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet09.ml",
    "content": "module type FreeF = sig\n  type 'a f\n  type a\n  type i\n\n  val h : i -> a\n  val fi : i -> i f\nend\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet10.ml",
    "content": "module FreeFunctor (F : sig\n  type 'a f\nend) : Functor = struct\n  module type F = FreeF with type 'a f = 'a F.f\n\n  type 'a t = (module F with type a = 'a)\n\n  let fmap\n      (type a' b')\n      (f : a' -> b')\n      (module FF : F with type a = a')\n    =\n    (module struct\n      type 'a f = 'a F.f\n      type a = b'\n      type i = FF.i\n\n      let h i = f (FF.h i)\n      let fi = FF.fi\n    end : F\n      with type a = b')\n  ;;\nend\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet11.ml",
    "content": "module type FreeF_Alt = sig\n  type a\n  type 'a f\n\n  val freeF : (a -> 'i) -> 'i f\nend\n"
  },
  {
    "path": "src/content/3.11/code/ocaml/snippet12.ml",
    "content": "module FreeFunctorAlt (F : sig\n  type 'a f\nend) : Functor = struct\n  module type F = FreeF_Alt with type 'a f = 'a F.f\n\n  type 'a t = (module F with type a = 'a)\n\n  let fmap (type a' b') f (module FF : F with type a = a') =\n    (module struct\n      type a = b'\n      type 'a f = 'a F.f\n\n      let freeF bi = FF.freeF (fun a -> bi (f a))\n    end : F\n      with type a = b')\n  ;;\nend\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet01.re",
    "content": "module type Ran = {\n  type k('a);\n  type d('a);\n  type ran('a) =\n    | Ran({r: 'i. ('a => k('i)) => d('i)});\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet02.re",
    "content": "let f: string => tree(int);\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet03.re",
    "content": "/* Higher rank polymorphic functions can be achieved using records */\n{ r : 'i. (a => k('i)) => 'i }\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet04.re",
    "content": "module type Lst = {\n  type a;\n  type m;\n\n  module M: Monoid with type m = m;\n\n  type lst = (a => M.m) => M.m;\n\n  let f: lst;\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet05.re",
    "content": "let fold_map = (type i, module M: Monoid with type m = i, xs, f) =>\n  List.fold_left((acc, a) => M.mappend(acc, f(a)), M.mempty, xs);\n\nlet to_lst = (type x, xs: list(x)) => {\n  module LM: Monoid with type m = list(x) = \n    ListMonoid({type a = x;});\n\n  (module {\n      type a = x;\n      type m = list(x);\n\n      module M = LM;\n\n      type lst = (a => LM.m) => LM.m;\n\n      let f = g => fold_map((module LM), xs, g);\n  });\n};\n\nlet from_lst = (type x, \n    module LstImpl: Lst with type a = x and type m = list(x)\n  ) => LstImpl.f(x => [x]);\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet06.re",
    "content": "module type Lan = {\n  type k('a);\n  type d('a);\n  type a;\n  type i;\n\n  let fk: k(i) => a;\n  let di: d(i);\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet07.re",
    "content": "module type Exp = {\n  type a;\n  type b;\n  type d('a) =\n    | I('a);\n  type k('a) = ('a, a);\n\n  include\n    Lan with type k('a) := (a, 'a) \n      and type d('a) := d('a) \n      and type a := b;\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet08.re",
    "content": "let to_exp = (type a', type b', f) :\n  (module Exp with type a = a' and type b = b') =>\n  (module {\n     type a = a';\n     type b = b';\n     type d('a) =\n       | I('a);\n     type k('a) = ('a, a);\n     type i = unit;\n\n     let fk = ((a, _)) => f(a);\n     let di = I();\n  });\n\nlet from_exp = (type a', type b', \n    module E: Exp with type a = a' and type b = b', a) => {\n  let I(i) = E.di;\n  E.fk((a, i));\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet09.re",
    "content": "module type FreeF = {\n  type f('a);\n  type a;\n  type i;\n\n  let h: i => a;\n  let fi: i => f(i);\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet10.re",
    "content": "module FreeFunctor = (F: {type f('a);}) : Functor => {\n  module type F = FreeF with type f('a) = F.f('a);\n\n  type t('a) = (module F with type a = 'a);\n\n  let fmap =\n    (type a', type b', \n      f: a' => b', module FF: F with type a = a') :\n    (module F with type a = b') =>\n    (module {\n       type f('a) = F.f('a);\n       type a = b';\n       type i = FF.i;\n\n       let h = i => f(FF.h(i));\n       let fi = FF.fi;\n    });\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet11.re",
    "content": "module type FreeF_Alt = {\n  type a;\n  type f('a);\n\n  let freeF: (a => 'i) => f('i);\n};\n"
  },
  {
    "path": "src/content/3.11/code/reason/snippet12.re",
    "content": "module FreeFunctorAlt = (F: {type f('a);}) : Functor => {\n  module type F = FreeF_Alt with type f('a) = F.f('a);\n\n  type t('a) = (module F with type a = 'a);\n\n  let fmap =\n      (type a', type b', f, module FF: F with type a = a')\n      : (module F with type a = b') =>\n    (module {\n       type a = b';\n       type f('a) = F.f('a);\n\n       let freeF = bi => FF.freeF(a => bi(f(a)));\n    });\n};\n"
  },
  {
    "path": "src/content/3.11/code/scala/snippet01.scala",
    "content": "// Another type needs to be introduced.\n// To read more about FunctionK (~>):\n// typelevel.org/cats/datatypes/functionk.html\ntrait ~>[F[_], G[_]] {\n  def apply[C](fa: F[C]): G[C]\n}\n\ntrait Ran[K[_], D[_], A] {\n  // partially-applied type\n  type AtoK[I] = A => K[I]\n\n  def apply: AtoK ~> D\n}"
  },
  {
    "path": "src/content/3.11/code/scala/snippet02.scala",
    "content": "def f: String => Tree[Int]"
  },
  {
    "path": "src/content/3.11/code/scala/snippet03.scala",
    "content": "type Id[I] = I\n\ntrait PolyFunc[A, K[_]] {\n  type AtoK[I] = A => K[I]\n\n  def apply(): AtoK ~> Id\n}"
  },
  {
    "path": "src/content/3.11/code/scala/snippet04.scala",
    "content": "trait `PolyFunctionM`[F[_], G[_]] {\n  def apply[I: Monoid](fa: F[I]): G[I]\n}\n\ntrait Lst[A] {\n  type aTo[X] = A => X\n\n  def apply(): aTo `PolyFunctionM` Id\n}"
  },
  {
    "path": "src/content/3.11/code/scala/snippet05.scala",
    "content": "// Read more about foldMap:\n// typelevel.org/cats/typeclasses/foldable.html\ndef foldMap[F[_], A, B](fa: F[A])(f: A => B)\n                       (implicit B: Monoid[B]): B = ???\nimplicit def listMonoid[A]: Monoid[List[A]] = ???\n\ndef toLst[A]: List[A] => Lst[A] = as => new Lst[A] {\n  def apply(): `PolyFunctionM`[aTo, Id] =\n    new `PolyFunctionM`[aTo, Id] {\n      def apply[I: Monoid](fa: aTo[I]): Id[I] =\n        foldMap(as)(fa)\n    }\n}\n\ndef fromLst[A]: Lst[A] => List[A] =\n  f => f().apply(a => List(a))"
  },
  {
    "path": "src/content/3.11/code/scala/snippet06.scala",
    "content": "trait Lan[K[_], +D[_], A] {\n  def fk[I](ki: K[I]): A\n  def di[I]: D[I]\n}"
  },
  {
    "path": "src/content/3.11/code/scala/snippet07.scala",
    "content": "type Exp[A, B] = Lan[(A, ?), I, B]"
  },
  {
    "path": "src/content/3.11/code/scala/snippet08.scala",
    "content": "def fst[I]: ((I, _)) => I = _._1\n\ndef toExp[A, B]: (A => B) => Exp[A, B] = f => new Lan[(A, ?), I, B] {\n  def fk[L](ki: (A, L)): B =\n    f.compose(fst[A])(ki)\n\n  def di[L]: I[L] = I()\n}\n\ndef fromExp[A, B]: Exp[A, B] => (A => B) =\n  lan => a => lan.fk((a, lan.di))"
  },
  {
    "path": "src/content/3.11/code/scala/snippet09.scala",
    "content": "trait FreeF[F[_], A] {\n  def h[I]: I => A\n  def fi[I]: F[I]\n}"
  },
  {
    "path": "src/content/3.11/code/scala/snippet10.scala",
    "content": "implicit def freeFunctor[F[_]] = new Functor[FreeF[F, ?]] {\n  def fmap[A, B](g: A => B)(fa: FreeF[F, A]): FreeF[F, B] = {\n    new FreeF[F, B] {\n      def h[I]: I => B = g compose fa.h\n      def fi[I]: F[I] = fi\n    }\n  }\n}"
  },
  {
    "path": "src/content/3.11/code/scala/snippet11.scala",
    "content": "case class FreeF[F[_], A](r: (A => ?) ~> F)"
  },
  {
    "path": "src/content/3.11/code/scala/snippet12.scala",
    "content": "implicit def freeFunctor[F[_]] = new Functor[FreeF[F, ?]] {\n  def fmap[A, B](g: A => B)(fa: FreeF[F, A]): FreeF[F, B] = fa match {\n    case FreeF(r) => FreeF {\n      new ~>[B => ?, F] {\n        def apply[C](bi: B => C): F[C] =\n          r(bi compose g)\n      }\n    }\n  }\n}"
  },
  {
    "path": "src/content/3.11/kan-extensions.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{S}{o far we've been} mostly working with a single category or a pair of\ncategories. In some cases that was a little too constraining.\n\nFor instance, when defining a limit in a category $\\cat{C}$, we introduced an\nindex category $\\cat{I}$ as the template for the pattern that would\nform the basis for our cones. It would have made sense to introduce\nanother category, a trivial one, to serve as a template for the apex of\nthe cone. Instead we used the constant functor $\\Delta_c$ from\n$\\cat{I}$ to $\\cat{C}$.\n\nIt's time to fix this awkwardness. Let's define a limit using three\ncategories. Let's start with the functor $D$ from the index\ncategory $\\cat{I}$ to $\\cat{C}$. This is the functor that selects the base\nof the cone --- the diagram functor.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan2.jpg}\n\\end{figure}\n\n\\noindent\nThe new addition is the category $\\cat{1}$ that contains a single\nobject (and a single identity morphism). There is only one possible\nfunctor $K$ from $\\cat{I}$ to this category. It maps all objects\nto the only object in $\\cat{1}$, and all morphisms to the identity\nmorphism. Any functor $F$ from $\\cat{1}$ to $\\cat{C}$ picks a\npotential apex for our cone.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan15.jpg}\n\\end{figure}\n\n\\noindent\nA cone is a natural transformation $\\varepsilon$ from $F \\circ K$ to\n$D$. Notice that $F \\circ K$ does exactly the same thing as\nour original $\\Delta_c$. The following diagram shows this\ntransformation.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan3-e1492120491591.jpg}\n\\end{figure}\n\n\\noindent\nWe can now define a universal property that picks the ``best'' such\nfunctor $F$. This $F$ will map $\\cat{1}$ to the object\nthat is the limit of $D$ in $\\cat{C}$, and the natural\ntransformation $\\varepsilon$ from $F \\circ K$ to $D$ will\nprovide the corresponding projections. This universal functor is called\nthe right Kan extension of $D$ along $K$ and is denoted by\n$\\Ran_{K}D$.\n\nLet's formulate the universal property. Suppose we have another cone ---\nthat is another functor $F'$ together with a natural\ntransformation $\\varepsilon'$ from $F' \\circ K$ to\n$D$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan31-e1492120512209.jpg}\n\\end{figure}\n\n\\noindent\nIf the Kan extension $F = Ran_{K}D$ exists, there must be a unique\nnatural transformation $\\sigma$ from $F'$ to it, such\nthat $\\varepsilon'$ factorizes through $\\varepsilon$, that is:\n\\[\\varepsilon' = \\varepsilon \\cdot (\\sigma \\circ K)\\]\nHere, $\\sigma \\circ K$ is the horizontal composition of two natural\ntransformations (one of them being the identity natural transformation\non $K$). This transformation is then vertically composed with\n$\\varepsilon$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan5.jpg}\n\\end{figure}\n\n\\noindent\nIn components, when acting on an object $i$ in $\\cat{I}$, we get:\n\\[\\varepsilon'_i = \\varepsilon_i \\circ \\sigma_{K i}\\]\nIn our case, $\\sigma$ has only one component corresponding to the\nsingle object of $\\cat{1}$. So, indeed, this is the unique morphism\nfrom the apex of the cone defined by $F'$ to the apex of\nthe universal cone defined by $\\Ran_{K}D$. The commuting conditions\nare exactly the ones required by the definition of a limit.\n\nBut, importantly, we are free to replace the trivial category $\\cat{1}$\nwith an arbitrary category $\\cat{A}$, and the definition of the right Kan\nextension remains valid.\n\n\\section{Right Kan Extension}\n\nThe right Kan extension of the functor $D \\Colon \\cat{I} \\to \\cat{C}$\nalong the functor $K \\Colon \\cat{I} \\to \\cat{A}$ is a functor\n$F \\Colon \\cat{A} \\to \\cat{C}$ (denoted $\\Ran_{K}D$) together with a\nnatural transformation\n\\[\\varepsilon \\Colon F \\circ K \\to D\\]\nsuch that for any other functor $F' \\Colon \\cat{A} \\to \\cat{C}$ and\na natural transformation\n\\[\\varepsilon' \\Colon F' \\circ K \\to D\\]\nthere is a unique natural transformation\n\\[\\sigma \\Colon F' \\to F\\]\nthat factorizes $\\varepsilon'$:\n\\[\\varepsilon' = \\varepsilon \\cdot (\\sigma \\circ K)\\]\nThis is quite a mouthful, but it can be visualized in this nice diagram:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan7.jpg}\n\\end{figure}\n\n\\noindent\nAn interesting way of looking at this is to notice that, in a sense, the\nKan extension acts like the inverse of ``functor multiplication.'' Some\nauthors go as far as use the notation $D/K$ for $\\Ran_{K}D$.\nIndeed, in this notation, the definition of $\\varepsilon$, which is also\ncalled the counit of the right Kan extension, looks like simple\ncancellation:\n\\[\\varepsilon \\Colon D/K \\circ K \\to D\\]\nThere is another interpretation of Kan extensions. Consider that the\nfunctor $K$ embeds the category $\\cat{I}$ inside $\\cat{A}$. In the\nsimplest case $\\cat{I}$ could just be a subcategory of $\\cat{A}$. We have\na functor $D$ that maps $\\cat{I}$ to $\\cat{C}$. Can we extend\n$D$ to a functor $F$ that is defined on the whole of\n$\\cat{A}$? Ideally, such an extension would make the composition\n$F \\circ K$ be isomorphic to $D$. In other words, $F$\nwould be extending the domain of $D$ to $\\cat{A}$. But a\nfull-blown isomorphism is usually too much to ask, and we can do with\njust half of it, namely a one-way natural transformation $\\varepsilon$ from\n$F \\circ K$ to $D$. (The left Kan extension picks the other direction.)\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan6.jpg}\n\\end{figure}\n\n\\noindent\nOf course, the embedding picture breaks down when the functor $K$\nis not injective on objects or not faithful on hom-sets, as in the\nexample of the limit. In that case, the Kan extension tries its best to\nextrapolate the lost information.\n\n\\section{Kan Extension as Adjunction}\n\nNow suppose that the right Kan extension exists for any $D$ (and\na fixed $K$). In that case $\\Ran_{K}-$ (with the dash\nreplacing $D$) is a functor from the functor category\n${[}\\cat{I}, \\cat{C}{]}$ to the functor category ${[}\\cat{A}, \\cat{C}{]}$. It\nturns out that this functor is the right adjoint to the precomposition\nfunctor $- \\circ K$. The latter maps functors in ${[}\\cat{A}, \\cat{C}{]}$\nto functors in ${[}\\cat{I}, \\cat{C}{]}$. The adjunction is:\n\\[[\\cat{I}, \\cat{C}](F' \\circ K, D) \\cong [\\cat{A}, \\cat{C}](F', \\Ran_{K}D)\\]\nIt is just a restatement of the fact that to every natural\ntransformation we called $\\varepsilon'$ corresponds a unique natural\ntransformation we called $\\sigma$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan92.jpg}\n\\end{figure}\n\n\\noindent\nFurthermore, if we chose the category $\\cat{I}$ to be the same as\n$\\cat{C}$, we can substitute the identity functor $I_{\\cat{C}}$ for\n$D$. We get the following identity:\n\\[[\\cat{C}, \\cat{C}](F' \\circ K, I_{\\cat{C}}) \\cong [\\cat{A}, \\cat{C}](F', \\Ran_{K}I_{\\cat{C}})\\]\nWe can now chose $F'$ to be the same as $\\Ran_{K}I_{\\cat{C}}$. In\nthat case the right hand side contains the identity natural\ntransformation and, corresponding to it, the left hand side gives us the\nfollowing natural transformation:\n\\[\\varepsilon \\Colon \\Ran_{K}I_{\\cat{C}} \\circ K \\to I_{\\cat{C}}\\]\nThis looks very much like the counit of an adjunction:\n\\[\\Ran_{K}I_{\\cat{C}} \\dashv K\\]\nIndeed, the right Kan extension of the identity functor along a functor\n$K$ can be used to calculate the left adjoint of $K$. For\nthat, one more condition is necessary: the right Kan extension must be\npreserved by the functor $K$. The preservation of the extension\nmeans that, if we calculate the Kan extension of the functor precomposed\nwith $K$, we should get the same result as precomposing the\noriginal Kan extension with $K$. In our case, this condition\nsimplifies to:\n\\[K \\circ \\Ran_{K}I_{\\cat{C}} \\cong \\Ran_{K}K\\]\nNotice that, using the division-by-$K$ notation, the adjunction can be\nwritten as:\n\\[I/K \\dashv K\\]\nwhich confirms our intuition that an adjunction describes some kind of\nan inverse. The preservation condition becomes:\n\\[K \\circ I/K \\cong K/K\\]\nThe right Kan extension of a functor along itself, $K/K$, is\ncalled a codensity monad.\n\nThe adjunction formula is an important result because, as we'll see\nsoon, we can calculate Kan extensions using ends (coends), thus giving\nus practical means of finding right (and left) adjoints.\n\n\\section{Left Kan Extension}\n\nThere is a dual construction that gives us the left Kan extension. To\nbuild some intuition, we'll start with the definition of a colimit\nand restructure it to use the singleton category $\\cat{1}$. We build a\ncocone by using the functor $D \\Colon \\cat{I} \\to \\cat{C}$ to form its\nbase, and the functor $F \\Colon \\cat{1} \\to \\cat{C}$ to select its apex.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan81.jpg}\n\\end{figure}\n\n\\noindent\nThe sides of the cocone, the injections, are components of a natural\ntransformation $\\eta$ from $D$ to $F \\circ K$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan10a.jpg}\n\\end{figure}\n\n\\noindent\nThe colimit is the universal cocone. So for any other functor\n$F'$ and a natural transformation\n\\[\\eta' \\Colon D \\to F' \\circ K\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan10b.jpg}\n\\end{figure}\n\n\\noindent\nthere is a unique natural transformation $\\sigma$ from $F$ to $F'$\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan14.jpg}\n\\end{figure}\n\n\\noindent\nsuch that:\n\\[\\eta' = (\\sigma \\circ K) \\cdot \\eta\\]\nThis is illustrated in the following diagram:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan112.jpg}\n\\end{figure}\n\n\\noindent\nReplacing the singleton category $\\cat{1}$ with $\\cat{A}$, this\ndefinition naturally generalized to the definition of the left Kan\nextension, denoted by $\\Lan_{K}D$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan12.jpg}\n\\end{figure}\n\n\\noindent\nThe natural transformation:\n\\[\\eta \\Colon D \\to \\Lan_{K}D \\circ K\\]\nis called the unit of the left Kan extension.\n\nAs before, we can recast the one-to-one correspondence between natural\ntransformations:\n\\[\\eta' = (\\sigma \\circ K) \\cdot \\eta\\]\nin terms of the adjunction:\n\\[[\\cat{A}, \\cat{C}](\\Lan_{K}D, F') \\cong [\\cat{I}, \\cat{C}](D, F' \\circ K)\\]\nIn other words, the left Kan extension is the left adjoint, and the\nright Kan extension is the right adjoint of the precomposition with\n$K$.\n\nJust like the right Kan extension of the identity functor could be used\nto calculate the left adjoint of $K$, the left Kan extension of\nthe identity functor turns out to be the right adjoint of $K$\n(with $\\eta$ being the unit of the adjunction):\n\\[K \\dashv \\Lan_{K}I_{\\cat{C}}\\]\nCombining the two results, we get:\n\\[\\Ran_{K}I_{\\cat{C}} \\dashv K \\dashv \\Lan_{K}I_{\\cat{C}}\\]\n\n\\section{Kan Extensions as Ends}\n\nThe real power of Kan extensions comes from the fact that they can be\ncalculated using ends (and coends). For simplicity, we'll restrict our\nattention to the case where the target category $\\cat{C}$ is\n$\\Set$, but the formulas can be extended to any category.\n\nLet's revisit the idea that a Kan extension can be used to extend the\naction of a functor outside of its original domain. Suppose that\n$K$ embeds $\\cat{I}$ inside $\\cat{A}$. Functor $D$ maps\n$\\cat{I}$ to $\\Set$. We could just say that for any object\n$a$ in the image of $K$, that is $a = K i$, the\nextended functor maps $a$ to $D i$. The problem is, what\nto do with those objects in $\\cat{A}$ that are outside of the image of\n$K$? The idea is that every such object is potentially connected\nthrough lots of morphisms to every object in the image of $K$. A\nfunctor must preserve these morphisms. The totality of morphisms from an\nobject $a$ to the image of $K$ is characterized by the\nhom-functor:\n\\[\\cat{A}(a, K -)\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/kan13.jpg}\n\\end{figure}\n\n\\noindent\nNotice that this hom-functor is a composition of two functors:\n\\[\\cat{A}(a, K -) = \\cat{A}(a, -) \\circ K\\]\nThe right Kan extension is the right adjoint of functor composition:\n\\[[\\cat{I}, \\Set](F' \\circ K, D) \\cong [\\cat{A}, \\Set](F', \\Ran_{K}D)\\]\nLet's see what happens when we replace $F'$ with the hom\nfunctor:\n\\[[\\cat{I}, \\Set](\\cat{A}(a, -) \\circ K, D) \\cong [\\cat{A}, \\Set](\\cat{A}(a, -), \\Ran_{K}D)\\]\nand then inline the composition:\n\\[[\\cat{I}, \\Set](\\cat{A}(a, K -), D) \\cong [\\cat{A}, \\Set](\\cat{A}(a, -), \\Ran_{K}D)\\]\nThe right hand side can be reduced using the Yoneda lemma:\n\\[[\\cat{I}, \\Set](\\cat{A}(a, K -), D) \\cong \\Ran_{K}D a\\]\nWe can now rewrite the set of natural transformations as the end to get\nthis very convenient formula for the right Kan extension:\n\\[\\Ran_{K}D a \\cong \\int_i \\Set(\\cat{A}(a, K i), D i)\\]\nThere is an analogous formula for the left Kan extension in terms of a\ncoend:\n\\[\\Lan_{K}D a = \\int^i \\cat{A}(K i, a)\\times{}D i\\]\nTo see that this is the case, we'll show that this is indeed the left\nadjoint to functor composition:\n\\[[\\cat{A}, \\Set](\\Lan_{K}D, F') \\cong [\\cat{I}, \\Set](D, F' \\circ K)\\]\nLet's substitute our formula in the left hand side:\n\\[[\\cat{A}, \\Set](\\int^i \\cat{A}(K i, -)\\times{}D i, F')\\]\nThis is a set of natural transformations, so it can be rewritten as an\nend:\n\\[\\int_a \\Set(\\int^i \\cat{A}(K i, a)\\times{}D i, F' a)\\]\nUsing the continuity of the hom-functor, we can replace the coend with\nthe end:\n\\[\\int_a \\int_i \\Set(\\cat{A}(K i, a)\\times{}D i, F' a)\\]\nWe can use the product-exponential adjunction:\n\\[\\int_a \\int_i \\Set(\\cat{A}(K i, a),\\ (F' a)^{D i})\\]\nThe exponential is isomorphic to the corresponding hom-set:\n\\[\\int_a \\int_i \\Set(\\cat{A}(K i, a),\\ \\Set(D i, F' a))\\]\nThere is a theorem called the Fubini theorem that allows us to swap the\ntwo ends:\n\\[\\int_i \\int_a \\Set(\\cat{A}(K i, a),\\ \\Set(D i, F' a))\\]\nThe inner end represents the set of natural transformations between two\nfunctors, so we can use the Yoneda lemma:\n\\[\\int_i \\Set(D i, F' (K i))\\]\nThis is indeed the set of natural transformations that forms the right\nhand side of the adjunction we set out to prove:\n\\[[\\cat{I}, \\Set](D, F' \\circ K)\\]\nThese kinds of calculations using ends, coends, and the Yoneda lemma are\npretty typical for the ``calculus'' of ends.\n\n\\section{Kan Extensions in Haskell}\n\nThe end/coend formulas for Kan extensions can be easily translated to\nHaskell. Let's start with the right extension:\n\\[\\Ran_{K}D a \\cong \\int_i \\Set(\\cat{A}(a, K i), D i)\\]\nWe replace the end with the universal quantifier, and hom-sets with\nfunction types:\n\n\\src{snippet01}\nLooking at this definition, it's clear that \\code{Ran} must contain a\nvalue of type \\code{a} to which the function can be applied, and a\nnatural transformation between the two functors \\code{k} and\n\\code{d}. For instance, suppose that \\code{k} is the tree functor,\nand \\code{d} is the list functor, and you were given a\n\\code{Ran Tree {[}{]} String}. If you pass it a function:\n\n\\src{snippet02}\nyou'll get back a list of \\code{Int}, and so on. The right Kan\nextension will use your function to produce a tree and then repackage it\ninto a list. For instance, you may pass it a parser that generates a\nparsing tree from a string, and you'll get a list that corresponds to\nthe depth-first traversal of this tree.\n\nThe right Kan extension can be used to calculate the left adjoint of a\ngiven functor by replacing the functor \\code{d} with the identity\nfunctor. This leads to the left adjoint of a functor \\code{k} being\nrepresented by the set of polymorphic functions of the type:\n\n\\src{snippet03}\nSuppose that \\code{k} is the forgetful functor from the category of\nmonoids. The universal quantifier then goes over all monoids. Of course,\nin Haskell we cannot express monoidal laws, but the following is a\ndecent approximation of the resulting free functor (the forgetful\nfunctor \\code{k} is an identity on objects):\n\n\\src{snippet04}\nAs expected, it generates free monoids, or Haskell lists:\n\n\\src{snippet05}\nThe left Kan extension is a coend:\n\\[\\Lan_{K}D a = \\int^i \\cat{A}(K i, a)\\times{}D i\\]\nso it translates to an existential quantifier. Symbolically:\n\n\\begin{snip}{haskell}\nLan k d a = exists i. (k i -> a, d i)\n\\end{snip}\nThis can be encoded in Haskell using \\acronym{GADT}s, or using a universally\nquantified data constructor:\n\n\\src{snippet06}\nThe interpretation of this data structure is that it contains a function\nthat takes a container of some unspecified \\code{i}s and produces an\n\\code{a}. It also has a container of those \\code{i}s. Since you have\nno idea what \\code{i}s are, the only thing you can do with this data\nstructure is to retrieve the container of \\code{i}s, repack it into\nthe container defined by the functor \\code{k} using a natural\ntransformation, and call the function to obtain the \\code{a}. For\ninstance, if \\code{d} is a tree, and \\code{k} is a list, you can\nserialize the tree, call the function with the resulting list, and\nobtain an \\code{a}.\n\nThe left Kan extension can be used to calculate the right adjoint of a\nfunctor. We know that the right adjoint of the product functor is the\nexponential, so let's try to implement it using the Kan extension:\n\n\\src{snippet07}\nThis is indeed isomorphic to the function type, as witnessed by the\nfollowing pair of functions:\n\n\\src{snippet08}\nNotice that, as described earlier in the general case, we performed the\nfollowing steps:\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Retrieved the container of \\code{x} (here, it's\n        just a trivial identity container), and the function \\code{f}.\n  \\item\n        Repackaged the container using the natural transformation between the\n        identity functor and the pair functor.\n  \\item\n        Called the function \\code{f}.\n\\end{enumerate}\n\n\\section{Free Functor}\n\nAn interesting application of Kan extensions is the construction of a\nfree functor. It's the solution to the following practical problem:\nsuppose you have a type constructor --- that is a mapping of objects. Is\nit possible to define a functor based on this type constructor? In other\nwords, can we define a mapping of morphisms that would extend this type\nconstructor to a full-blown endofunctor?\n\nThe key observation is that a type constructor can be described as a\nfunctor whose domain is a discrete category. A discrete category has no\nmorphisms other than the identity morphisms. Given a category $\\cat{C}$,\nwe can always construct a discrete category $\\cat{|C|}$\nby simply discarding all non-identity morphisms. A functor $F$\nfrom $\\cat{|C|}$ to $\\cat{C}$ is then a simple mapping\nof objects, or what we call a type constructor in Haskell. There is also\na canonical functor $J$ that injects $\\cat{|C|}$\ninto $\\cat{C}$: it's an identity on objects (and on identity morphisms).\nThe left Kan extension of $F$ along $J$, if it exists, is\nthen a functor for $\\cat{C}$ to $\\cat{C}$:\n\\[\\Lan_{J}F a = \\int^i \\cat{C}(J i, a)\\times{}F i\\]\nIt's called a free functor based on $F$.\n\nIn Haskell, we would write it as:\n\n\\src{snippet09}\nIndeed, for any type constructor \\code{f}, \\code{FreeF f} is a\nfunctor:\n\n\\src{snippet10}\nAs you can see, the free functor fakes the lifting of a function by\nrecording both the function and its argument. It accumulates the lifted\nfunctions by recording their composition. Functor rules are\nautomatically satisfied. This construction was used in a paper\n\\urlref{http://okmij.org/ftp/Haskell/extensible/more.pdf}{Freer Monads,\n  More Extensible Effects}.\n\nAlternatively, we can use the right Kan extension for the same purpose:\n\n\\src{snippet11}\nIt's easy to check that this is indeed a functor:\n\n\\src{snippet12}\n"
  },
  {
    "path": "src/content/3.12/enriched-categories.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{A}{ category is small} if its objects form a set. But we know that\nthere are things larger than sets. Famously, a set of all sets cannot be\nformed within the standard set theory (the Zermelo-Fraenkel theory,\noptionally augmented with the Axiom of Choice). So a category of all\nsets must be large. There are mathematical tricks like Grothendieck\nuniverses that can be used to define collections that go beyond sets.\nThese tricks let us talk about large categories.\n\nA category is \\emph{locally small} if morphisms between any two objects\nform a set. If they don't form a set, we have to rethink a few\ndefinitions. In particular, what does it mean to compose morphisms if we\ncan't even pick them from a set? The solution is to bootstrap ourselves\nby replacing hom-sets, which are objects in $\\Set$, with\n\\emph{objects} from some other category $\\cat{V}$. The difference is\nthat, in general, objects don't have elements, so we are no longer\nallowed to talk about individual morphisms. We have to define all\nproperties of an \\emph{enriched} category in terms of operations that\ncan be performed on hom-objects as a whole. In order to do that, the\ncategory that provides hom-objects must have additional structure --- it\nmust be a monoidal category. If we call this monoidal category $\\cat{V}$,\nwe can talk about a category $\\cat{C}$ enriched over $\\cat{V}$.\n\nBeside size reasons, we might be interested in generalizing hom-sets to\nsomething that has more structure than mere sets. For instance, a\ntraditional category doesn't have the notion of a distance between\nobjects. Two objects are either connected by morphisms or not. All\nobjects that are connected to a given object are its neighbors. Unlike\nin real life; in a category, a friend of a friend of a friend is as\nclose to me as my bosom buddy. In a suitably enriched category, we can\ndefine distances between objects.\n\nThere is one more very practical reason to get some experience with\nenriched categories, and that's because a very useful online source of\ncategorical knowledge, the \\urlref{https://ncatlab.org/}{nLab}, is written\nmostly in terms of enriched categories.\n\n\\section{Why Monoidal Category?}\n\nWhen constructing an enriched category we have to keep in mind that we\nshould be able to recover the usual definitions when we replace the\nmonoidal category with $\\Set$ and hom-objects with hom-sets. The\nbest way to accomplish this is to start with the usual definitions and\nkeep reformulating them in a point-free manner --- that is, without\nnaming elements of sets.\n\nLet's start with the definition of composition. Normally, it takes a\npair of morphisms, one from $\\cat{C}(b, c)$ and one from\n$\\cat{C}(a, b)$ and maps it to a morphism from $\\cat{C}(a, c)$. In\nother words it's a mapping:\n\\[\\cat{C}(b, c)\\times{}\\cat{C}(a, b) \\to \\cat{C}(a, c)\\]\nThis is a function between sets --- one of them being the Cartesian\nproduct of two hom-sets. This formula can be easily generalized by\nreplacing Cartesian product with something more general. A categorical\nproduct would work, but we can go even further and use a completely\ngeneral tensor product.\n\nNext come the identity morphisms. Instead of picking individual elements\nfrom hom-sets, we can define them using functions from the singleton set\n$\\cat{1}$:\n\\[j_a \\Colon \\cat{1} \\to \\cat{C}(a, a)\\]\nAgain, we could replace the singleton set with the terminal object, but\nwe can go even further by replacing it with the unit $i$ of the\ntensor product.\n\nAs you can see, objects taken from some monoidal category $\\cat{V}$ are\ngood candidates for hom-set replacement.\n\n\\section{Monoidal Category}\n\nWe've talked about monoidal categories before, but it's worth restating\nthe definition. A monoidal category defines a tensor product that is a\nbifunctor:\n\\[\\otimes \\Colon \\cat{V}\\times{}\\cat{V} \\to \\cat{V}\\]\nWe want the tensor product to be associative, but it's enough to satisfy\nassociativity up to natural isomorphism. This isomorphism is called the\nassociator. Its components are:\n\\[\\alpha_{a b c} \\Colon (a \\otimes b) \\otimes c \\to a \\otimes (b \\otimes c)\\]\nIt must be natural in all three arguments.\n\nA monoidal category must also define a special unit object $i$\nthat serves as the unit of the tensor product; again, up to natural\nisomorphism. The two isomorphisms are called, respectively, the left and\nthe right unitor, and their components are:\n\\begin{align*}\n  \\lambda_a & \\Colon i \\otimes a \\to a \\\\\n  \\rho_a    & \\Colon a \\otimes i \\to a\n\\end{align*}\nThe associator and the unitors must satisfy coherence conditions:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}[row sep=large]\n    ((a \\otimes b) \\otimes c) \\otimes d\n    \\arrow[d, \"\\alpha_{(a \\otimes b)cd}\"]\n    \\arrow[rr, \"\\alpha_{abc} \\otimes \\id_d\"]\n    & & (a \\otimes (b \\otimes c)) \\otimes d\n    \\arrow[d, \"\\alpha_{a(b \\otimes c)d}\"] \\\\\n    (a \\otimes b) \\otimes (c \\otimes d)\n    \\arrow[rd, \"\\alpha_{ab(c \\otimes d)}\"]\n    & & a \\otimes ((b \\otimes c) \\otimes d)\n    \\arrow[ld, \"\\id_a \\otimes \\alpha_{bcd}\"] \\\\\n    & a \\otimes (b \\otimes (c \\otimes d))\n  \\end{tikzcd}\n\\end{figure}\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}[row sep=large]\n    (a \\otimes i) \\otimes b\n    \\arrow[dr, \"\\rho_{a} \\otimes \\id_b\"']\n    \\arrow[rr, \"\\alpha_{aib}\"]\n    & & a \\otimes (i \\otimes b)\n    \\arrow[dl, \"\\id_a \\otimes \\lambda_b\"] \\\\\n    & a \\otimes b\n  \\end{tikzcd}\n\\end{figure}\n\n\\noindent\nA monoidal category is called \\newterm{symmetric} if there is a natural\nisomorphism with components:\n\\[\\gamma_{a b} \\Colon a \\otimes b \\to b \\otimes a\\]\nwhose ``square is one'':\n\\[\\gamma_{b a} \\circ \\gamma_{a b} = \\idarrow[a \\otimes b]\\]\nand which is consistent with the monoidal structure.\n\nAn interesting thing about monoidal categories is that you may be able\nto define the internal hom (the function object) as the right adjoint to\nthe tensor product. You may recall that the standard definition of the\nfunction object, or the exponential, was through the right adjoint to\nthe categorical product. A category in which such an object existed for\nany pair of objects was called Cartesian closed. Here is the adjunction\nthat defines the internal hom in a monoidal category:\n\\[\\cat{V}(a \\otimes b, c) \\sim \\cat{V}(a, [b, c])\\]\nFollowing\n\\urlref{http://www.tac.mta.ca/tac/reprints/articles/10/tr10.pdf}{G. M.\n  Kelly}, I'm using the notation ${[}b, c{]}$ for the internal\nhom. The counit of this adjunction is the natural transformation whose\ncomponents are called evaluation morphisms:\n\\[\\varepsilon_{a b} \\Colon ([a, b] \\otimes a) \\to b\\]\nNotice that, if the tensor product is not symmetric, we may define\nanother internal hom, denoted by ${[}{[}a, c{]}{]}$, using the\nfollowing adjunction:\n\\[\\cat{V}(a \\otimes b, c) \\sim \\cat{V}(b, [[a, c]])\\]\nA monoidal category in which both are defined is called \\newterm{biclosed}. An\nexample of a category that is not biclosed is the category of\nendofunctors in $\\Set$, with functor composition serving as tensor\nproduct. That's the category we used to define monads.\n\n\\section{Enriched Category}\n\nA category $\\cat{C}$ enriched over a monoidal category $\\cat{V}$ replaces\nhom-sets with hom-objects. To every pair of objects $a$ and\n$b$ in $\\cat{C}$ we associate an object $\\cat{C}(a, b)$ in\n$\\cat{V}$. We use the same notation for hom-objects as we used for\nhom-sets, with the understanding that they don't contain morphisms. On\nthe other hand, $\\cat{V}$ is a regular (non-enriched) category with\nhom-sets and morphisms. So we are not entirely rid of sets --- we just\nswept them under the rug.\n\nSince we cannot talk about individual morphisms in $\\cat{C}$, composition\nof morphisms is replaced by a family of morphisms in $\\cat{V}$:\n\\[\\circ \\Colon \\cat{C}(b, c) \\otimes \\cat{C}(a, b) \\to \\cat{C}(a, c)\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.45\\textwidth]{images/composition.jpg}\n\\end{figure}\n\n\\noindent\nSimilarly, identity morphisms are replaced by a family of morphisms in\n$\\cat{V}$:\n\\[j_a \\Colon i \\to \\cat{C}(a, a)\\]\nwhere $i$ is the tensor unit in $\\cat{V}$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/id.jpg}\n\\end{figure}\n\n\\noindent\nAssociativity of composition is defined in terms of the associator in\n$\\cat{V}$:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}[column sep=large]\n    (\\cat{C}(c,d) \\otimes \\cat{C}(b,c)) \\otimes \\cat{C}(a,b)\n    \\arrow[r, \"\\circ\\otimes\\id\"]\n    \\arrow[dd, \"\\alpha\"]\n    & \\cat{C}(b,d) \\otimes \\cat{C}(a,b)\n    \\arrow[dr, \"\\circ\"] \\\\\n    & & \\cat{C}(a,d) \\\\\n    \\cat{C}(c,d) \\otimes (\\cat{C}(b,c) \\otimes \\cat{C}(a,b))\n    \\arrow[r, \"\\id\\otimes\\circ\"]\n    & \\cat{C}(c,d) \\otimes \\cat{C}(a,c)\n    \\arrow[ur, \"\\circ\"]\n  \\end{tikzcd}\n\\end{figure}\n\n\\noindent\nUnit laws are likewise expressed in terms of unitors:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[row sep=large]\n      \\cat{C}(a,b) \\otimes i\n      \\arrow[rr, \"\\id \\otimes j_a\"]\n      \\arrow[dr, \"\\rho\"]\n      & & \\cat{C}(a,b) \\otimes \\cat{C}(a,a)\n      \\arrow[dl, \"\\circ\"] \\\\\n      & \\cat{C}(a,b)\n    \\end{tikzcd}\n  \\end{subfigure}\n  \\hspace{1cm}\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[row sep=large]\n      i \\otimes \\cat{C}(a,b)\n      \\arrow[rr, \"j_b \\otimes \\id\"]\n      \\arrow[dr, \"\\lambda\"]\n      & & \\cat{C}(b,b) \\otimes \\cat{C}(a,b)\n      \\arrow[dl, \"\\circ\"] \\\\\n      & \\cat{C}(a,b)\n    \\end{tikzcd}\n  \\end{subfigure}\n\\end{figure}\n\n\\section{Preorders}\n\nA preorder is defined as a thin category, one in which every hom-set is\neither empty or a singleton. We interpret a non-empty set\n$\\cat{C}(a, b)$ as the proof that $a$ is less than or equal to\n$b$. Such a category can be interpreted as enriched over a very\nsimple monoidal category that contains just two objects, $0$ and $1$\n(sometimes called $\\mathit{False}$ and $\\mathit{True}$). Besides the mandatory identity\nmorphisms, this category has a single morphism going from $0$ to $1$, let's\ncall it $0 \\to 1$. A simple monoidal structure can be\nestablished in it, with the tensor product modeling the simple\narithmetic of $0$ and $1$ (i.e., the only non-zero product is $1 \\otimes 1$).\nThe identity object in this category is $1$. This is a strict monoidal\ncategory, that is, the associator and the unitors are identity\nmorphisms.\n\nSince in a preorder the-hom set is either empty or a singleton, we can\neasily replace it with a hom-object from our tiny category. The enriched\npreorder $\\cat{C}$ has a hom-object $\\cat{C}(a, b)$ for any pair of\nobjects $a$ and $b$. If $a$ is less than or equal\nto $b$, this object is $1$; otherwise it's $0$.\n\nLet's have a look at composition. The tensor product of any two objects\nis $0$, unless both of them are $1$, in which case it's $1$. If it's $0$, then\nwe have two options for the composition morphism: it could be either\n$\\idarrow[0]$ or $0 \\to 1$. But if it's $1$, then the only\noption is $\\idarrow[1]$. Translating this back to relations, this says\nthat if $a \\leqslant b$ and $b \\leqslant c$ then\n$a \\leqslant c$, which is exactly the transitivity law we\nneed.\n\nWhat about the identity? It's a morphism from $1$ to $\\cat{C}(a, a)$.\nThere is only one morphism going from $1$, and that's the identity\n$\\idarrow[1]$, so $\\cat{C}(a, a)$ must be $1$. It means that\n$a \\leqslant a$, which is the reflexivity law for a\npreorder. So both transitivity and reflexivity are automatically\nenforced, if we implement a preorder as an enriched category.\n\n\\section{Metric Spaces}\n\nAn interesting example is due to\n\\urlref{http://www.tac.mta.ca/tac/reprints/articles/1/tr1.pdf}{William\n  Lawvere}. He noticed that metric spaces can be defined using enriched\ncategories. A metric space defines a distance between any two objects.\nThis distance is a non-negative real number. It's convenient to include\ninfinity as a possible value. If the distance is infinite, there is no\nway of getting from the starting object to the target object.\n\nThere are some obvious properties that have to be satisfied by\ndistances. One of them is that the distance from an object to itself\nmust be zero. The other is the triangle inequality: the direct distance\nis no larger than the sum of distances with intermediate stops. We don't\nrequire the distance to be symmetric, which might seem weird at first\nbut, as Lawvere explained, you can imagine that in one direction you're\nwalking uphill, while in the other you're going downhill. In any case,\nsymmetry may be imposed later as an additional constraint.\n\nSo how can a metric space be cast into a categorical language? We have\nto construct a category in which hom-objects are distances. Mind you,\ndistances are not morphisms but hom-objects. How can a hom-object be a\nnumber? Only if we can construct a monoidal category $\\cat{V}$ in which\nthese numbers are objects. Non-negative real numbers (plus infinity)\nform a total order, so they can be treated as a thin category. A\nmorphism between two such numbers $x$ and $y$ exists if\nand only if $x \\geqslant y$ (note: this is the opposite\ndirection to the one traditionally used in the definition of a\npreorder). The monoidal structure is given by addition, with zero\nserving as the unit object. In other words, the tensor product of two\nnumbers is their sum.\n\nA metric space is a category enriched over such a monoidal category. A\nhom-object $\\cat{C}(a, b)$ from object $a$ to $b$ is a\nnon-negative (possibly infinite) number that we will call the distance\nfrom $a$ to $b$. Let's see what we get for identity and\ncomposition in such a category.\n\nBy our definitions, a morphism from the tensorial unit, which is the\nnumber zero, to a hom-object $\\cat{C}(a, a)$ is the relation:\n\\[0 \\geqslant \\cat{C}(a, a)\\]\nSince $\\cat{C}(a, a)$ is a non-negative number, this condition tells\nus that the distance from $a$ to $a$ is always zero.\nCheck!\n\nNow let's talk about composition. We start with the tensor product of\ntwo abutting hom-objects, $\\cat{C}(b, c) \\otimes \\cat{C}(a, b)$. We have defined\nthe tensor product as the sum of the two distances. Composition is a\nmorphism in $\\cat{V}$ from this product to $\\cat{C}(a, c)$. A morphism\nin $\\cat{V}$ is defined as the greater-or-equal relation. In other words,\nthe sum of distances from $a$ to $b$ and from $b$\nto $c$ is greater than or equal to the distance from $a$\nto $c$. But that's just the standard triangle inequality. Check!\n\nBy re-casting the metric space in terms of an enriched category, we get\nthe triangle inequality and the zero self-distance ``for free.''\n\n\\section{Enriched Functors}\n\nThe definition of a functor involves the mapping of morphisms. In the\nenriched setting, we don't have the notion of individual morphisms, so\nwe have to deal with hom-objects in bulk. Hom-objects are objects in a\nmonoidal category $\\cat{V}$, and we have morphisms between them at our\ndisposal. It therefore makes sense to define enriched functors between\ncategories when they are enriched over the same monoidal category\n$\\cat{V}$. We can then use morphisms in $\\cat{V}$ to map the hom-objects\nbetween two enriched categories.\n\nAn \\newterm{enriched functor} $F$ between two categories $\\cat{C}$\nand $\\cat{D}$, besides mapping objects to objects, also assigns, to every\npair of objects in $\\cat{C}$, a morphism in $\\cat{V}$:\n\\[F_{a b} \\Colon \\cat{C}(a, b) \\to \\cat{D}(F a, F b)\\]\nA functor is a structure-preserving mapping. For regular functors it\nmeant preserving composition and identity. In the enriched setting, the\npreservation of composition means that the following diagram commute:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}[column sep=large, row sep=large]\n    \\cat{C}(b,c) \\otimes \\cat{C}(a,b)\n    \\arrow[r, \"\\circ\"]\n    \\arrow[d, \"F_{bc} \\otimes F_{ab}\"]\n    & \\cat{C}(a,c)\n    \\arrow[d, \"F_{ac}\"] \\\\\n    \\cat{D}(F b, F c) \\otimes \\cat{D}(F a, F b)\n    \\arrow[r,  \"\\circ\"]\n    & \\cat{D}(F a, F c)\n  \\end{tikzcd}\n\\end{figure}\n\n\\noindent\nThe preservation of identity is replaced by the preservation of the\nmorphisms in $\\cat{V}$ that ``select'' the identity:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}[row sep=large]\n    & i \\arrow[dl, \"j_a\"'] \\arrow[dr, \"j_{F a}\"] & \\\\\n    \\cat{C}(a,a)\n    \\arrow[rr, \"F_{aa}\"]\n    & & \\cat{D}(F a, F a)\n  \\end{tikzcd}\n\\end{figure}\n\n\\section{Self Enrichment}\n\nA closed symmetric monoidal category may be self-enriched by replacing\nhom-sets with internal homs (see the definition above). To make this\nwork, we have to define the composition law for internal homs. In other\nwords, we have to implement a morphism with the following signature:\n\\[[b, c] \\otimes [a, b] \\to [a, c]\\]\nThis is not much different from any other programming task, except that,\nin category theory, we usually use point free implementations. We start\nby specifying the set whose element it's supposed to be. In this case,\nit's a member of the hom-set:\n\\[\\cat{V}([b, c] \\otimes [a, b], [a, c])\\]\nThis hom-set is isomorphic to:\n\\[\\cat{V}(([b, c] \\otimes [a, b]) \\otimes a, c)\\]\nI just used the adjunction that defined the internal hom\n${[}a, c{]}$. If we can build a morphism in this new set, the\nadjunction will point us at the morphism in the original set, which we\ncan then use as composition. We construct this morphism by composing\nseveral morphisms that are at our disposal. To begin with, we can use\nthe associator $\\alpha_{{[}b, c{]}\\ {[}a, b{]}\\ a}$ to reassociate the\nexpression on the left:\n\\[([b, c] \\otimes [a, b]) \\otimes a \\to [b, c] \\otimes ([a, b] \\otimes a)\\]\nWe can follow it with the counit of the adjunction $\\varepsilon_{a b}$:\n\\[[b, c] \\otimes ([a, b] \\otimes a) \\to [b, c] \\otimes b\\]\nAnd use the counit $\\varepsilon_{b c}$ again to get to $c$. We have\nthus constructed a morphism:\n\\[\\varepsilon_{b c} \\circ (\\idarrow[{[b, c]}] \\otimes \\varepsilon_{a b}) \\circ \\alpha_{[b, c] [a, b] a}\\]\nthat is an element of the hom-set:\n\\[\\cat{V}(([b, c] \\otimes [a, b]) \\otimes a, c)\\]\nThe adjunction will give us the composition law we were looking for.\n\nSimilarly, the identity:\n\\[j_a \\Colon i \\to [a, a]\\]\nis a member of the following hom-set:\n\\[\\cat{V}(i, [a, a])\\]\nwhich is isomorphic, through adjunction, to:\n\\[\\cat{V}(i \\otimes a, a)\\]\nWe know that this hom-set contains the left identity $\\lambda_a$. We can\ndefine $j_a$ as its image under the adjunction.\n\nA practical example of self-enrichment is the category $\\Set$ that\nserves as the prototype for types in programming languages. We've seen\nbefore that it's a closed monoidal category with respect to Cartesian\nproduct. In $\\Set$, the hom-set between any two sets is itself a\nset, so it's an object in $\\Set$. We know that it's isomorphic to\nthe exponential set, so the external and the internal homs are\nequivalent. Now we also know that, through self-enrichment, we can use\nthe exponential set as the hom-object and express composition in terms\nof Cartesian products of exponential objects.\n\n\\section{Relation to $\\cat{2}$-Categories}\n\nI talked about $\\cat{2}$-categories in the context of $\\Cat$, the category\nof (small) categories. The morphisms between categories are functors,\nbut there is an additional structure: natural transformations between\nfunctors. In a $\\cat{2}$-category, the objects are often called zero-cells;\nmorphisms, $1$-cells; and morphisms between morphisms, $2$-cells. In\n$\\Cat$ the $0$-cells are categories, $1$-cells are functors, and\n$2$-cells are natural transformations.\n\nBut notice that functors between two categories form a category too; so,\nin $\\Cat$, we really have a \\emph{hom-category} rather than a\nhom-set. It turns out that, just like $\\Set$ can be treated as a\ncategory enriched over $\\Set$, $\\Cat$ can be treated as a\ncategory enriched over $\\Cat$. Even more generally, just like\nevery category can be treated as enriched over $\\Set$, every\n$\\cat{2}$-category can be considered enriched over $\\Cat$.\n"
  },
  {
    "path": "src/content/3.13/topoi.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{ realize that we might} be getting away from programming and diving into\nhard-core math. But you never know what the next big revolution in\nprogramming might bring and what kind of math might be necessary to\nunderstand it. There are some very interesting ideas going around, like\nfunctional reactive programming with its continuous time, the extension\nof Haskell's type system with dependent types, or the exploration on\nhomotopy type theory in programming.\n\nSo far I've been casually identifying types with \\emph{sets} of values.\nThis is not strictly correct, because such an approach doesn't take into\naccount the fact that, in programming, we \\emph{compute} values, and the\ncomputation is a process that takes time and, in extreme cases, might\nnot terminate. Divergent computations are part of every Turing-complete\nlanguage.\n\nThere are also foundational reasons why set theory might not be the best\nfit as the basis for computer science or even math itself. A good\nanalogy is that of set theory being the assembly language that is tied\nto a particular architecture. If you want to run your math on different\narchitectures, you have to use more general tools.\n\nOne possibility is to use spaces in place of sets. Spaces come with more\nstructure, and may be defined without recourse to sets. One thing\nusually associated with spaces is topology, which is necessary to define\nthings like continuity. And the conventional approach to topology is,\nyou guessed it, through set theory. In particular, the notion of a\nsubset is central to topology. Not surprisingly, category theorists\ngeneralized this idea to categories other than $\\Set$. The type of\ncategory that has just the right properties to serve as a replacement\nfor set theory is called a \\newterm{topos} (plural: topoi), and it\nprovides, among other things, a generalized notion of a subset.\n\n\\section{Subobject Classifier}\n\nLet's start by trying to express the idea of a subset using functions\nrather than elements. Any function $f$ from some set $a$\nto $b$ defines a subset of $b$--that of the image of\n$a$ under $f$. But there are many functions that define\nthe same subset. We need to be more specific. To begin with, we might\nfocus on functions that are injective --- ones that don't smush multiple\nelements into one. Injective functions ``inject'' one set into another.\nFor finite sets, you may visualize injective functions as parallel\narrows connecting elements of one set to elements of another. Of course,\nthe first set cannot be larger than the second set, or the arrows would\nnecessarily converge. There is still some ambiguity left: there may be\nanother set $a'$ and another injective function\n$f'$ from that set to $b$ that picks the same\nsubset. But you can easily convince yourself that such a set would have\nto be isomorphic to $a$. We can use this fact to define a subset\nas a family of injective functions that are related by isomorphisms of\ntheir domains. More precisely, we say that two injective functions:\n\\begin{align*}\n  f  & \\Colon a \\to b  \\\\\n  f' & \\Colon a' \\to b\n\\end{align*}\nare equivalent if there is an isomorphism:\n\\[h \\Colon a \\to a'\\]\nsuch that:\n\\[f = f' \\circ h\\]\nSuch a family of equivalent injections defines a subset of $b$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/subsetinjection.jpg}\n\\end{figure}\n\n\\noindent\nThis definition can be lifted to an arbitrary category if we replace\ninjective functions with monomorphism. Just to remind you, a\nmonomorphism $m$ from $a$ to $b$ is defined by its\nuniversal property. For any object $c$ and any pair of morphisms:\n\\begin{align*}\n  g  & \\Colon c \\to a \\\\\n  g' & \\Colon c \\to a\n\\end{align*}\nsuch that:\n\\[m \\circ g = m \\circ g'\\]\nit must be that $g = g'$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/monomorphism.jpg}\n\\end{figure}\n\n\\noindent\nOn sets, this definition is easier to understand if we consider what it\nwould mean for a function $m$ \\emph{not} to be a monomorphism. It\nwould map two different elements of $a$ to a single element of\n$b$. We could then find two functions $g$ and\n$g'$ that differ only at those two elements. The\npostcomposition with $m$ would then mask this difference.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/notmono.jpg}\n\\end{figure}\n\n\\noindent\nThere is another way of defining a subset: using a single function\ncalled the characteristic function. It's a function $\\chi$ from the\nset $b$ to a two-element set $\\Omega$. One element of this set\nis designated as ``true'' and the other as ``false.'' This function\nassigns ``true'' to those elements of $b$ that are members of the\nsubset, and ``false'' to those that aren't.\n\nIt remains to specify what it means to designate an element of\n$\\Omega$ as ``true.'' We can use the standard trick: use a function\nfrom a singleton set to $\\Omega$. We'll call this function\n$\\mathit{true}$:\n\\[\\mathit{true} \\Colon 1 \\to \\Omega\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/true.jpg}\n\\end{figure}\n\n\\noindent\nThese definitions can be combined in such a way that they not only\ndefine what a subobject is, but also define the special object\n$\\Omega$ without talking about elements. The idea is that we want the\nmorphism $\\mathit{true}$ to represent a ``generic'' subobject. In\n$\\Set$, it picks a single-element subset from a two-element set\n$\\Omega$. This is as generic as it gets. It's clearly a proper subset,\nbecause $\\Omega$ has one more element that's \\emph{not} in that\nsubset.\n\nIn a more general setting, we define $\\mathit{true}$ to be a monomorphism\nfrom the terminal object to the \\emph{classifying object} $\\Omega$.\nA \\emph{subobject classifier} consists of $\\Omega$ together with $\\mathit{true}$.\nBut we have to define the classifying object. We need a universal\nproperty that links this object to the characteristic function. It turns\nout that, in $\\Set$, the pullback of $\\mathit{true}$ along the\ncharacteristic function $\\chi$ defines both the subset $a$\nand the injective function that embeds it in $b$. Here's the\npullback diagram:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/pullback.jpg}\n\\end{figure}\n\n\\noindent\nLet's analyze this diagram. The pullback equation is:\n\\[\\mathit{true} \\circ \\mathit{unit} = \\chi \\circ f\\]\nThe function $\\mathit{true} \\circ \\mathit{unit}$ maps every element of $a$ to\n``true.'' Therefore $f$ must map all elements of $a$ to\nthose elements of $b$ for which $\\chi$ is ``true.'' These\nare, by definition, the elements of the subset that is specified by the\ncharacteristic function $\\chi$. The image of $f$ is indeed\nthe subset in question. The universality of the pullback guarantees that\n$f$ is injective.\n\nThis pullback diagram can be used to define the classifying object in\ncategories other than $\\Set$. Such a category must have a terminal\nobject, which will let us define the monomorphism $\\mathit{true}$. It must\nalso have pullbacks --- the actual requirement is that it must have all\nfinite limits (a pullback is an example of a finite limit). Under those\nassumptions, we define the classifying object $\\Omega$ by the property\nthat, for every monomorphism $f$ there is a unique morphism\n$\\chi$ that completes the pullback diagram.\n\nLet's analyze the last statement. When we construct a pullback, we are\ngiven three objects $\\Omega$, $b$ and $1$; and two\nmorphisms, $\\mathit{true}$ and $\\chi$. The existence of a pullback\nmeans that we can find the best such object $a$, equipped with\ntwo morphisms $f$ and $\\mathit{unit}$ (the latter is uniquely\ndetermined by the definition of the terminal object), that make the\ndiagram commute.\n\nHere we are solving a different system of equations. We are solving for\n$\\Omega$ and $\\mathit{true}$ while varying both $a$ \\emph{and}\n$b$. For a given $a$ and $b$ there may or may not\nbe a monomorphism $f \\Colon a \\to b$. But if there is one, we\nwant it to be a pullback of some $\\chi$. Moreover, we want this\n$\\chi$ to be uniquely determined by $f$.\n\nWe can't say that there is a one-to-one correspondence between\nmonomorphisms $f$ and characteristic functions $\\chi$,\nbecause a pullback is only unique up to isomorphism. But remember our\nearlier definition of a subset as a family of equivalent injections. We\ncan generalize it by defining a subobject of $b$ as a family of\nequivalent monomorphisms to $b$. This family of monomorphisms is\nin one-to-one correspondence with the family of equivalent pullbacks of\nour diagram.\n\nWe can thus define a set of subobjects of $b$, $\\mathit{Sub}(b)$,\nas a family of monomorphisms, and see that it is isomorphic to the set\nof morphisms from $b$ to $\\Omega$:\n\\[\\mathit{Sub}(b) \\cong \\cat{C}(b, \\Omega)\\]\nThis happens to be a natural isomorphism of two functors. In other\nwords, $\\mathit{Sub}(-)$ is a representable (contravariant) functor whose\nrepresentation is the object $\\Omega$.\n\n\\section{Topos}\n\nA topos is a category that:\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Is Cartesian closed: It has all products, the terminal object, and\n        exponentials (defined as right adjoints to products),\n  \\item\n        Has limits for all finite diagrams,\n  \\item\n        Has a subobject classifier $\\Omega$.\n\\end{enumerate}\n\nThis set of properties makes a topos a shoe-in for $\\Set$ in most\napplications. It also has additional properties that follow from its\ndefinition. For instance, a topos has all finite colimits, including the\ninitial object.\n\nIt would be tempting to define the subobject classifier as a coproduct\n(sum) of two copies of the terminal object --that's what it is in\n$\\Set$--- but we want to be more general than that. Topoi in which\nthis is true are called Boolean.\n\n\\section{Topoi and Logic}\n\nIn set theory, a characteristic function may be interpreted as defining\na property of the elements of a set --- a \\newterm{predicate} that is true\nfor some elements and false for others. The predicate $\\mathit{isEven}$\nselects a subset of even numbers from the set of natural numbers. In a\ntopos, we can generalize the idea of a predicate to be a morphism from\nobject $a$ to $\\Omega$. This is why $\\Omega$ is sometimes\ncalled the truth object.\n\nPredicates are the building blocks of logic. A topos contains all the\nnecessary instrumentation to study logic. It has products that\ncorrespond to logical conjunctions (logical \\emph{and}), coproducts for\ndisjunctions (logical \\emph{or}), and exponentials for implications. All\nstandard axioms of logic hold in a topos except for the law of excluded\nmiddle (or, equivalently, double negation elimination). That's why the\nlogic of a topos corresponds to constructive or intuitionistic logic.\n\nIntuitionistic logic has been steadily gaining ground, finding\nunexpected support from computer science. The classical notion of\nexcluded middle is based on the belief that there is absolute truth: Any\nstatement is either true or false or, as Ancient Romans would say,\n\\emph{tertium non datur} (there is no third option). But the only way we\ncan know whether something is true or false is if we can prove or\ndisprove it. A proof is a process, a computation --- and we know that\ncomputations take time and resources. In some cases, they may never\nterminate. It doesn't make sense to claim that a statement is true if we\ncannot prove it in finite amount of time. A topos with its more nuanced\ntruth object provides a more general framework for modeling interesting\nlogics.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Show that the function $f$ that is the pullback of\n        $\\mathit{true}$ along the characteristic function must be injective.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.14/code/haskell/snippet01.hs",
    "content": "type Two = Either () ()"
  },
  {
    "path": "src/content/3.14/code/haskell/snippet02.hs",
    "content": "raise :: () -> a"
  },
  {
    "path": "src/content/3.14/code/haskell/snippet03.hs",
    "content": "type Maybe a = Either () a"
  },
  {
    "path": "src/content/3.14/code/haskell/snippet04.hs",
    "content": "data Maybe a = Nothing | Just a"
  },
  {
    "path": "src/content/3.14/code/ocaml/snippet01.ml",
    "content": "type ('a, 'b) either =\n  | Left of 'a\n  | Right of 'b\n\ntype two = (unit, unit) either\n"
  },
  {
    "path": "src/content/3.14/code/ocaml/snippet02.ml",
    "content": "val raise : unit -> 'a\n"
  },
  {
    "path": "src/content/3.14/code/ocaml/snippet03.ml",
    "content": "type 'a option = (unit, 'a) either\n"
  },
  {
    "path": "src/content/3.14/code/ocaml/snippet04.ml",
    "content": "type 'a option =\n  | None\n  | Some of 'a\n"
  },
  {
    "path": "src/content/3.14/code/reason/snippet01.re",
    "content": "type either('a, 'b) =\n  | Left('a)\n  | Right('b);\n\ntype two = either(unit, unit);\n"
  },
  {
    "path": "src/content/3.14/code/reason/snippet02.re",
    "content": "let raise: unit => 'a;\n"
  },
  {
    "path": "src/content/3.14/code/reason/snippet03.re",
    "content": "type option('a) = either(unit, 'a);\n"
  },
  {
    "path": "src/content/3.14/code/reason/snippet04.re",
    "content": "type option('a) =\n  | None\n  | Some('a);\n"
  },
  {
    "path": "src/content/3.14/code/scala/snippet01.scala",
    "content": "type Two = Either[Unit, Unit]"
  },
  {
    "path": "src/content/3.14/code/scala/snippet02.scala",
    "content": "def raise: Unit => A"
  },
  {
    "path": "src/content/3.14/code/scala/snippet03.scala",
    "content": "type Option[A] = Either[Unit, A]"
  },
  {
    "path": "src/content/3.14/code/scala/snippet04.scala",
    "content": "sealed trait Option[+A]\ncase object None extends Option[Nothing]\ncase class Some[A](a: A) extends Option[A]"
  },
  {
    "path": "src/content/3.14/lawvere-theories.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{N}{owadays you can't} talk about functional programming without mentioning\nmonads. But there is an alternative universe in which, by chance,\nEugenio Moggi turned his attention to Lawvere theories rather than\nmonads. Let's explore that universe.\n\n\\section{Universal Algebra}\n\nThere are many ways of describing algebras at various levels of\nabstraction. We try to find a general language to describe things like\nmonoids, groups, or rings. At the simplest level, all these\nconstructions define \\emph{operations} on elements of a set, plus some\n\\emph{laws} that must be satisfied by these operations. For instance, a\nmonoid can be defined in terms of a binary operation that is\nassociative. We also have a unit element and unit laws. But with a\nlittle bit of imagination we can turn the unit element to a nullary\noperation --- an operation that takes no arguments and returns a special\nelement of the set. If we want to talk about groups, we add a unary\noperator that takes an element and returns its inverse. There are\ncorresponding left and right inverse laws to go with it. A ring defines\ntwo binary operators plus some more laws. And so on.\n\nThe big picture is that an algebra is defined by a set of $n$-ary\noperations for various values of $n$, and a set of equational identities.\nThese identities are all universally quantified. The associativity\nequation must be satisfied for all possible combinations of three\nelements, and so on.\n\nIncidentally, this eliminates fields from consideration, for the simple\nreason that zero (unit with respect to addition) has no inverse with\nrespect to multiplication. The inverse law for a field can't be\nuniversally quantified.\n\nThis definition of a universal algebra can be extended to categories\nother than $\\Set$, if we replace operations (functions) with\nmorphisms. Instead of a set, we select an object $a$ (called a\ngeneric object). A unary operation is just an endomorphism of\n$a$. But what about other arities (\\newterm{arity} is the number of\narguments for a given operation)? A binary operation (arity 2) can be\ndefined as a morphism from the product $a\\times{}a$ back to $a$.\nA general $n$-ary operation is a morphism from the $n^\\text{th}$ power of\n$a$ to $a$:\n\\[\\alpha_n \\Colon a^n \\to a\\]\nA nullary operation is a morphism from the terminal object (the zeroth\npower of $a$). So all we need in order to define any algebra is a\ncategory whose objects are powers of one special object $a$. The\nspecific algebra is encoded in the hom-sets of this category. This is a\nLawvere theory in a nutshell.\n\nThe derivation of Lawvere theories goes through many steps, so here's\nthe roadmap:\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Category of finite sets $\\cat{FinSet}$.\n  \\item\n        Its skeleton $\\cat{F}$.\n  \\item\n        Its opposite $\\Fop$.\n  \\item\n        Lawvere theory $\\cat{L}$: an object in the category $\\cat{Law}$.\n  \\item\n        Model $M$ of a Lawvere category: an object in the category\\\\\n        $\\cat{Mod}(\\cat{L}, \\Set)$.\n\\end{enumerate}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.8\\textwidth]{images/lawvere1.png}\n\\end{figure}\n\n\\section{Lawvere Theories}\n\nAll Lawvere theories share a common backbone. All objects in a Lawvere\ntheory are generated from just one object using products (really, just\npowers). But how do we define these products in a general category? It\nturns out that we can define products using a mapping from a simpler\ncategory. In fact this simpler category may define coproducts instead of\nproducts, and we'll use a \\emph{contravariant} functor to embed them in\nour target category. A contravariant functor turns coproducts into\nproducts and injections to projections.\n\nThe natural choice for the backbone of a Lawvere category is the\ncategory of finite sets, $\\cat{FinSet}$. It contains the empty set\n$\\varnothing$, a singleton set $1$, a two-element set $2$,\nand so on. All objects in this category can be generated from the\nsingleton set using coproducts (treating the empty set as a special case\nof a nullary coproduct). For instance, a two-element set is a sum of two\nsingletons, $2 = 1 + 1$, as expressed in Haskell:\n\n\\src{snippet01}\nHowever, even though it's natural to think that there's only one empty\nset, there may be many distinct singleton sets. In particular, the set\n$1 + \\varnothing$ is different from the set $\\varnothing + 1$, and\ndifferent from $1$ --- even though they are all isomorphic. The\ncoproduct in the category of sets is not associative. We can remedy that\nsituation by building a category that identifies all isomorphic sets.\nSuch a category is called a \\newterm{skeleton}. In other words, the\nbackbone of any Lawvere theory is the skeleton $\\cat{F}$ of\n$\\cat{FinSet}$. The objects in this category can be identified with\nnatural numbers (including zero) that correspond to the element count in\n$\\cat{FinSet}$. Coproduct plays the role of addition. Morphisms in\n$\\cat{F}$ correspond to functions between finite sets. For instance,\nthere is a unique morphism from $\\varnothing$ to $n$ (empty set\nbeing the initial object), no morphisms from $n$ to $\\varnothing$\n(except $\\varnothing \\to \\varnothing$), $n$ morphisms from $1$ to\n$n$ (the injections), one morphism from $n$ to $1$,\nand so on. Here, $n$ denotes an object in $\\cat{F}$\ncorresponding to all $n$-element sets in $\\cat{FinSet}$ that have been\nidentified through isomorphisms.\n\nUsing the category $\\cat{F}$ we can formally define a \\newterm{Lawvere\n  theory} as a category $\\cat{L}$ equipped with a special functor:\n\\[I_{\\cat{L}} \\Colon \\Fop \\to \\cat{L}\\]\nThis functor must be a bijection on objects and it must preserve finite\nproducts (products in $\\Fop$ are the same as\ncoproducts in $\\cat{F}$):\n\\[I_{\\cat{L}} (m\\times{}n) = I_{\\cat{L}} m\\times{}I_{\\cat{L}} n\\]\nYou may sometimes see this functor characterized as identity-on-objects,\nwhich means that the objects in $\\cat{F}$ and $\\cat{L}$ are the same.\nWe will therefore use the same names for them --- we'll denote them by\nnatural numbers. Keep in mind though that objects in $\\cat{F}$ are not\nthe same as sets (they are classes of isomorphic sets).\n\nThe hom-sets in $\\cat{L}$ are, in general, richer than those in\n$\\Fop$. They may contain morphisms other than\nthe ones corresponding to functions in $\\cat{FinSet}$ (the latter are\nsometimes called \\newterm{basic product operations}). Equational laws of a\nLawvere theory are encoded in those morphisms.\n\nThe key observation is that the singleton set $1$ in $\\cat{F}$\nis mapped to some object that we also call $1$ in $\\cat{L}$, and\nall the other objects in $\\cat{L}$ are automatically powers of this\nobject. For instance, the two-element set $2$ in $\\cat{F}$ is\nthe coproduct $1 + 1$, so it must be mapped to a product\n$1 \\times 1$ (or $1^2$) in $\\cat{L}$. In this sense, the category\n$\\cat{F}$ behaves like the logarithm of $\\cat{L}$.\n\nAmong morphisms in $\\cat{L}$ we have those transferred by the functor\n$I_{\\cat{L}}$ from $\\cat{F}$. They play a structural role in $\\cat{L}$. In\nparticular coproduct injections $i_k$ become product projections\n$p_k$. A useful intuition is to imagine the projection:\n\\[p_k \\Colon 1^n \\to 1\\]\nas the prototype for a function of $n$ variables that ignores all but the\n$k^\\text{th}$ variable. Conversely, constant morphisms $n \\to 1$\nin $\\cat{F}$ become diagonal morphisms $1 \\to 1^n$ in\n$\\cat{L}$. They correspond to duplication of variables.\n\nThe interesting morphisms in $\\cat{L}$ are the ones that define $n$-ary\noperations other than projections. It's those morphisms that distinguish\none Lawvere theory from another. These are the multiplications, the\nadditions, the selections of unit elements, and so on, that define the\nalgebra. But to make $\\cat{L}$ a full category, we also need compound\noperations $n \\to m$ (or, equivalently,\n$1^n \\to 1^m$). Because of the simple structure of\nthe category, they turn out to be products of simpler morphisms of the\ntype $n \\to 1$. This is a generalization of the\nstatement that a function that returns a product is a product of\nfunctions; as we've seen earlier, the hom-functor is continuous.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.8\\textwidth]{images/lawvere1.png}\n  \\caption{Lawvere theory $\\cat{L}$ is based on $\\Fop$, from which\n    it inherits the ``boring'' morphisms that define the products. It adds\n    the ``interesting'' morphisms that describe the $n$-ary operations (dotted\n    arrows).}\n\\end{figure}\n\nLawvere theories form a category $\\cat{Law}$, in which morphisms are\nfunctors that preserve finite products and commute with the functors\n$I$. Given two such theories, $(\\cat{L}, I_{\\cat{L}})$ and\n$(\\cat{L'}, I'_{\\cat{L'}})$, a morphism between them is a\nfunctor $F \\Colon \\cat{L} \\to \\cat{L'}$ such that:\n\\begin{gather*}\n  F (m \\times n) = F m \\times F n \\\\\n  F \\circ I_{\\cat{L}} = I'_{\\cat{L'}}\n\\end{gather*}\nMorphisms between Lawvere theories encapsulate the idea of the\ninterpretation of one theory inside another. For instance, group\nmultiplication may be interpreted as monoid multiplication if we ignore\ninverses.\n\nThe simplest trivial example of a Lawvere category is\n$\\Fop$ itself (corresponding to the choice of\nthe identity functor for $I_{\\cat{L}}$). This Lawvere theory that has no\noperations or laws happens to be the initial object in $\\cat{Law}$.\n\nAt this point it would be very helpful to present a non-trivial example\nof a Lawvere theory, but it would be hard to explain it without first\nunderstanding what models are.\n\n\\section{Models of Lawvere Theories}\n\nThe key to understand Lawvere theories is to realize that one such\ntheory generalizes a lot of individual algebras that share the same\nstructure. For instance, the Lawvere theory of monoids describes the\nessence of being a monoid. It must be valid for all monoids. A\nparticular monoid becomes a model of such a theory. A model is defined\nas a functor from the Lawvere theory $\\cat{L}$ to the category of sets\n$\\Set$. (There are generalizations of Lawvere theories that use\nother categories for models but here I'll just concentrate on\n$\\Set$.) Since the structure of $\\cat{L}$ depends heavily on\nproducts, we require that such a functor preserve finite products. A\nmodel of $\\cat{L}$, also called the algebra over the Lawvere theory\n$\\cat{L}$, is therefore defined by a functor:\n\\begin{gather*}\n  M \\Colon \\cat{L} \\to \\Set \\\\\n  M (a \\times b) \\cong M a \\times M b\n\\end{gather*}\nNotice that we require the preservation of products only \\emph{up to\n  isomorphism}. This is very important, because strict preservation of\nproducts would eliminate most interesting theories.\n\nThe preservation of products by models means that the image of\n$M$ in $\\Set$ is a sequence of sets generated by powers of\nthe set $M 1$ --- the image of the object $1$ from\n$\\cat{L}$. Let's call this set $a$. (This set is sometimes\ncalled a \\emph{sort}, and such an algebra is called \\newterm{single-sorted}. There\nexist generalizations of Lawvere theories to multi-sorted algebras.) In\nparticular, binary operations from $\\cat{L}$ are mapped to functions:\n\\[a \\times a \\to a\\]\nAs with any functor, it's possible that multiple morphisms in $\\cat{L}$\nare collapsed to the same function in $\\Set$.\n\nIncidentally, the fact that all laws are universally quantified\nequalities means that every Lawvere theory has a trivial model: a\nconstant functor mapping all objects to the singleton set, and all morphisms\nto the identity function on it.\n\nA general morphism in $\\cat{L}$ of the form\n$m \\to n$ is mapped to a function:\n\\[a^m \\to a^n\\]\nIf we have two different models, $M$ and $N$, a natural\ntransformation between them is a family of functions indexed by\n$n$:\n\\[\\mu_n \\Colon M n \\to N n\\]\nor, equivalently:\n\\[\\mu_n \\Colon a^n \\to b^n\\]\nwhere $b = N 1$.\n\nNotice that the naturality condition guarantees the preservation of\n$n$-ary operations:\n\\[N f \\circ \\mu_n = \\mu_1 \\circ M f\\]\nwhere $f \\Colon n \\to 1$ is an $n$-ary operation in\n$\\cat{L}$.\n\nThe functors that define models form a category of models,\n$\\cat{Mod}(\\cat{L}, \\Set)$, with natural transformations as morphisms.\n\nConsider a model for the trivial Lawvere category\n$\\Fop$. Such a model is completely determined by\nits value at $1$, $M 1$. Since $M 1$ can be any\nset, there are as many of these models as there are sets in\n$\\Set$. Moreover, every morphism in $\\cat{Mod}(\\Fop, \\Set)$ (a\nnatural transformation between functors $M$ and $N$) is\nuniquely determined by its component at $1$. Conversely, every\nfunction $M 1 \\to N 1$ induces a natural\ntransformation between the two models $M$ and $N$.\nTherefore $\\cat{Mod}(\\Fop, \\Set)$ is equivalent to $\\Set$.\n\n\\section{The Theory of Monoids}\n\nThe simplest nontrivial example of a Lawvere theory describes the\nstructure of monoids. It is a single theory that distills the structure\nof all possible monoids, in the sense that the models of this theory\nspan the whole category $\\cat{Mon}$ of monoids. We've already seen a\n\\hyperref[free-monoids]{universal\n  construction}, which showed that every monoid can be obtained from an\nappropriate free monoid by identifying a subset of morphisms. So a\nsingle free monoid already generalizes a whole lot of monoids. There\nare, however, infinitely many free monoids. The Lawvere theory for\nmonoids $\\cat{L}_{\\cat{Mon}}$ combines all of them in one\nelegant construction.\n\nEvery monoid must have a unit, so we have to have a special morphism\n$\\eta$ in $\\cat{L}_{\\cat{Mon}}$ that goes from $0$ to\n$1$. Notice that there can be no corresponding morphism in\n$\\cat{F}$. Such a morphism would go in the opposite direction, from\n$1$ to $0$ which, in $\\cat{FinSet}$, would be a function\nfrom the singleton set to the empty set. No such function exists.\n\nNext, consider morphisms $2 \\to 1$, members of\n$\\cat{L}_{\\cat{Mon}}(2, 1)$, which must contain prototypes of all binary\noperations. When constructing models in $\\cat{Mod}(\\cat{L}_{\\cat{Mon}}, \\Set)$, these\nmorphisms will be mapped to functions from the Cartesian product\n$M 1 \\times M 1$ to $M 1$. In other words, functions of\ntwo arguments.\n\nThe question is: how many functions of two arguments can one implement\nusing only the monoidal operator. Let's call the two arguments\n$a$ and $b$. There is one function that ignores both\narguments and returns the monoidal unit. Then there are two projections\nthat return $a$ and $b$, respectively. They are followed\nby functions that return $ab$, $ba$, $aa$,\n$bb$, $aab$, and so on\\ldots{} In fact there are as many\nsuch functions of two arguments as there are elements in the free monoid\nwith generators $a$ and $b$. Notice that\n$\\cat{L}_{\\cat{Mon}}(2, 1)$ must contain all those morphisms because one of the\nmodels is the free monoid. In a free monoid they correspond to distinct\nfunctions. Other models may collapse multiple morphisms in\n$\\cat{L}_{\\cat{Mon}}(2, 1)$ down to a single function, but not the free monoid.\n\nIf we denote the free monoid with $n$ generators $n^*$, we may\nidentify the hom-set $\\cat{L}(2, 1)$ with the hom-set\n$\\cat{Mon}(1^*, 2^*)$ in $\\cat{Mon}$, the category of monoids. In\ngeneral, we pick $\\cat{L}_{\\cat{Mon}}(m, n)$ to be $\\cat{Mon}(n^*, m^*)$. In\nother words, the category $\\cat{L}_{\\cat{Mon}}$ is the opposite of the category\nof free monoids.\n\nThe category of \\emph{models} of the Lawvere theory for monoids,\\\\\n$\\cat{Mod}(\\cat{L}_{\\cat{Mon}}, \\Set)$, is equivalent to the category of all monoids,\n$\\cat{Mon}$.\n\n\\section{Lawvere Theories and Monads}\n\nAs you may remember, algebraic theories can be described using monads\n--- in particular\n\\hyperref[algebras-for-monads]{algebras\n  for monads}. It should be no surprise then that there is a connection\nbetween Lawvere theories and monads.\n\nFirst, let's see how a Lawvere theory induces a monad. It does it\nthrough an\n\\hyperref[free-forgetful-adjunctions]{adjunction}\nbetween a forgetful functor and a free functor. The forgetful functor\n$U$ assigns a set to each model. This set is given by evaluating\nthe functor $M$ from $\\cat{Mod}(\\cat{L}, \\Set)$ at the object $1$ in\n$\\cat{L}$.\n\nAnother way of deriving $U$ is by exploiting the fact that\n$\\Fop$ is the initial object in $\\cat{Law}$. It\nmeans that, for any Lawvere theory $\\cat{L}$, there is a unique\nfunctor $\\Fop \\to \\cat{L}$. This functor induces the\nopposite functor on models (since models are functors \\emph{from}\ntheories to sets):\n\\[\\cat{Mod}(\\cat{L}, \\Set) \\to \\cat{Mod}(\\Fop, \\Set)\\]\nBut, as we discussed, the category of models of\n$\\Fop$ is equivalent to $\\Set$, so we get\nthe forgetful functor:\n\\[U \\Colon \\cat{Mod}(\\cat{L}, \\Set) \\to \\Set\\]\nIt can be shown that so defined $U$ always has a left adjoint,\nthe free functor $F$.\n\nThis is easily seen for finite sets. The free functor $F$\nproduces free algebras. A free algebra is a particular model in\n$\\cat{Mod}(\\cat{L}, \\Set)$ that is generated from a finite set of generators\n$n$. We can implement $F$ as the representable functor:\n\\[\\cat{L}(n, -) \\Colon \\cat{L} \\to \\Set\\]\nTo show that it's indeed free, all we have to do is to prove that it's a\nleft adjoint to the forgetful functor:\n\\[\\cat{Mod}(\\cat{L}, \\Set)(\\cat{L}(n, -), M) \\cong \\Set(n, U(M))\\]\nLet's simplify the right hand side:\n\\[\\Set(n, U(M)) \\cong \\Set(n, M 1) \\cong (M 1)^n \\cong M n\\]\n(I used the fact that a set of morphisms is isomorphic to the\nexponential which, in this case, is just the iterated product.) The\nadjunction is the result of the Yoneda lemma:\n\\[[\\cat{L}, \\Set](\\cat{L}(n, -), M) \\cong M n\\]\nTogether, the forgetful and the free functor define a\n\\hyperref[monads-categorically]{monad}\n$T = U \\circ F$ on $\\Set$. Thus every Lawvere theory generates\na monad.\n\nIt turns out that the category of\n\\hyperref[algebras-for-monads]{algebras\n  for this monad} is equivalent to the category of models.\n\nYou may recall that monad algebras define ways to evaluate expressions\nthat are formed using monads. A Lawvere theory defines $n$-ary operations\nthat can be used to generate expressions. Models provide means to\nevaluate these expressions.\n\nThe connection between monads and Lawvere theories doesn't go both ways,\nthough. Only finitary monads lead to Lawvere theories. A finitary monad\nis based on a finitary functor. A finitary functor on $\\Set$ is\nfully determined by its action on finite sets. Its action on an\narbitrary set $a$ can be evaluated using the following coend:\n\\[F a = \\int^n a^n \\times (F n)\\]\nSince the coend generalizes a coproduct, or a sum, this formula is a\ngeneralization of a power series expansion. Or we can use the intuition\nthat a functor is a generalized container. In that case a finitary\ncontainer of $a$s can be described as a sum of shapes and\ncontents. Here, $F n$ is a set of shapes for storing $n$ elements,\nand the contents is an $n$-tuple of elements, itself an element of\n$a^n$. For instance, a list (as a functor) is finitary, with one\nshape for every arity. A tree has more shapes per arity, and so on.\n\nFirst off, all monads that are generated from Lawvere theories are\nfinitary and they can be expressed as coends:\n\\[T_{\\cat{L}} a = \\int^n a^n \\times \\cat{L}(n, 1)\\]\nConversely, given any finitary monad $T$ on $\\Set$, we can\nconstruct a Lawvere theory. We start by constructing a Kleisli category\nfor $T$. As you may remember, a morphism in a Kleisli category\nfrom $a$ to $b$ is given by a morphism in the underlying\ncategory:\n\\[a \\to T b\\]\nWhen restricted to finite sets, this becomes:\n\\[m \\to T n\\]\nThe category opposite to this Kleisli category,\n$\\cat{Kl}^\\mathit{op}_{T}$, restricted to finite\nsets, is the Lawvere theory in question. In particular, the hom-set\n$\\cat{L}(n, 1)$ that describes $n$-ary operations in $\\cat{L}$ is given\nby the hom-set $\\cat{Kl}_{T}(1, n)$.\n\nIt turns out that most monads that we encounter in programming are\nfinitary, with the notable exception of the continuation monad. It is\npossible to extend the notion of Lawvere theory beyond finitary\noperations.\n\n\\section{Monads as Coends}\n\nLet's explore the coend formula in more detail.\n\\[T_{\\cat{L}} a = \\int^n a^n \\times \\cat{L}(n, 1)\\]\nTo begin with, this coend is taken over a profunctor $P$ in\n$\\cat{F}$ defined as:\n\\[P n m = a^n \\times \\cat{L}(m, 1)\\]\nThis profunctor is contravariant in the first argument, $n$.\nConsider how it lifts morphisms. A morphism in $\\cat{FinSet}$ is a\nmapping of finite sets $f \\Colon m \\to n$. Such a\nmapping describes a selection of $m$ elements from an $n$-element set\n(repetitions are allowed). It can be lifted to the mapping of powers of\n$a$, namely (notice the direction):\n\\[a^n \\to a^m\\]\nThe lifting simply selects $m$ elements from a tuple of $n$ elements\\\\\n$(a_1, a_2, \\ldots{}, a_n)$ (possibly with repetitions).\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/liftpower.png}\n\\end{figure}\n\n\\noindent\nFor instance, let's take $f_k \\Colon 1 \\to n$ --- a\nselection of the $k^\\text{th}$ element from an $n$-element set. It lifts to\na function that takes a $n$-tuple of elements of $a$ and returns\nthe $k^\\text{th}$ one.\n\nOr let's take $f \\Colon m \\to 1$ --- a constant\nfunction that maps all $m$ elements to one. Its lifting is a function that\ntakes a single element of $a$ and duplicates it $m$ times:\n\\[\\lambda{}x \\to (\\underbrace{x, x, \\ldots{}, x}_{m})\\]\nYou might notice that it's not immediately obvious that the profunctor\nin question is covariant in the second argument. The hom-functor\n$\\cat{L}(m, 1)$ is actually contravariant in $m$. However, we\nare taking the coend not in the category $\\cat{L}$ but in the category\n$\\cat{F}$. The coend variable $n$ goes over finite sets (or the\nskeletons of such). The category $\\cat{L}$ contains the opposite of\n$\\cat{F}$, so a morphism $m \\to n$ in $\\cat{F}$\nis a member of $\\cat{L}(n, m)$ in $\\cat{L}$ (the embedding is given\nby the functor $I_{\\cat{L}}$).\n\nLet's check the functoriality of $\\cat{L}(m, 1)$ as a functor from\n$\\cat{F}$ to $\\Set$. We want to lift a function\n$f \\Colon m \\to n$, so our goal is to implement a\nfunction from $\\cat{L}(m, 1)$ to $\\cat{L}(n, 1)$. Corresponding to\nthe function $f$ there is a morphism in $\\cat{L}$ from\n$n$ to $m$ (notice the direction). Precomposing this\nmorphism with $\\cat{L}(m, 1)$ gives us a subset of\n$\\cat{L}(n, 1)$.\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}[column sep=large]\n    \\cat{L}(m, 1) \\arrow[r] & \\cat{L}(n, 1)\\\\\n    {}^m \\bullet \\arrow[r, \"f\"'] & \\bullet^n\n  \\end{tikzcd}\n\\end{figure}\n\n\\noindent\nNotice that, by lifting a function $1 \\to n$ we can go\nfrom $\\cat{L}(1, 1)$ to $\\cat{L}(n, 1)$. We'll use this fact later\non.\n\nThe product of a contravariant functor $a^n$ and a covariant\nfunctor $\\cat{L}(m, 1)$ is a profunctor\n$\\Fop \\times \\cat{F} \\to \\Set$. Remember that a coend can be defined\nas a coproduct (disjoint sum) of all the diagonal members of a\nprofunctor, in which some elements are identified. The identifications\ncorrespond to cowedge conditions.\n\nHere, the coend starts as the disjoint sum of sets\n$a^n \\times \\cat{L}(n, 1)$ over all $n$s. The identifications can\nbe generated by expressing the\n\\hyperref[ends-and-coends]{coend as\n  a coequalizer}. We start with an off-diagonal term\n$a^n \\times \\cat{L}(m, 1)$. To get to the diagonal, we can apply a\nmorphism $f \\Colon m \\to n$ either to the first or\nthe second component of the product. The two results are then\nidentified.\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}\n    & a^n \\times \\cat{L}(m, 1)\n    \\arrow[dl, \"\\langle f {,} \\id \\rangle\"']\n    \\arrow[dr, \"\\langle \\id {,} f \\rangle\"]\n    & \\\\\n    a^m \\times \\cat{L}(m, 1)\n    & \\scalebox{2.5}[1]{\\sim}\n    & a^n \\times \\cat{L}(n, 1) \\\\\n    & f \\Colon m \\to n &\n  \\end{tikzcd}\n\\end{figure}\n\n\\noindent\nI have shown before that the lifting of\n$f \\Colon 1 \\to n$ results in these two\ntransformations:\n\\[a^n \\to a\\]\nand:\n\\[\\cat{L}(1, 1) \\to \\cat{L}(n, 1)\\]\nTherefore, starting from $a^n \\times \\cat{L}(1, 1)$ we can reach both:\n\\[a \\times \\cat{L}(1, 1)\\]\nwhen we lift $\\langle f, \\id \\rangle$ and:\n\\[a^n \\times \\cat{L}(n, 1)\\]\nwhen we lift $\\langle \\id, f \\rangle$. This doesn't\nmean, however, that all elements of $a^n \\times \\cat{L}(n, 1)$ can be\nidentified with $a \\times \\cat{L}(1, 1)$. That's because not all elements\nof $\\cat{L}(n, 1)$ can be reached from $\\cat{L}(1, 1)$. Remember\nthat we can only lift morphisms from $\\cat{F}$. A non-trivial $n$-ary\noperation in $\\cat{L}$ cannot be constructed by lifting a morphism\n$f \\Colon 1 \\to n$.\n\nIn other words, we can only identify all addends in the coend formula\nfor which $\\cat{L}(n, 1)$ can be reached from $\\cat{L}(1, 1)$\nthrough the application of basic morphisms. They are all equivalent to\n$a \\times \\cat{L}(1, 1)$. Basic morphisms are the ones that are images of\nmorphisms in $\\cat{F}$.\n\nLet's see how this works in the simplest case of the Lawvere theory, the\n$\\Fop$ itself. In such a theory, every\n$\\cat{L}(n, 1)$ can be reached from $\\cat{L}(1, 1)$. This is because\n$\\cat{L}(1, 1)$ is a singleton containing just the identity morphism,\nand $\\cat{L}(n, 1)$ only contains morphisms corresponding to\ninjections $1 \\to n$ in $\\cat{F}$, which \\emph{are}\nbasic morphisms. Therefore all the addends in the coproduct are\nequivalent and we get:\n\\[T a = a \\times \\cat{L}(1, 1) = a\\]\nwhich is the identity monad.\n\n\\section{Lawvere Theory of Side Effects}\n\nSince there is such a strong connection between monads and Lawvere\ntheories, it's natural to ask the question if Lawvere theories could be\nused in programming as an alternative to monads. The major problem with\nmonads is that they don't compose nicely. There is no generic recipe for\nbuilding monad transformers. Lawvere theories have an advantage in this\narea: they can be composed using coproducts and tensor products. On the\nother hand, only finitary monads can be easily converted to Lawvere\ntheories. The outlier here is the continuation monad. There is ongoing\nresearch in this area (see bibliography).\n\nTo give you a taste of how a Lawvere theory can be used to describe side\neffects, I'll discuss the simple case of exceptions that are\ntraditionally implemented using the \\code{Maybe} monad.\n\nThe \\code{Maybe} monad is generated by the Lawvere theory with a\nsingle nullary operation $0 \\to 1$. A model of this\ntheory is a functor that maps $1$ to some set $a$, and\nmaps the nullary operation to a function:\n\n\\src{snippet02}\nWe can recover the \\code{Maybe} monad using the coend formula. Let's\nconsider what the addition of the nullary operation does to the hom-sets\n$\\cat{L}(n, 1)$. Besides creating a new element in $\\cat{L}(0, 1)$ (which is\nabsent from $\\Fop$), it also adds new morphisms\nto $\\cat{L}(n, 1)$. These are the results of composing morphism of the\ntype $n \\to 0$ with our $0 \\to 1$.\nSuch contributions are all identified with $a^0 \\times \\cat{L}(0, 1)$ in\nthe coend formula, because they can be obtained from:\n\\[a^n \\times \\cat{L}(0, 1)\\]\nby lifting $0 \\to n$ in two different ways.\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}\n    & a^n \\times \\cat{L}(0, 1)\n    \\arrow[dl, \"\\langle f {,} \\id \\rangle\"']\n    \\arrow[dr, \"\\langle \\id {,} f \\rangle\"]\n    & \\\\\n    a^0 \\times \\cat{L}(0, 1)\n    & \\scalebox{2.5}[1]{\\sim}\n    & a^n \\times \\cat{L}(n, 1) \\\\\n    & f \\Colon 0 \\to n &\n  \\end{tikzcd}\n\\end{figure}\n\n\\noindent\nThe coend reduces to:\n\\[T_{\\cat{L}} a = a^0 + a^1\\]\nor, using Haskell notation:\n\n\\src{snippet03}\nwhich is equivalent to:\n\n\\src{snippet04}\nNotice that this Lawvere theory only supports the raising of exceptions,\nnot their handling.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Enumerate all morphisms between $2$ and $3$ in $\\cat{F}$ (the skeleton of\n        $\\cat{FinSet}$).\n  \\item\n        Show that the category of models for the Lawvere theory of monoids is\n        equivalent to the category of monad algebras for the list monad.\n  \\item\n        The Lawvere theory of monoids generates the list monad. Show that its\n        binary operations can be generated using the corresponding Kleisli\n        arrows.\n  \\item\n        $\\cat{FinSet}$ is a subcategory of $\\Set$ and there is a\n        functor that embeds it in $\\Set$. Any functor on $\\Set$\n        can be restricted to $\\cat{FinSet}$. Show that a finitary functor is\n        the left Kan extension of its own restriction.\n\\end{enumerate}\n\n\\section{Further Reading}\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        \\urlref{http://www.tac.mta.ca/tac/reprints/articles/5/tr5.pdf}{Functorial Semantics of Algebraic Theories}, F. William Lawvere\n  \\item\n        \\urlref{http://homepages.inf.ed.ac.uk/gdp/publications/Comp_Eff_Monads.pdf}{Notions of computation determine monads}, Gordon Plotkin and John Power\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.15/monads-monoids-and-categories.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{T}{here is no good place} to end a book on category theory. There's always\nmore to learn. Category theory is a vast subject. At the same time, it's\nobvious that the same themes, concepts, and patterns keep showing up\nover and over again. There is a saying that all concepts are Kan\nextensions and, indeed, you can use Kan extensions to derive limits,\ncolimits, adjunctions, monads, the Yoneda lemma, and much more. The\nnotion of a category itself arises at all levels of abstraction, and so\ndoes the concept of a monoid and a monad. Which one is the most basic?\nAs it turns out they are all interrelated, one leading to another in a\nnever-ending cycle of abstractions. I decided that showing these\ninterconnections might be a good way to end this book.\n\n\\section{Bicategories}\n\nOne of the most difficult aspects of category theory is the constant\nswitching of perspectives. Take the category of sets, for instance. We\nare used to defining sets in terms of elements. An empty set has no\nelements. A singleton set has one element. A Cartesian product of two\nsets is a set of pairs, and so on. But when talking about the category\n$\\Set$ I asked you to forget about the contents of sets and\ninstead concentrate on morphisms (arrows) between them. You were\nallowed, from time to time, to peek under the covers to see what a\nparticular universal construction in $\\Set$ described in terms of\nelements. The terminal object turned out to be a set with one element,\nand so on. But these were just sanity checks.\n\nA functor is defined as a mapping of categories. It's natural to\nconsider a mapping as a morphism in a category. A functor turned out to\nbe a morphism in the category of categories (small categories, if we\nwant to avoid questions about size). By treating a functor as an arrow,\nwe forfeit the information about its action on the internals of a\ncategory (its objects and morphisms), just like we forfeit the\ninformation about the action of a function on elements of a set when we\ntreat it as an arrow in $\\Set$. But functors between any two\ncategories also form a category. This time you are asked to consider\nsomething that was an arrow in one category to be an object in another.\nIn a functor category functors are objects and natural transformations\nare morphisms. We have discovered that the same thing can be an arrow in\none category and an object in another. The naive view of objects as\nnouns and arrows as verbs doesn't hold.\n\nInstead of switching between two views, we can try to merge them into\none. This is how we get the concept of a $\\cat{2}$-category, in which objects\nare called $0$-cells, morphisms are $1$-cells, and morphisms between\nmorphisms are $2$-cells.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/twocat.png}\n  \\caption{$0$-cells $a, b$; $1$-cells $f, g$; and a $2$-cell $\\alpha$.}\n\\end{figure}\n\n\\noindent\nThe category of categories $\\Cat$ is an immediate example. We have\ncategories as $0$-cells, functors as $1$-cells, and natural transformations\nas $2$-cells. The laws of a $\\cat{2}$-category tell us that $1$-cells between any\ntwo $0$-cells form a category (in other words, $\\cat{C}(a, b)$ is a\nhom-category rather than a hom-set). This fits nicely with our earlier\nassertion that functors between any two categories form a functor\ncategory.\n\nIn particular, $1$-cells from any $0$-cell back to itself also form a\ncategory, the hom-category $\\cat{C}(a, a)$; but that category has even\nmore structure. Members of $\\cat{C}(a, a)$ can be viewed as arrows in\n$\\cat{C}$ or as objects in $\\cat{C}(a, a)$. As arrows, they can be\ncomposed with each other. But when we look at them as objects, the\ncomposition becomes a mapping from a pair of objects to an object. In\nfact it looks very much like a product --- a tensor product to be\nprecise. This tensor product has a unit: the identity $1$-cell. It turns\nout that, in any $\\cat{2}$-category, a hom-category $\\cat{C}(a, a)$ is\nautomatically a monoidal category with the tensor product defined as\ncomposition of $1$-cells. Associativity and unit laws simply fall out from\nthe corresponding category laws.\n\nLet's see what this means in our canonical example of a $\\cat{2}$-category\n$\\Cat$. The hom-category $\\Cat(a, a)$ is the category of\nendofunctors on $a$. Endofunctor composition plays the role of a\ntensor product in it. The identity functor is the unit with respect to\nthis product. We've seen before that endofunctors form a monoidal\ncategory (we used this fact in the definition of a monad), but now we\nsee that this is a more general phenomenon: endo-$1$-cells in any\n$\\cat{2}$-category form a monoidal category. We'll come back to it later when we\ngeneralize monads.\n\nYou might recall that, in a general monoidal category, we did not insist\non the monoid laws being satisfied on the nose. It was often enough for\nthe unit laws and the associativity laws to be satisfied up to\nisomorphism. In a $\\cat{2}$-category, monoidal laws in $\\cat{C}(a, a)$ follow\nfrom composition laws for $1$-cells. These laws are strict, so we will\nalways get a strict monoidal category. It is, however, possible to relax\nthese laws as well. We can say, for instance, that a composition of the\nidentity $1$-cell $\\idarrow[a]$ with another $1$-cell,\n$f \\Colon a \\to b$, is isomorphic, rather than equal,\nto $f$. Isomorphism of $1$-cells is defined using $2$-cells. In other\nwords, there is a $2$-cell:\n\\[\\rho \\Colon f \\circ \\idarrow[a] \\to f\\]\nthat has an inverse.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/bicat.png}\n  \\caption{Identity law in a bicategory holds up to isomorphism (an invertible\n    $2$-cell $\\rho$).}\n\\end{figure}\n\n\\noindent\nWe can do the same for the left identity and associativity laws. This\nkind of relaxed $\\cat{2}$-category is called a bicategory (there are some\nadditional coherency laws, which I will omit here).\n\nAs expected, endo-$1$-cells in a bicategory form a general monoidal\ncategory with non-strict laws.\n\nAn interesting example of a bicategory is the category of spans. A span\nbetween two objects $a$ and $b$ is an object $x$\nand a pair of morphisms:\n\\begin{gather*}\n  f \\Colon x \\to a \\\\\n  g \\Colon x \\to b\n\\end{gather*}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.35\\textwidth]{images/span.png}\n\\end{figure}\n\n\\noindent\nYou might recall that we used spans in the definition of a categorical\nproduct. Here, we want to look at spans as $1$-cells in a bicategory. The\nfirst step is to define a composition of spans. Suppose that we have an\nadjoining span:\n\\begin{gather*}\n  f' \\Colon y \\to b \\\\\n  g' \\Colon y \\to c\n\\end{gather*}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/compspan.png}\n\\end{figure}\n\n\\noindent\nThe composition would be a third span, with some apex $z$. The\nmost natural choice for it is the pullback of $g$ along\n$f'$. Remember that a pullback is the object $z$\ntogether with two morphisms:\n\\begin{align*}\n  h  & \\Colon z \\to x \\\\\n  h' & \\Colon z \\to y\n\\end{align*}\nsuch that:\n\\[g \\circ h = f' \\circ h'\\]\nwhich is universal among all such objects.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/pullspan.png}\n\\end{figure}\n\n\\noindent\nFor now, let's concentrate on spans over the category of sets. In that\ncase, the pullback is just a set of pairs $(p, q)$ from the\nCartesian product $x \\times y$ such that:\n\\[g\\ p = f'\\ q\\]\nA morphism between two spans that share the same endpoints is defined as\na morphism $h$ between their apices, such that the appropriate\ntriangles commute.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/morphspan.png}\n  \\caption{A $2$-cell in $\\cat{Span}$.}\n\\end{figure}\n\n\\noindent\nTo summarize, in the bicategory $\\cat{Span}$: $0$-cells are sets, $1$-cells\nare spans, $2$-cells are span morphisms. An identity $1$-cell is a\ndegenerate span in which all three objects are the same, and the two\nmorphisms are identities.\n\nWe've seen another example of a bicategory before: the bicategory\n$\\cat{Prof}$ of\n\\hyperref[ends-and-coends]{profunctors},\nwhere 0-cells are categories, 1-cells are profunctors, and 2-cells are\nnatural transformations. The composition of profunctors was given by a\ncoend.\n\n\\section{Monads}\n\nBy now you should be pretty familiar with the definition of a monad as a\nmonoid in the category of endofunctors. Let's revisit this definition\nwith the new understanding that the category of endofunctors is just one\nsmall hom-category of endo-$1$-cells in the bicategory $\\Cat$. We\nknow it's a monoidal category: the tensor product comes from the\ncomposition of endofunctors. A monoid is defined as an object in a\nmonoidal category --- here it will be an endofunctor $T$ ---\ntogether with two morphisms. Morphisms between endofunctors are natural\ntransformations. One morphism maps the monoidal unit --- the identity\nendofunctor --- to $T$:\n\\[\\eta \\Colon I \\to T\\]\nThe second morphism maps the tensor product of $T \\otimes T$ to\n$T$. The tensor product is given by endofunctor composition, so\nwe get:\n\\[\\mu \\Colon T \\circ T \\to T\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/monad.png}\n\\end{figure}\n\n\\noindent\nWe recognize these as the two operations defining a monad (they are\ncalled \\code{return} and \\code{join} in Haskell), and we know that\nmonoid laws turn to monad laws.\n\nNow let's remove all mention of endofunctors from this definition. We\nstart with a bicategory $\\cat{C}$ and pick a $0$-cell $a$ in it.\nAs we've seen earlier, the hom-category $\\cat{C}(a, a)$ is a monoidal\ncategory. We can therefore define a monoid in $\\cat{C}(a, a)$ by\npicking a $1$-cell, $T$, and two $2$-cells:\n\\begin{align*}\n  \\eta & \\Colon I \\to T         \\\\\n  \\mu  & \\Colon T \\circ T \\to T\n\\end{align*}\nsatisfying the monoid laws. We call \\emph{this} a monad.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/bimonad.png}\n\\end{figure}\n\n\\noindent\nThat's a much more general definition of a monad using only $0$-cells,\n$1$-cells, and $2$-cells. It reduces to the usual monad when applied to the\nbicategory $\\Cat$. But let's see what happens in other\nbicategories.\n\nLet's construct a monad in $\\cat{Span}$. We pick a $0$-cell, which is a\nset that, for reasons that will become clear soon, I will call\n$\\mathit{Ob}$. Next, we pick an endo-$1$-cell: a span from $\\mathit{Ob}$ back\nto $\\mathit{Ob}$. It has a set at the apex, which I will call $\\mathit{Arr}$,\nequipped with two functions:\n\\begin{align*}\n  \\mathit{dom} & \\Colon \\mathit{Arr} \\to \\mathit{Ob} \\\\\n  \\mathit{cod} & \\Colon \\mathit{Arr} \\to \\mathit{Ob}\n\\end{align*}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/spanmonad.png}\n\\end{figure}\n\n\\noindent\nLet's call the elements of the set $\\mathit{Arr}$ ``arrows.'' If I also\ntell you to call the elements of $\\mathit{Ob}$ ``objects,'' you might get\na hint where this is leading to. The two functions $\\mathit{dom}$ and\n$\\mathit{cod}$ assign the domain and the codomain to an ``arrow.''\n\nTo make our span into a monad, we need two $2$-cells, $\\eta$ and\n$\\mu$. The monoidal unit, in this case, is the trivial span from\n$\\mathit{Ob}$ to $\\mathit{Ob}$ with the apex at $\\mathit{Ob}$ and two identity\nfunctions. The $2$-cell $\\eta$ is a function between the apices\n$\\mathit{Ob}$ and $\\mathit{Arr}$. In other words, $\\eta$ assigns an\n``arrow'' to every ``object.'' A $2$-cell in $\\cat{Span}$ must satisfy\ncommutation conditions --- in this case:\n\\begin{align*}\n  \\mathit{dom} & \\circ \\eta = \\id \\\\\n  \\mathit{cod} & \\circ \\eta = \\id\n\\end{align*}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/spanunit.png}\n\\end{figure}\n\n\\noindent\nIn components, this becomes:\n\\[\\mathit{dom}\\ (\\eta\\ \\mathit{ob}) = \\mathit{ob} = \\mathit{cod}\\ (\\eta\\ \\mathit{ob})\\]\nwhere $\\mathit{ob}$ is an ``object'' in $\\mathit{Ob}$. In other words,\n$\\eta$ assigns to every ``object'' an ``arrow'' whose domain and\ncodomain are that ``object.'' We'll call this special ``arrow'' the\n``identity arrow.''\n\nThe second $2$-cell $\\mu$ acts on the composition of the span\n$\\mathit{Arr}$ with itself. The composition is defined as a pullback, so\nits elements are pairs of elements from $\\mathit{Arr}$ --- pairs of\n``arrows'' $(a_1, a_2)$. The pullback condition is:\n\\[\\mathit{cod}\\ a_1 = \\mathit{dom}\\ a_2\\]\nWe say that $a_1$ and $a_2$ are ``composable,'' because the\ndomain of one is the codomain of the other.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/spanmul.png}\n\\end{figure}\n\n\\noindent\nThe $2$-cell $\\mu$ is a function that maps a pair of composable\n``arrows'' $(a_1, a_2)$ to a single ``arrow'' $a_3$ from\n$\\mathit{Arr}$. In other words $\\mu$ defines composition of ``arrows''.\n\nIt's easy to check that monad laws correspond to identity and\nassociativity laws for arrows. We have just defined a category (a small\ncategory, mind you, in which objects and arrows form sets).\n\nSo, all told, a category is just a monad in the bicategory of spans.\n\nWhat is amazing about this result is that it puts categories on the same\nfooting as other algebraic structures like monads and monoids. There is\nnothing special about being a category. It's just two sets and four\nfunctions. In fact we don't even need a separate set for objects,\nbecause objects can be identified with identity arrows (they are in\none-to-one correspondence). So it's really just a set and a few\nfunctions. Considering the pivotal role that category theory plays in\nall of mathematics, this is a very humbling realization.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Derive unit and associativity laws for the tensor product defined as\n        composition of endo-$1$-cells in a bicategory.\n  \\item\n        Check that monad laws for a monad in $\\cat{Span}$ correspond to\n        identity and associativity laws in the resulting category.\n  \\item\n        Show that a monad in $\\cat{Prof}$ is an identity-on-objects functor.\n  \\item\n        What's a monad algebra for a monad in $\\cat{Span}$?\n\\end{enumerate}\n\n\\section{Bibliography}\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        \\urlref{https://graphicallinearalgebra.net/2017/04/16/a-monoid-is-a-category-a-category-is-a-monad-a-monad-is-a-monoid/}{Paweł Sobociński’s blog}.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.2/adjunctions.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{n mathematics we have} various ways of saying that one thing is like\nanother. The strictest is equality. Two things are equal if there is no\nway to distinguish one from another. One can be substituted for the\nother in every imaginable context. For instance, did you notice that we\nused \\newterm{equality} of morphisms every time we talked about commuting\ndiagrams? That's because morphisms form a set (hom-set) and set elements\ncan be compared for equality.\n\nBut equality is often too strong. There are many examples of things\nbeing the same for all intents and purposes, without actually being\nequal. For instance, the pair type \\code{(Bool, Char)} is not\nstrictly equal to \\code{(Char, Bool)}, but we understand that they\ncontain the same information. This concept is best captured by an\n\\newterm{isomorphism} between two types --- a morphism that's invertible.\nSince it's a morphism, it preserves the structure; and being ``iso''\nmeans that it's part of a round trip that lands you in the same spot, no\nmatter on which side you start. In the case of pairs, this isomorphism\nis called \\code{swap}:\n\n\\src{snippet01}\n\\code{swap} happens to be its own inverse.\n\n\\section{Adjunction and Unit/Counit Pair}\n\nWhen we talk about categories being isomorphic, we express this in terms\nof mappings between categories, a.k.a. functors. We would like to be\nable to say that two categories $\\cat{C}$ and $\\cat{D}$ are isomorphic if\nthere exists a functor $R$ (``right'') from $\\cat{C}$ to $\\cat{D}$,\nwhich is invertible. In other words, there exists another functor\n$L$ (``left'') from $\\cat{D}$ back to $\\cat{C}$ which, when\ncomposed with $R$, is equal to the identity functor $I$.\nThere are two possible compositions, $R \\circ L$ and\n$L \\circ R$; and two possible identity functors: one in $\\cat{C}$\nand another in $\\cat{D}$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/adj-1.jpg}\n\\end{figure}\n\n\\noindent\nBut here's the tricky part: What does it mean for two functors to be\n\\emph{equal}? What do we mean by this equality:\n\\[R \\circ L = I_{\\cat{D}}\\]\nor this one:\n\\[L \\circ R = I_{\\cat{C}}\\]\nIt would be reasonable to define functor equality in terms of equality\nof objects. Two functors, when acting on equal objects, should produce\nequal objects. But we don't, in general, have the notion of object\nequality in an arbitrary category. It's just not part of the definition.\n(Going deeper into this rabbit hole of ``what equality really is,'' we\nwould end up in Homotopy Type Theory.)\n\nYou might argue that functors \\emph{are} morphisms in the category of\ncategories, so they should be equality-comparable. And indeed, as long\nas we are talking about small categories, where objects form a set, we\ncan indeed use the equality of elements of a set to equality-compare\nobjects.\n\nBut, remember, $\\Cat$ is really a $\\cat{2}$-category. Hom-sets in a\n$\\cat{2}$-category have additional structure --- there are $2$-morphisms acting\nbetween $1$-morphisms. In $\\Cat$, $1$-morphisms are functors, and\n$2$-morphisms are natural transformations. So it's more natural (can't\navoid this pun!) to consider natural isomorphisms as substitutes for\nequality when talking about functors.\n\nSo, instead of isomorphism of categories, it makes sense to consider a\nmore general notion of \\newterm{equivalence}. Two categories $\\cat{C}$ and\n$\\cat{D}$ are \\emph{equivalent} if we can find two functors going back\nand forth between them, whose composition (either way) is\n\\newterm{naturally isomorphic} to the identity functor. In other words,\nthere is a two-way natural transformation between the composition\n$R \\circ L$ and the identity functor $I_{\\cat{D}}$, and another\nbetween $L \\circ R$ and the identity functor $I_{\\cat{C}}$.\n\nAdjunction is even weaker than equivalence, because it doesn't require\nthat the composition of the two functors be \\emph{isomorphic} to the\nidentity functor. Instead it stipulates the existence of a \\newterm{one\n  way} natural transformation from $I_{\\cat{D}}$ to $R \\circ L$, and\nanother from $L \\circ R$ to $I_{\\cat{C}}$. Here are the signatures of\nthese two natural transformations:\n\\begin{gather*}\n  \\eta \\Colon I_{\\cat{D}} \\to R \\circ L \\\\\n  \\varepsilon \\Colon L \\circ R \\to I_{\\cat{C}}\n\\end{gather*}\n$\\eta$ is called the unit, and $\\varepsilon$ the counit of the adjunction.\n\nNotice the asymmetry between these two definitions. In general, we don't\nhave the two remaining mappings:\n\\begin{gather*}\n  R \\circ L \\to I_{\\cat{D}} \\quad\\quad\\text{not necessarily} \\\\\n  I_{\\cat{C}} \\to L \\circ R \\quad\\quad\\text{not necessarily}\n\\end{gather*}\nBecause of this asymmetry, the functor $L$ is called the\n\\newterm{left adjoint} to the functor $R$, while the functor\n$R$ is the right adjoint to $L$. (Of course, left and\nright make sense only if you draw your diagrams one particular way.)\n\nThe compact notation for the adjunction is:\n\\[L \\dashv R\\]\nTo better understand the adjunction, let's analyze the unit and the\ncounit in more detail.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/adj-unit.jpg}\n\\end{figure}\n\n\\noindent\nLet's start with the unit. It's a natural transformation, so it's a\nfamily of morphisms. Given an object $d$ in $\\cat{D}$, the\ncomponent of $\\eta$ is a morphism between $I d$, which is equal to\n$d$, and $(R \\circ L) d$; which, in the picture, is called\n$d'$:\n\\[\\eta_d \\Colon d \\to (R \\circ L) d\\]\nNotice that the composition $R \\circ L$ is an endofunctor in $\\cat{D}$.\n\nThis equation tells us that we can pick any object $d$ in\n$\\cat{D}$ as our starting point, and use the round trip functor\n$R \\circ L$ to pick our target object $d'$. Then we\nshoot an arrow --- the morphism $\\eta_d$ --- to our target.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/adj-counit.jpg}\n\\end{figure}\n\n\\noindent\nBy the same token, the component of the counit $\\varepsilon$ can be described as:\n\\[\\varepsilon_{c} \\Colon (L \\circ R) c \\to c\\]\nIt tells us that we\ncan pick any object $c$ in $\\cat{C}$ as our target, and use the\nround trip functor $L \\circ R$ to pick the source\n$c' = (L \\circ R) c$. Then we shoot the arrow --- the morphism\n$\\varepsilon_{c}$ --- from the source to the target.\n\nAnother way of looking at unit and counit is that unit lets us\n\\emph{introduce} the composition $R \\circ L$ anywhere we could\ninsert an identity functor on $\\cat{D}$; and counit lets us\n\\emph{eliminate} the composition $L \\circ R$, replacing it with the\nidentity on $\\cat{C}$. That leads to some ``obvious'' consistency\nconditions, which make sure that introduction followed by elimination\ndoesn't change anything:\n\\begin{gather*}\n  L = L \\circ I_{\\cat{D}} \\to L \\circ R \\circ L \\to I_{\\cat{C}} \\circ L = L \\\\\n  R = I_{\\cat{D}} \\circ R \\to R \\circ L \\circ R \\to R \\circ I_{\\cat{C}} = R\n\\end{gather*}\nThese are called triangular identities because they make the following\ndiagrams commute:\n\n\\begin{figure}[H]\n  \\centering\n\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      L \\arrow[rd, equal] \\arrow[r, \"L \\circ \\eta\"]\n      & L \\circ R \\circ L \\arrow[d, \"\\varepsilon \\circ L\"] \\\\\n      & L\n    \\end{tikzcd}\n  \\end{subfigure}%\n  \\hspace{1cm}\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      R \\arrow[rd, equal] \\arrow[r, \"\\eta \\circ R\"]\n      & R \\circ L \\circ R \\arrow[d, \"R \\circ \\varepsilon\"] \\\\\n      & R\n    \\end{tikzcd}\n  \\end{subfigure}\n\\end{figure}\n\n\\noindent\nThese are diagrams in the functor category: the arrows are natural\ntransformations, and their composition is the horizontal composition of\nnatural transformations. In components, these identities become:\n\\begin{gather*}\n  \\varepsilon_{L d} \\circ L \\eta_d = \\id_{L d} \\\\\n  R \\varepsilon_{c} \\circ \\eta_{R c} = \\id_{R c}\n\\end{gather*}\nWe often see unit and counit in Haskell under different names. Unit is\nknown as \\code{return} (or \\code{pure}, in the definition of\n\\code{Applicative}):\n\n\\src{snippet02}\nand counit as \\code{extract}:\n\n\\src{snippet03}\nHere, \\code{m} is the (endo-) functor corresponding to $R \\circ L$,\nand \\code{w} is the (endo-) functor corresponding to $L \\circ R$. As\nwe'll see later, they are part of the definition of a monad and a\ncomonad, respectively.\n\nIf you think of an endofunctor as a container, the unit (or\n\\code{return}) is a polymorphic function that creates a default box\naround a value of arbitrary type. The counit (or \\code{extract}) does\nthe reverse: it retrieves or produces a single value from a container.\n\nWe'll see later that every pair of adjoint functors defines a monad and\na comonad. Conversely, every monad or comonad may be factorized into a\npair of adjoint functors --- this factorization is not unique, though.\n\nIn Haskell, we use monads a lot, but only rarely factorize them into\npairs of adjoint functors, primarily because those functors would\nnormally take us out of $\\Hask$.\n\nWe can however define adjunctions of \\newterm{endofunctors} in Haskell.\nHere's part of the definition taken from\n\\code{Data.Functor.Adjunction}:\n\n\\src{snippet04}\nThis definition requires some explanation. First of all, it describes a\nmulti-parameter type class --- the two parameters being \\code{f} and\n\\code{u}. It establishes a relation called \\code{Adjunction} between\nthese two type constructors.\n\nAdditional conditions, after the vertical bar, specify functional\ndependencies. For instance, \\code{f -> u} means that\n\\code{u} is determined by \\code{f} (the relation between \\code{f}\nand \\code{u} is a function, here on type constructors). Conversely,\n\\code{u -> f} means that, if we know \\code{u}, then\n\\code{f} is uniquely determined.\n\nI'll explain in a moment why, in Haskell, we can impose the condition\nthat the right adjoint \\code{u} be a \\newterm{representable} functor.\n\n\\section{Adjunctions and Hom-Sets}\n\nThere is an equivalent definition of the adjunction in terms of natural\nisomorphisms of hom-sets. This definition ties nicely with universal\nconstructions we've been studying so far. Every time you hear the\nstatement that there is some unique morphism, which factorizes some\nconstruction, you should think of it as a mapping of some set to a\nhom-set. That's the meaning of ``picking a unique morphism.''\n\nFurthermore, factorization can be often described in terms of natural\ntransformations. Factorization involves commuting diagrams --- some\nmorphism being equal to a composition of two morphisms (factors). A\nnatural transformation maps morphisms to commuting diagrams. So, in a\nuniversal construction, we go from a morphism to a commuting diagram,\nand then to a unique morphism. We end up with a mapping from morphism to\nmorphism, or from one hom-set to another (usually in different\ncategories). If this mapping is invertible, and if it can be naturally\nextended across all hom-sets, we have an adjunction.\n\nThe main difference between universal constructions and adjunctions is\nthat the latter are defined globally --- for all hom-sets. For instance,\nusing a universal construction you can define a product of two select\nobjects, even if it doesn't exist for any other pair of objects in that\ncategory. As we'll see soon, if the product of \\emph{any pair} of\nobjects exists in a category, it can be also defined through an\nadjunction.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/adj-homsets.jpg}\n\\end{figure}\n\n\\noindent\nHere's the alternative definition of the adjunction using hom-sets. As\nbefore, we have two functors $L \\Colon \\cat{D} \\to \\cat{C}$ and\n$R \\Colon \\cat{C} \\to \\cat{D}$. We pick two arbitrary objects: the\nsource object $d$ in $\\cat{D}$, and the target object $c$\nin $\\cat{C}$. We can map the source object $d$ to $\\cat{C}$ using\n$L$. Now we have two objects in $\\cat{C}$, $L d$ and\n$c$. They define a hom-set:\n\\[\\cat{C}(L d, c)\\]\nSimilarly, we can map the target object $c$ using $R$. Now\nwe have two objects in $\\cat{D}$, $d$ and $R c$. They,\ntoo, define a hom set:\n\\[\\cat{D}(d, R c)\\]\nWe say that $L$ is left adjoint to $R$ iff there is an\nisomorphism of hom sets:\n\\[\\cat{C}(L d, c) \\cong \\cat{D}(d, R c)\\]\nthat is natural both in $d$ and $c$.\nNaturality means that the source $d$ can be varied smoothly\nacross $\\cat{D}$; and the target $c$, across $\\cat{C}$. More\nprecisely, we have a natural transformation $\\varphi$ between the\nfollowing two (covariant) functors from $\\cat{C}$ to $\\Set$. Here's\nthe action of these functors on objects:\n\\begin{gather*}\n  c \\to \\cat{C}(L d, c) \\\\\n  c \\to \\cat{D}(d, R c)\n\\end{gather*}\nThe other natural transformation, $\\psi$, acts between the following\n(contravariant) functors:\n\\begin{gather*}\n  d \\to \\cat{C}(L d, c) \\\\\n  d \\to \\cat{D}(d, R c)\n\\end{gather*}\nBoth natural transformations must be invertible.\n\nIt's easy to show that the two definitions of the adjunction are\nequivalent. For instance, let's derive the unit transformation starting\nfrom the isomorphism of hom-sets:\n\\[\\cat{C}(L d, c) \\cong \\cat{D}(d, R c)\\]\nSince this isomorphism works for any object $c$, it must also\nwork for $c = L d$:\n\\[\\cat{C}(L d, L d) \\cong \\cat{D}(d, (R \\circ L) d)\\]\nWe know that the left hand side must contain at least one morphism, the\nidentity. The natural transformation will map this morphism to an\nelement of $\\cat{D}(d, (R \\circ L) d)$ or, inserting the identity\nfunctor $I$, a morphism in:\n\\[\\cat{D}(I d, (R \\circ L) d)\\]\nWe get a family of morphisms parameterized by $d$. They form a\nnatural transformation between the functor $I$ and the functor\n$R \\circ L$ (the naturality condition is easy to verify). This is\nexactly our unit, $\\eta$.\n\nConversely, starting from the existence of the unit and counit, we can\ndefine the transformations between hom-sets. For instance, let's pick an\narbitrary morphism $f$ in the hom-set $\\cat{C}(L d, c)$. We\nwant to define a $\\varphi$ that, acting on $f$, produces a\nmorphism in $\\cat{D}(d, R c)$.\n\nThere isn't really much choice. One thing we can try is to lift\n$f$ using $R$. That will produce a morphism $R f$\nfrom $R (L d)$ to $R c$ --- a morphism that's an\nelement of $\\cat{D}((R \\circ L) d, R c)$.\n\nWhat we need for a component of $\\varphi$, is a morphism from\n$d$ to $R c$. That's not a problem, since we can use a\ncomponent of $\\eta_d$ to get from $d$ to\n$(R \\circ L) d$. We get:\n\\[\\varphi_f = R f \\circ \\eta_d\\]\nThe other direction is analogous, and so is the derivation of $\\psi$.\n\nGoing back to the Haskell definition of \\code{Adjunction}, the natural\ntransformations $\\varphi$ and $\\psi$ are replaced by polymorphic\n(in \\code{a} and \\code{b}) functions \\code{leftAdjunct} and\n\\code{rightAdjunct}, respectively. The functors $L$ and\n$R$ are called \\code{f} and \\code{u}:\n\n\\src{snippet05}\nThe equivalence between the \\code{unit}/\\code{counit} formulation\nand the \\code{leftAdjunct}/\\allowbreak\\code{rightAdjunct} formulation is\nwitnessed by these mappings:\n\n\\src{snippet06}\nIt's very instructive to follow the translation from the categorical\ndescription of the adjunction to Haskell code. I highly encourage this\nas an exercise.\n\nWe are now ready to explain why, in Haskell, the right adjoint is\nautomatically a \\hyperref[representable-functors]{representable\n  functor}. The reason for this is that, to the first approximation, we\ncan treat the category of Haskell types as the category of sets.\n\nWhen the right category $\\cat{D}$ is $\\Set$, the right adjoint\n$R$ is a functor from $\\cat{C}$ to $\\Set$. Such a functor is\nrepresentable if we can find an object $\\mathit{rep}$ in $\\cat{C}$ such\nthat the hom-functor $\\cat{C}(\\mathit{rep}, \\_)$ is naturally isomorphic to\n$R$. It turns out that, if $R$ is the right adjoint of\nsome functor $L$ from $\\Set$ to $\\cat{C}$, such an object\nalways exists --- it's the image of the singleton set $()$ under\n$L$:\n\\[\\mathit{rep} = L ()\\]\nIndeed, the adjunction tells us that the following two hom-sets are\nnaturally isomorphic:\n\\[\\cat{C}(L (), c) \\cong \\Set((), R c)\\]\nFor a given $c$, the right hand side is the set of functions from\nthe singleton set $()$ to $R c$. We've seen earlier that\neach such function picks one element from the set $R c$. The set\nof such functions is isomorphic to the set $R c$. So we have:\n\\[\\cat{C}(L (), -) \\cong R\\]\nwhich shows that $R$ is indeed representable.\n\n\\section{Product from Adjunction}\n\nWe have previously introduced several concepts using universal\nconstructions. Many of those concepts, when defined globally, are easier\nto express using adjunctions. The simplest non-trivial example is that\nof the product. The gist of the \\hyperref[products-and-coproducts]{universal\n  construction of the product} is the ability to factorize any\nproduct-like candidate through the universal product.\n\nMore precisely, the product of two objects $a$ and $b$ is\nthe object $(a\\times{}b)$ (or \\code{(a, b)} in the Haskell\nnotation) equipped with two morphisms $\\mathit{fst}$ and $\\mathit{snd}$ such\nthat, for any other candidate $c$ equipped with two morphisms\n$p \\Colon c \\to a$ and $q \\Colon c \\to b$, there\nexists a unique morphism $m \\Colon c \\to (a, b)$ that\nfactorizes $p$ and $q$ through $\\mathit{fst}$ and $\\mathit{snd}$.\n\nAs we've seen earlier, in Haskell, we can implement a \\code{factorizer} that generates this\nmorphism from the two projections:\n\n\\src{snippet07}\nIt's easy to verify that the factorization conditions hold:\n\n\\src{snippet08}\nWe have a mapping that takes a pair of morphisms \\code{p} and\n\\code{q} and produces another morphism\n\\code{m = factorizer p q}.\n\nHow can we translate this into a mapping between two hom-sets that we\nneed to define an adjunction? The trick is to go outside of\n$\\Hask$ and treat the pair of morphisms as a single morphism in\nthe product category.\n\nLet me remind you what a product category is. Take two arbitrary\ncategories $\\cat{C}$ and $\\cat{D}$. The objects in the product category\n$\\cat{C}\\times{}\\cat{D}$ are pairs of objects, one from $\\cat{C}$ and one from\n$\\cat{D}$. The morphisms are pairs of morphisms, one from $\\cat{C}$ and\none from $\\cat{D}$.\n\nTo define a product in some category $\\cat{C}$, we should start with the\nproduct category $\\cat{C}\\times{}\\cat{C}$. Pairs of morphism from $\\cat{C}$ are single\nmorphisms in the product category $\\cat{C}\\times{}\\cat{C}$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/adj-productcat.jpg}\n\\end{figure}\n\n\\noindent\nIt might be a little confusing at first that we are using a product\ncategory to define a product. These are, however, very different\nproducts. We don't need a universal construction to define a product\ncategory. All we need is the notion of a pair of objects and a pair of\nmorphisms.\n\nHowever, a pair of objects from $\\cat{C}$ is \\emph{not} an object in\n$\\cat{C}$. It's an object in a different category, $\\cat{C}\\times{}\\cat{C}$. We can\nwrite the pair formally as $\\langle a, b \\rangle$,\nwhere $a$ and $b$ are objects of $\\cat{C}$. The universal\nconstruction, on the other hand, is necessary in order to define the\nobject $a\\times{}b$ (or \\code{(a, b)} in Haskell), which is an object\nin \\emph{the same} category $\\cat{C}$. This object is supposed to\nrepresent the pair $\\langle a, b \\rangle$ in a way\nspecified by the universal construction. It doesn't always exist and,\neven if it exists for some, might not exist for other pairs of objects\nin $\\cat{C}$.\n\nLet's now look at the \\code{factorizer} as a mapping of hom-sets. The\nfirst hom-set is in the product category $\\cat{C}\\times{}\\cat{C}$, and the second is\nin $\\cat{C}$. A general morphism in $\\cat{C}\\times{}\\cat{C}$ would be a pair of\nmorphisms $\\langle f, g \\rangle$:\n\\begin{gather*}\n  f \\Colon c' \\to a \\\\\n  g \\Colon c'' \\to b\n\\end{gather*}\nwith $c''$ potentially different from\n$c'$. But to define a product, we are interested in a\nspecial morphism in $\\cat{C}\\times{}\\cat{C}$, the pair $p$ and $q$ that\nshare the same source object $c$. That's okay: In the definition\nof an adjunction, the source of the left hom-set is not an arbitrary\nobject --- it's the result of the left functor $L$ acting on some\nobject from the right category. The functor that fits the bill is easy\nto guess --- it's the diagonal functor $\\Delta$ from $\\cat{C}$ to $\\cat{C}\\times{}\\cat{C}$,\nwhose action on objects is:\n\\[\\Delta c = \\langle c, c \\rangle\\]\nThe left-hand side hom-set in our adjunction should thus be:\n\\[(\\cat{C}\\times{}\\cat{C})(\\Delta c, \\langle a, b \\rangle)\\]\nIt's a hom-set in the product category. Its elements are pairs of\nmorphisms that we recognize as the arguments to our \\code{factorizer}:\n\\[(c \\to a) \\to (c \\to b) \\ldots{}\\]\nThe right-hand side hom-set lives in $\\cat{C}$, and it goes between the\nsource object $c$ and the result of some functor $R$\nacting on the target object in $\\cat{C}\\times{}\\cat{C}$. That's the functor that maps\nthe pair $\\langle a, b \\rangle$ to our product object,\n$a\\times{}b$. We recognize this element of the hom-set as the\n\\emph{result} of the \\code{factorizer}:\n\\[\\ldots{} \\to (c \\to (a, b))\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/adj-product.jpg}\n\\end{figure}\n\n\\noindent\nWe still don't have a full adjunction. For that we first need our\n\\code{factorizer} to be invertible --- we are building an\n\\emph{isomorphism} between hom-sets. The inverse of the\n\\code{factorizer} should start from a morphism $m$ --- a\nmorphism from some object $c$ to the product object $a\\times{}b$.\nIn other words, $m$ should be an element of:\n\\[\\cat{C}(c, a\\times{}b)\\]\nThe inverse factorizer should map $m$ to a morphism\n$\\langle p, q \\rangle$ in $\\cat{C}\\times{}\\cat{C}$ that goes from\n$\\langle c, c \\rangle$ to\n$\\langle a, b \\rangle$; in other words, a morphism\nthat's an element of:\n\\[(\\cat{C}\\times{}\\cat{C})(\\Delta\\ c, \\langle a, b \\rangle)\\]\nIf that mapping exists, we conclude that there exists the right adjoint\nto the diagonal functor. That functor defines a product.\n\nIn Haskell, we can always construct the inverse of the\n\\code{factorizer} by composing \\code{m} with, respectively,\n\\code{fst} and \\code{snd}.\n\n\\begin{snip}{haskell}\np = fst . m\nq = snd . m\n\\end{snip}\nTo complete the proof of the equivalence of the two ways of defining a\nproduct we also need to show that the mapping between hom-sets is\nnatural in $a$, $b$, and $c$. I will leave this as\nan exercise for the dedicated reader.\n\nTo summarize what we have done: A categorical product may be defined\nglobally as the \\newterm{right adjoint} of the diagonal functor:\n\\[(\\cat{C}\\times{}\\cat{C})(\\Delta c, \\langle a, b \\rangle) \\cong \\cat{C}(c, a\\times{}b)\\]\nHere, $a\\times{}b$ is the result of the action of our right adjoint\nfunctor $\\mathit{Product}$ on the pair\n$\\langle a, b \\rangle$. Notice that any functor from\n$\\cat{C}\\times{}\\cat{C}$ is a bifunctor, so $\\mathit{Product}$ is a bifunctor. In\nHaskell, the $\\mathit{Product}$ bifunctor is written simply as\n\\code{(,)}. You can apply it to two types and get their product type,\nfor instance:\n\n\\src{snippet09}\n\n\\section{Exponential from Adjunction}\n\nThe exponential $b^a$, or the function object $a \\Rightarrow b$, can be\ndefined using a \\hyperref[function-types]{universal\n  construction}. This construction, if it exists for all pairs of objects,\ncan be seen as an adjunction. Again, the trick is to concentrate on the\nstatement:\n\n\\begin{quote}\n  For any other object $z$ with a morphism $g \\Colon z\\times{}a \\to b$\n  there is a unique morphism $h \\Colon z \\to (a \\Rightarrow b)$\n\\end{quote}\nThis statement establishes a mapping between hom-sets.\n\nIn this case, we are dealing with objects in the same category, so the\ntwo adjoint functors are endofunctors. The left (endo-)functor\n$L$, when acting on object $z$, produces $z\\times{}a$.\nIt's a functor that corresponds to taking a product with some fixed\n$a$.\n\nThe right (endo-)functor $R$, when acting on $b$ produces\nthe function object $a \\Rightarrow b$ (or $b^a$). Again, $a$ is\nfixed. The adjunction between these two functors is often written as:\n\\[-\\times{}a \\dashv (-)^a\\]\nThe mapping of hom-sets that underlies this adjunction is best seen by\nredrawing the diagram that we used in the universal construction.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/adj-expo.jpg}\n\\end{figure}\n\n\\noindent\nNotice that the $\\mathit{eval}$ morphism\\footnote{See ch.9 on \\hyperref[function-types]{universal\n    construction}.} is nothing else but the counit of\nthis adjunction:\n\\[(a \\Rightarrow b)\\times{}a \\to b\\]\nwhere:\n\\[(a \\Rightarrow b)\\times{}a = (L \\circ R) b\\]\nI have previously mentioned that a universal construction defines a\nunique object, up to isomorphism. That's why we have ``the'' product and\n``the'' exponential. This property translates to adjunctions as well: if\na functor has an adjoint, this adjoint is unique up to isomorphism.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Derive the naturality square for $\\psi$, the transformation\n        between the two (contravariant) functors:\n        \\begin{gather*}\n          a \\to \\cat{C}(L a, b) \\\\\n          a \\to \\cat{D}(a, R b)\n        \\end{gather*}\n  \\item\n        Derive the counit $\\varepsilon$ starting from the hom-sets isomorphism in\n        the second definition of the adjunction.\n  \\item\n        Complete the proof of equivalence of the two definitions of the\n        adjunction.\n  \\item\n        Show that the coproduct can be defined by an adjunction. Start with\n        the definition of the factorizer for a coproduct.\n  \\item\n        Show that the coproduct is the left adjoint of the diagonal functor.\n  \\item\n        Define the adjunction between a product and a function object in\n        Haskell.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet01.hs",
    "content": "swap :: (a,b) -> (b,a)\nswap (a,b) = (b,a)"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet02.hs",
    "content": "return :: d -> m d"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet03.hs",
    "content": "extract :: w c -> c"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet04.hs",
    "content": "class (Functor f, Representable u) =>\n      Adjunction f u | f -> u, u -> f where\n    unit :: a -> u (f a)\n    counit :: f (u a) -> a"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet05.hs",
    "content": "class (Functor f, Representable u) => \n  Adjunction f u | f -> u, u -> f where\n    leftAdjunct  :: (f a -> b) -> (a -> u b)\n    rightAdjunct :: (a -> u b) -> (f a -> b)"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet06.hs",
    "content": "unit           = leftAdjunct id\ncounit         = rightAdjunct id\nleftAdjunct f  = fmap f . unit\nrightAdjunct f = counit . fmap f"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet07.hs",
    "content": "factorizer :: (c -> a) -> (c -> b) -> (c -> (a, b))\nfactorizer p q = \\x -> (p x, q x)"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet08.hs",
    "content": "fst . factorizer p q = p\nsnd . factorizer p q = q"
  },
  {
    "path": "src/content/3.2/code/haskell/snippet09.hs",
    "content": "(,) Int Bool ~ (Int, Bool)"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet01.ml",
    "content": "let swap (a, b) = b, a\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet02.ml",
    "content": "module type Unit_Example = sig\n  type 'a m\n\n  val return : 'd -> 'd m\nend\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet03.ml",
    "content": "module type Counit_Example = sig\n  type 'c w\n\n  val extract : 'c w -> 'c\nend\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet04.ml",
    "content": "(* L is Functor F and R is Representable Functor U *)\nmodule type Adjunction = functor\n  (F : Functor)\n  (U : Representable)\n  -> sig\n  val unit : 'a -> 'a F.t U.t\n  val counit : 'a U.t F.t -> 'a\nend\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet05.ml",
    "content": "module type Adjunction_HomSet = functor\n  (F : Functor)\n  (U : Representable)\n  -> sig\n  val left_adjunct : ('a F.t -> 'b) -> 'a -> 'b U.t\n  val right_adjunct : ('a -> 'b U.t) -> 'a F.t -> 'b\nend\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet06.ml",
    "content": "(* Putting it all together to show the equivalence between\n   unit/counit and left_adjunct/right_adjunct *)\nmodule type Adjunction = functor\n  (F : Functor)\n  (U : Representable)\n  -> sig\n  val unit : 'a -> 'a F.t U.t\n  val counit : 'a U.t F.t -> 'a\n  val left_adjunct : ('a F.t -> 'b) -> 'a -> 'b U.t\n  val right_adjunct : ('a -> 'b U.t) -> 'a F.t -> 'b\nend\n\n(* Adjunction via unit/counit *)\nmodule type Adjunction_Unit_Counit = functor\n  (F : Functor)\n  (U : Representable)\n  -> sig\n  val unit : 'a -> 'a F.t U.t\n  val counit : 'a U.t F.t -> 'a\nend\n\n(* Adjunction via left and right adjoints *)\nmodule type Adjunction_Hom_Set = functor\n  (F : Functor)\n  (U : Representable)\n  -> sig\n  val left_adjunct : ('a F.t -> 'b) -> 'a -> 'b U.t\n  val right_adjunct : ('a -> 'b U.t) -> 'a F.t -> 'b\nend\n\n(* Implementing unit/counit from left and right adjoint definitions *)\nmodule Adjunction_From_Hom_Set (A : Adjunction_Hom_Set) : Adjunction =\nfunctor\n  (F : Functor)\n  (U : Representable)\n  ->\n  struct\n    type 't f = 't F.t\n    type 't u = 't U.t\n\n    module M = A (F) (U)\n    include M\n\n    let unit : 'a. 'a -> 'a f u = fun a -> M.left_adjunct idty a\n\n    let counit : 'a. 'a u f -> 'a =\n     fun fua -> M.right_adjunct idty fua\n   ;;\n  end\n\n(* Implementing left and right adjunct from unit/counit Definitions *)\nmodule Adjunction_From_Unit_Counit (A : Adjunction_Unit_Counit) :\n  Adjunction =\nfunctor\n  (F : Functor)\n  (U : Representable)\n  ->\n  struct\n    type 't f = 't F.t\n    type 't u = 't U.t\n\n    module M = A (F) (U)\n    include M\n\n    let left_adjunct f a = (U.fmap f) (M.unit a)\n    let right_adjunct f fa = M.counit (F.fmap f fa)\n  end\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet07.ml",
    "content": "let factorizer p q x = p x, q x\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet08.ml",
    "content": "compose fst (factorizer p q) = p\ncompose snd (factorizer p q) = q\n"
  },
  {
    "path": "src/content/3.2/code/ocaml/snippet09.ml",
    "content": "int * bool ~ (int, bool)\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet01.re",
    "content": "let swap = (a, b) => (b, a);\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet02.re",
    "content": "module type Unit_Example = {\n  type m('a);\n\n  let return: 'd => m('d);\n};\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet03.re",
    "content": "module type Counit_Example = {\n  type w('c);\n\n  let extract: w('c) => 'c;\n};\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet04.re",
    "content": "/* L is Functor F and R is Representable Functor U */\nmodule type Adjunction =\n  (F: Functor, U: Representable) => {\n    let unit: 'a => U.t(F.t('a));\n    let counit: F.t(U.t('a)) => 'a;\n  };\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet05.re",
    "content": "module type Adjunction_HomSet =\n  (F: Functor, U: Representable) => {\n    let left_adjunct: (F.t('a) => 'b, 'a) => U.t('b);\n    let right_adjunct: ('a => U.t('b), F.t('a)) => 'b;\n  };\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet06.re",
    "content": "/* Putting it all together to show the equivalence between \n* unit & counit and left_adjunct & right_adjunct */\nmodule type Adjunction =\n  (F: Functor, U: Representable) => {\n    let unit: 'a => U.t(F.t('a));\n    let counit: F.t(U.t('a)) => 'a;\n    let left_adjunct: (F.t('a) => 'b, 'a) => U.t('b);\n    let right_adjunct: ('a => U.t('b), F.t('a)) => 'b;\n  };\n\n/* Adjunction via unit & counit */\nmodule type Adjunction_Unit_Counit =\n  (F: Functor, U: Representable) => {\n    let unit: 'a => U.t(F.t('a));\n    let counit: F.t(U.t('a)) => 'a;\n  };\n\n/* Adjunction via left and right adjoints */\nmodule type Adjunction_Hom_Set =\n  (F: Functor, U: Representable) => {\n    let left_adjunct: (F.t('a) => 'b, 'a) => U.t('b);\n    let right_adjunct: ('a => U.t('b), F.t('a)) => 'b;\n  };\n\n/* Implementing unit & counit from left and right adjoint definitions */\nmodule Adjunction_From_Hom_Set = (A: Adjunction_Hom_Set) : Adjunction =>\n  (F: Functor, U: Representable) => {\n    type f('t) = F.t('t);\n    type u('t) = U.t('t);\n\n    module M = A(F, U);\n    include M;\n\n    let unit: 'a. 'a => u(f('a)) = a => M.left_adjunct(idty, a);\n    let counit: 'a. f(u('a)) => 'a = fua => M.right_adjunct(idty, fua);\n  };\n\n/* Implementing left and right adjunct from unit & counit Definitions */\nmodule Adjunction_From_Unit_Counit = (A: Adjunction_Unit_Counit) : Adjunction =>\n  (F: Functor, U: Representable) => {\n    type f('t) = F.t('t);\n    type u('t) = U.t('t);\n\n    module M = A(F, U);\n    include M;\n\n    let left_adjunct = (f, a) => (U.fmap(f))(M.unit(a));\n    let right_adjunct = (f, fa) => M.counit(F.fmap(f, fa));\n  };\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet07.re",
    "content": "let factorizer = (p, q, x) => (p(x), q(x));\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet08.re",
    "content": "compose(fst, factorizer(p, q)) == p;\ncompose(snd, factorizer(p, q)) == q;\n"
  },
  {
    "path": "src/content/3.2/code/reason/snippet09.re",
    "content": "(int, bool) ~ (int, bool)\n"
  },
  {
    "path": "src/content/3.2/code/scala/snippet01.scala",
    "content": "def swap[A, B]: ((A, B)) => (B, A) = {\n  case (a, b) => (b, a)\n}"
  },
  {
    "path": "src/content/3.2/code/scala/snippet02.scala",
    "content": "// return is a keyword in Scala\ndef pure[D]: D => M[D]"
  },
  {
    "path": "src/content/3.2/code/scala/snippet03.scala",
    "content": "def extract[C]: W[C] => C"
  },
  {
    "path": "src/content/3.2/code/scala/snippet04.scala",
    "content": "abstract class Adjunction[F[_], U[_]](\n  implicit val F: Functor[F],\n  val U: Representable[U]\n){\n  def unit[A](a: A): U[F[A]]\n\n  def counit[A](a: F[U[A]]): A\n}\n"
  },
  {
    "path": "src/content/3.2/code/scala/snippet05.scala",
    "content": "abstract class Adjunction[F[_], U[_]](\n  implicit val F: Functor[F],\n  val U: Representable[U]\n){\n  // changed the order of parameters\n  // to help Scala compiler infer types\n  def leftAdjunct[A, B](a: A)(f: F[A] => B): U[B]\n\n  def rightAdjunct[A, B](fa: F[A])(f: A => U[B]): B\n}"
  },
  {
    "path": "src/content/3.2/code/scala/snippet06.scala",
    "content": "def unit[A](a: A): U[F[A]] =\n    leftAdjunct(a)(identity)\n  \n  def counit[A](a: F[U[A]]): A =\n    rightAdjunct(a)(identity)\n  \n  def leftAdjunct[A, B](a: A)(f: F[A] => B): U[B] =\n    U.map(unit(a))(f)\n  \n  def rightAdjunct[A, B](a: F[A])(f: A => U[B]): B =\n    counit(F.map(a)(f))"
  },
  {
    "path": "src/content/3.2/code/scala/snippet07.scala",
    "content": "def factorizer[A, B, C](p: C => A)(q: C => B): (C => (A, B)) =\n  x => (p(x), q(x))"
  },
  {
    "path": "src/content/3.2/code/scala/snippet08.scala",
    "content": "factorizer(p)(q).andThen(_._1) == p\nfactorizer(p)(q).andThen(_._2) == q"
  },
  {
    "path": "src/content/3.2/code/scala/snippet09.scala",
    "content": "Product2[Int, Boolean] ~ (Int, Boolean)"
  },
  {
    "path": "src/content/3.3/code/haskell/snippet01.hs",
    "content": "type String = [Char]"
  },
  {
    "path": "src/content/3.3/code/haskell/snippet02.hs",
    "content": "toNat :: [()] -> Int\ntoNat = length\n\ntoLst :: Int -> [()]\ntoLst n = replicate n ()"
  },
  {
    "path": "src/content/3.3/code/ocaml/snippet01.ml",
    "content": "type string = char list\n"
  },
  {
    "path": "src/content/3.3/code/ocaml/snippet02.ml",
    "content": "let to_nat : unit list -> int = List.length\nlet to_lst : int -> unit list = fun n -> List.init n ~f:(fun _ -> ())\n"
  },
  {
    "path": "src/content/3.3/code/reason/snippet01.re",
    "content": "type string = list(char);\n"
  },
  {
    "path": "src/content/3.3/code/reason/snippet02.re",
    "content": "let to_nat: list(unit) => int = List.length;\nlet to_lst: int => list(unit) = n => List.init(n, ~f=_ => ());\n"
  },
  {
    "path": "src/content/3.3/code/scala/snippet01.scala",
    "content": "type String = List[Char]"
  },
  {
    "path": "src/content/3.3/code/scala/snippet02.scala",
    "content": "def toNat: List[Unit] => Int =\n  _.length\n\ndef toLst: Int => List[Unit] =\n  n => List.fill(n)(())"
  },
  {
    "path": "src/content/3.3/free-forgetful-adjunctions.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{F}{ree constructions are} a powerful application of adjunctions. A\n\\newterm{free functor} is defined as the left adjoint to a \\newterm{forgetful\n  functor}. A forgetful functor is usually a pretty simple functor that\nforgets some structure. For instance, lots of interesting categories are\nbuilt on top of sets. But categorical objects, which abstract those\nsets, have no internal structure --- they have no elements. Still, those\nobjects often carry the memory of sets, in the sense that there is a\nmapping --- a functor --- from a given category $\\cat{C}$ to\n$\\Set$. A set corresponding to some object in $\\cat{C}$ is called\nits \\newterm{underlying set}.\n\nMonoids are such objects that have underlying sets --- sets of elements.\nThere is a forgetful functor $U$ from the category of monoids\n$\\cat{Mon}$ to the category of sets, which maps monoids to their\nunderlying sets. It also maps monoid morphisms (homomorphisms) to\nfunctions between sets.\n\nI like to think of $\\cat{Mon}$ as having split personality. On the one\nhand, it's a bunch of sets with multiplication and unit elements. On the\nother hand, it's a category with featureless objects whose only\nstructure is encoded in morphisms that go between them. Every\nset-function that preserves multiplication and unit gives rise to a\nmorphism in $\\cat{Mon}$.\\\\\n\\newline\nThings to keep in mind:\n\n\\begin{itemize}\n  \\tightlist\n  \\item\n        There may be many monoids that map to the same set, and\n  \\item\n        There are fewer (or at most as many as) monoid morphisms than there\n        are functions between their underlying sets.\n\\end{itemize}\n\n\\noindent\nThe functor $F$ that's the left adjoint to the forgetful functor\n$U$ is the free functor that builds free monoids from their\ngenerator sets. The adjunction follows from the free monoid\nuniversal construction we've discussed before.\\footnote{See ch.13 on\n  \\hyperref[free-monoids]{free monoids}.}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.6\\textwidth]{images/forgetful.jpg}\n  \\caption{Monoids $m_1$ and $m_2$ have the same\n    underlying set. There are more functions between the underlying sets of\n    $m_2$ and $m_3$ than there are morphisms\n    between them.}\n\\end{figure}\n\n\\noindent\nIn terms of hom-sets, we can write this adjunction as:\n\\[\\cat{Mon}(F x, m) \\cong \\Set(x, U m)\\]\nThis (natural in $x$ and $m$) isomorphism tells us that:\n\n\\begin{itemize}\n  \\tightlist\n  \\item\n        For every monoid homomorphism between the free monoid $F x$\n        generated by $x$ and an arbitrary monoid $m$ there is a\n        unique function that embeds the set of generators $x$ in the\n        underlying set of $m$. It's a function in\n        $\\Set(x, U m)$.\n  \\item\n        For every function that embeds $x$ in the underlying set of\n        some $m$ there is a unique monoid morphism between the free\n        monoid generated by $x$ and the monoid $m$. (This is the\n        morphism we called $h$ in our universal construction.)\n\\end{itemize}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.8\\textwidth]{images/freemonadjunction.jpg}\n\\end{figure}\n\n\\noindent\nThe intuition is that $F x$ is the ``maximum'' monoid that can\nbe built on the basis of $x$. If we could look inside monoids, we\nwould see that any morphism that belongs to $\\cat{Mon}(F x, m)$\n\\emph{embeds} this free monoid in some other monoid $m$. It does\nit by possibly identifying some elements. In particular, it embeds the\ngenerators of $F x$ (i.e., the elements of $x$) in\n$m$. The adjunction shows that the embedding of $x$, which\nis given by a function from $\\Set(x, U m)$ on the right,\nuniquely determines the embedding of monoids on the left, and vice\nversa.\n\nIn Haskell, the list data structure is a free monoid (with some caveats:\nsee \\urlref{http://comonad.com/reader/2015/free-monoids-in-haskell/}{Dan\n  Doel's blog post}). A list type \\code{{[}a{]}} is a free monoid with\nthe type \\code{a} representing the set of generators. For instance,\nthe type \\code{{[}Char{]}} contains the unit element --- the empty\nlist \\code{{[}{]}} --- and the singletons like\n\\code{{[}'a'{]}}, \\code{{[}'b'{]}} --- the\ngenerators of the free monoid. The rest is generated by applying the\n``product.'' Here, the product of two lists simply appends one to\nanother. Appending is associative and unital (that is, there is a\nneutral element --- here, the empty list). A free monoid generated by\n\\code{Char} is nothing but the set of all strings of characters from\n\\code{Char}. It's called \\code{String} in Haskell:\n\n\\src{snippet01}\n(\\code{type} defines a type synonym --- a different name for an\nexisting type).\n\nAnother interesting example is a free monoid built from just one\ngenerator. It's the type of the list of units, \\code{{[}(){]}}. Its\nelements are \\code{{[}{]}}, \\code{{[}(){]}}, \\code{{[}(), (){]}},\netc. Every such list can be described by one natural number --- its\nlength. There is no more information encoded in the list of units.\nAppending two such lists produces a new list whose length is the sum of\nthe lengths of its constituents. It's easy to see that the type\n\\code{{[}(){]}} is isomorphic to the additive monoid of natural\nnumbers (with zero). Here are the two functions that are the inverse of\neach other, witnessing this isomorphism:\n\n\\src{snippet02}\nFor simplicity I used the type \\code{Int} rather than\n\\code{Natural}, but the idea is the same. The function\n\\code{replicate} creates a list of length \\code{n} pre-filled with a\ngiven value --- here, the unit.\n\n\\section{Some Intuitions}\n\nWhat follows are some hand-waving arguments. Those kind of arguments are\nfar from rigorous, but they help in forming intuitions.\n\nTo get some intuition about the free/forgetful adjunctions it helps to\nkeep in mind that functors and functions are lossy in nature. Functors\nmay collapse multiple objects and morphisms, functions may bunch\ntogether multiple elements of a set. Also, their image may cover only\npart of their codomain.\n\nAn ``average'' hom-set in $\\Set$ will contain a whole spectrum of\nfunctions starting with the ones that are least lossy (e.g., injections\nor, possibly, isomorphisms) and ending with constant functions that\ncollapse the whole domain to a single element (if there is one).\n\nI tend to think of morphisms in an arbitrary category as being lossy\ntoo. It's just a mental model, but it's a useful one, especially when\nthinking of adjunctions --- in particular those in which one of the\ncategories is $\\Set$.\n\nFormally, we can only speak of morphisms that are invertible\n(isomorphisms) or non-invertible. It's that latter kind that may be\nthought of as lossy. There is also a notion of mono- and epi- morphisms\nthat generalize the idea of injective (non-collapsing) and surjective\n(covering the whole codomain) functions, but it's possible to have a\nmorphism that is both mono and epi, and which is still non-invertible.\n\nIn the Free ⊣ Forgetful adjunction, we have the more constrained\ncategory $\\cat{C}$ on the left, and a less constrained category $\\cat{D}$\non the right. Morphisms in $\\cat{C}$ are ``fewer'' because they have to\npreserve some additional structure. In the case of $\\cat{Mon}$, they\nhave to preserve multiplication and unit. Morphisms in $\\cat{D}$ don't\nhave to preserve as much structure, so there are ``more'' of them.\n\nWhen we apply a forgetful functor $U$ to an object $c$ in\n$\\cat{C}$, we think of it as revealing the ``internal structure'' of\n$c$. In fact, if $\\cat{D}$ is $\\Set$ we think of $U$\nas \\emph{defining} the internal structure of $c$ --- its\nunderlying set. (In an arbitrary category, we can't talk about the\ninternals of an object other than through its connections to other\nobjects, but here we are just hand-waving.)\n\nIf we map two objects $c'$ and $c$ using $U$,\nwe expect that, in general, the mapping of the hom-set\n$\\cat{C}(c', c)$ will cover only a subset of\n$\\cat{D}(U c', U c)$. That's because morphisms in\n$\\cat{C}(c', c)$ have to preserve the additional structure,\nwhereas the ones in $\\cat{D}(U c', U c)$ don't.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.45\\textwidth]{images/forgettingmorphisms.jpg}\n\\end{figure}\n\n\\noindent\nBut since an adjunction is defined as an \\newterm{isomorphism} of\nparticular hom-sets, we have to be very picky with our selection of\n$c'$. In the adjunction, $c'$ is picked not\nfrom just anywhere in $\\cat{C}$, but from the (presumably smaller) image\nof the free functor $F$:\n\\[\\cat{C}(F d, c) \\cong \\cat{D}(d, U c)\\]\nThe image of $F$ must therefore consist of objects that have lots\nof morphisms going to an arbitrary $c$. In fact, there has to be\nas many structure-preserving morphisms from $F d$ to $c$\nas there are non-structure preserving morphisms from $d$ to\n$U c$. It means that the image of $F$ must consist of\nessentially structure-free objects (so that there is no structure to\npreserve by morphisms). Such ``structure-free'' objects are called free\nobjects.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.45\\textwidth]{images/freeimage.jpg}\n\\end{figure}\n\n\\noindent\nIn the monoid example, a free monoid has no structure other than what's\ngenerated by unit and associativity laws. Other than that, all\nmultiplications produce brand new elements.\n\nIn a free monoid, $2 * 3$ is not $6$ --- it's a new element ${[}2, 3{]}$. Since\nthere is no identification of ${[}2, 3{]}$ and $6$, a morphism from this\nfree monoid to any other monoid $m$ is allowed to map them\nseparately. But it's also okay for it to map both ${[}2, 3{]}$ and $6$\n(their product) to the same element of $m$. Or to identify ${[}2,\n  3{]}$ and $5$ (their sum) in an additive monoid, and so on. Different\nidentifications give you different monoids.\n\nThis leads to another interesting intuition: Free monoids, instead of\nperforming the monoidal operation, accumulate the arguments that were\npassed to it. Instead of multiplying $2$ and $3$ they remember $2$ and $3$ in a\nlist. The advantage of this scheme is that we don't have to specify what\nmonoidal operation we will use. We can keep accumulating arguments, and\nonly at the end apply an operator to the result. And it's then that we\ncan chose what operator to apply. We can add the numbers, or multiply\nthem, or perform addition modulo 2, and so on. A free monoid separates\nthe creation of an expression from its evaluation. We'll see this idea\nagain when we talk about algebras.\n\nThis intuition generalizes to other, more elaborate free constructions.\nFor instance, we can accumulate whole expression trees before evaluating\nthem. The advantage of this approach is that we can transform such trees\nto make the evaluation faster or less memory consuming. This is, for\ninstance, done in implementing matrix calculus, where eager evaluation\nwould lead to lots of allocations of temporary arrays to store\nintermediate results.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Consider a free monoid built from a singleton set as its generator.\n        Show that there is a one-to-one correspondence between morphisms from\n        this free monoid to any monoid $m$, and functions from the\n        singleton set to the underlying set of $m$.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet01.hs",
    "content": "vlen = sqrt . sum . fmap (flip (^) 2)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet02.hs",
    "content": "newtype Writer w a = Writer (a, w)\n\ninstance Functor (Writer w) where\n    fmap f (Writer (a, w)) = Writer (f a, w)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet03.hs",
    "content": "a -> Writer w b"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet04.hs",
    "content": "class Monad m where \n    (>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c)\n    return :: a -> m a"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet05.hs",
    "content": "instance Monoid w => Monad (Writer w) where\n    f >=> g = \\a ->\n        let Writer (b, s) = f a\n            Writer (c, s') = g b\n        in Writer (c, s `mappend` s')\n    return a = Writer (a, mempty)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet06.hs",
    "content": "tell :: w -> Writer w ()\ntell s = Writer ((), s)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet07.hs",
    "content": "(>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c)\nf >=> g = \\a -> ..."
  },
  {
    "path": "src/content/3.4/code/haskell/snippet08.hs",
    "content": "f >=> g = \\a -> let mb = f a\n                in ..."
  },
  {
    "path": "src/content/3.4/code/haskell/snippet09.hs",
    "content": "(>>=) :: m a -> (a -> m b) -> m b"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet10.hs",
    "content": "class Monad m where\n    (>>=) :: m a -> (a -> m b) -> m b\n    return :: a -> m a"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet11.hs",
    "content": "(Writer (a, w)) >>= f = let Writer (b, w') = f a \n                        in Writer (b, w `mappend` w')"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet12.hs",
    "content": "join :: m (m a) -> m a"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet13.hs",
    "content": "ma >>= f = join (fmap f ma)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet14.hs",
    "content": "class Functor m => Monad m where\n    join :: m (m a) -> m a\n    return :: a -> m a"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet15.hs",
    "content": "fmap f ma = ma >>= \\a -> return (f a)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet16.hs",
    "content": "join :: Monoid w => Writer w (Writer w a) -> Writer w a\njoin (Writer ((Writer (a, w')), w)) = Writer (a, w `mappend` w')"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet17.hs",
    "content": "process :: String -> Writer String [String]\nprocess = upCase >=> toWords"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet18.hs",
    "content": "process s = do \n    upStr <- upCase s\n    toWords upStr"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet19.hs",
    "content": "upCase :: String -> Writer String String\nupCase s = Writer (map toUpper s, \"upCase \")"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet20.hs",
    "content": "process s = \n    upCase s >>= \\upStr ->\n        toWords upStr"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet21.hs",
    "content": "upStr <- upCase s"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet22.hs",
    "content": "process s = do\n    upStr <- upCase s\n    tell \"toWords \"\n    return (words upStr)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet23.hs",
    "content": "process s =\n    upCase s >>= \\upStr ->\n      tell \"toWords \" >>= \\() ->\n        return (words upStr)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet24.hs",
    "content": "(>>) :: m a -> m b -> m b\nm >> k = m >>= (\\_ -> k)"
  },
  {
    "path": "src/content/3.4/code/haskell/snippet25.hs",
    "content": "process s =\n  upCase s >>= \\upStr ->\n    tell \"toWords \" >>\n      return (words upStr)"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet01.ml",
    "content": "(* Depends on OCaml library Core *)\nmodule Vlen (F : Functor with type 'a t = 'a list) = struct\n  let summable =\n    (module Float : Base__.Container_intf.Summable\n      with type t = float)\n\n\n  let vlen =\n    Float.sqrt\n    <.> List.sum summable ~f:Fn.id\n    <.> F.fmap (flip Float.int_pow 2)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet02.ml",
    "content": "module WriterInstance (W : sig\n  type w\nend) : Functor with type 'a t = (W.w, 'a) writer = struct\n  type 'a t = (W.w, 'a) writer\n\n  let fmap f (Writer (a, w)) = Writer (f a, w)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet03.ml",
    "content": "'a -> ('w, 'b) writer\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet04.ml",
    "content": "module type Monad = sig\n  type 'a m\n\n  val ( >=> ) : ('a -> 'b m) -> ('b -> 'c m) -> 'a -> 'c m\n  val return : 'a -> 'a m\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet05.ml",
    "content": "module WriterMonad (W : Monoid) :\n  Monad with type 'a m = (W.a, 'a) writer = struct\n  type 'a m = (W.a, 'a) writer\n\n  let ( >=> ) f g a =\n    let (Writer (b, w)) = f a in\n    let (Writer (c, w')) = g b in\n    Writer (c, W.mappend w w')\n\n\n  let return a = Writer (a, W.mempty)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet06.ml",
    "content": "let tell w = Writer ((), w)\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet07.ml",
    "content": "let (>=>) f g = fun a -> ...\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet08.ml",
    "content": "let (>=>) f g = fun a -> \n  let mb = f a in\n  ...\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet09.ml",
    "content": "val ( >>= ) : 'a m -> ('a -> 'b m) -> 'b m\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet10.ml",
    "content": "module type Monad_Bind = sig\n  type 'a m\n\n  val ( >>= ) : 'a m -> ('a -> 'b m) -> 'b m\n  val return : 'a -> 'a m\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet11.ml",
    "content": "module WriterMonadBind (W : Monoid) = struct\n  let ( >>= ) (Writer (a, w)) f =\n    let (Writer (b, w')) = f a in\n    Writer (b, W.mappend w w')\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet12.ml",
    "content": "val join : ('a m) m : 'a m\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet13.ml",
    "content": "module BindUsingFunctionAndJoin (F : Functor) = struct\n  type 'a m = 'a F.t\n\n  external join : 'a m m -> 'a m = \"%identity\"\n  (** Make the type signature of join work \n  without providing an implementation **)\n\n  let ( >>= ) ma f = join (F.fmap f ma)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet14.ml",
    "content": "module type Monad_Join = functor (F : Functor) -> sig\n  type 'a m = 'a F.t\n\n  val join : 'a m m -> 'a m\n  val return : 'a -> 'a m\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet15.ml",
    "content": "module Fmap_Using_Monad (M : Monad_Bind) = struct\n  let fmap f ma = M.( >>= ) ma (fun a -> M.return (f a))\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet16.ml",
    "content": "module Writer_Join (W : Monoid) = struct\n  let join (Writer (Writer (a, w'), w)) = Writer (a, W.mappend w w')\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet17.ml",
    "content": "(* Import Str module using this - #require \"str\" *)\nlet to_words s = Writer (Str.split (Str.regexp \"\\b\") s, \"to_words\")\n\nmodule Writer_Process (W : Monad with type 'a m = (string, 'a) writer) =\nstruct\n  let process = W.(up_case >=> to_words)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet18.ml",
    "content": "module Process_Do\n    (W : Monad_Bind with type 'a m = (string, 'a) writer) =\nstruct\n  (* Needs OCaml compiler >= 4.08 *)\n  let ( let* ) = W.( >>= )\n\n  let process s =\n    let* up_str = up_case s in\n    to_words up_str\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet19.ml",
    "content": "let up_case s = Writer (String.uppercase s, \"up_case \")\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet20.ml",
    "content": "module Process_Bind_Without_Do\n    (W : Monad_Bind with type 'a m = (string, 'a) writer) =\nstruct\n  let process s = W.(up_case s >>= fun up_str -> to_words up_str)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet21.ml",
    "content": "let* up_str <- up_case s\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet22.ml",
    "content": "module Process_Tell\n    (W : Monad_Bind with type 'a m = (string, 'a) writer) =\nstruct\n  (* Needs OCaml compiler >= 4.08 *)\n  let ( let* ) = W.( >>= )\n  let tell w = Writer ((), w)\n\n  let process s =\n    let* up_str = up_case s in\n    let* _ = tell \"to_words \" in\n    to_words up_str\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet23.ml",
    "content": "module Process_Bind_Without_Do\n    (W : Monad_Bind with type 'a m = (string, 'a) writer) =\nstruct\n  let tell w = Writer ((), w)\n\n  let process s =\n    W.(\n      up_case s\n      >>= fun up_str -> tell \"to_words\" >>= fun _ -> to_words up_str)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet24.ml",
    "content": "module Monad_Ops (M : Monad_Bind) = struct\n  let ( >> ) m k = M.(m >>= fun _ -> k)\nend\n"
  },
  {
    "path": "src/content/3.4/code/ocaml/snippet25.ml",
    "content": "module Process_Bind_Without_Do\n    (W : Monad_Bind with type 'a m = (string, 'a) writer) =\nstruct\n  open Monad_Ops (W)\n\n  let tell w = Writer ((), w)\n\n  let process s =\n    W.(\n      up_case s >>= fun up_str -> tell \"to_words\" >> to_words up_str)\nend\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet01.re",
    "content": "/* Depends on OCaml library Core */\nmodule Vlen = (F: Functor with type t('a) = list('a)) => {\n  let summable: \n    module Base__.Container_intf.Summable with type t = float =\n    (module Float);\n\n  let vlen =\n    Float.sqrt\n    <.> List.sum(summable, ~f=Fn.id)\n    <.> F.fmap(flip(Float.int_pow, 2));\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet02.re",
    "content": "module WriterInstance = (W: {type w;}) : \n       (Functor with type t('a) = writer(W.w, 'a)) => {\n  type t('a) = writer(W.w, 'a);\n\n  let fmap = (f, Writer(a, w)) => Writer(f(a), w);\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet03.re",
    "content": "'a => writer('w, 'b)"
  },
  {
    "path": "src/content/3.4/code/reason/snippet04.re",
    "content": "module type Monad = {\n  type m('a);\n\n  let (>=>): ('a => m('b), 'b => m('c), 'a) => m('c);\n  let return: 'a => m('a);\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet05.re",
    "content": "module WriterMonad = (W: Monoid) : \n    (Monad with type m('a) = writer(W.a, 'a)) => {\n  type m('a) = writer(W.a, 'a);\n\n  let (>=>) = (f, g, a) => {\n    let Writer(b, w) = f(a);\n    let Writer(c, w') = g(b);\n    Writer(c, W.mappend(w, w'));\n  };\n\n  let return = a => Writer(a, W.mempty);\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet06.re",
    "content": "let tell = w => Writer((), w);\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet07.re",
    "content": "let (>=>) = (f, g) => a => ...\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet08.re",
    "content": "let (>=>) = (f, g) => a => {\n  let mb = f(a);\n  ...\n}"
  },
  {
    "path": "src/content/3.4/code/reason/snippet09.re",
    "content": "let (>>=): (m('a), 'a => m('b)) => m('b);\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet10.re",
    "content": "module type Monad_Bind = {\n  type m('a);\n\n  let (>>=): (m('a), 'a => m('b)) => m('b);\n  let return: 'a => m('a);\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet11.re",
    "content": "module WriterMonadBind = (W: Monoid) => {\n  let (>>=) = (Writer(a, w), f) => {\n    let Writer(b, w') = f(a);\n    Writer(b, W.mappend(w, w'));\n  };\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet12.re",
    "content": "let join: m(m('a)) => m('a)\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet13.re",
    "content": "module BindUsingFunctionAndJoin = (F: Functor) => {\n  type m('a) = F.t('a);\n\n  /** Make the type signature of join work\n  without providing an implementation **/\n  external join: m(m('a)) => m('a) = \"%identity\";\n\n  let (>>=) = (ma, f) => join(F.fmap(f, ma));\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet14.re",
    "content": "module type Monad_Join = (F: Functor) => {\n  type m('a) = F.t('a);\n\n  let join: m(m('a)) => m('a);\n  let return: 'a => m('a);\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet15.re",
    "content": "module Fmap_Using_Monad = (M: Monad_Bind) => {\n  let fmap = (f, ma) => M.(>>=)(ma, a => M.return(f(a)));\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet16.re",
    "content": "module Writer_Join = (W: Monoid) => {\n  let join = (Writer(Writer(a, w'), w)) => Writer(a, W.mappend(w, w'));\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet17.re",
    "content": "/* Import Str module using this - #require \"str\" */\nlet to_words = s => Writer(Str.split(Str.regexp(\"\\b\"), s), \"to_words\");\n\nmodule Writer_Process = (W: Monad with type m('a) = \n    writer(string, 'a)) => {\n  let process = W.(up_case >=> to_words);\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet18.re",
    "content": "module Process_Do = (W: Monad_Bind with type m('a) = \n    writer(string, 'a)) => {\n  /* Needs Reason parser >= 3.6.0 */\n  let (let*) = W.(>>=);\n\n  let process = s => {\n    let* up_str = up_case(s);\n    to_words(up_str);\n  };\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet19.re",
    "content": "let up_case = s => Writer(String.uppercase(s), \"up_case \");\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet20.re",
    "content": "module Process_Bind_Without_Do =\n       (W: Monad_Bind with type m('a) = writer(string, 'a)) => {\n  let process = s => W.(up_case(s) >>= (up_str => to_words(up_str)));\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet21.re",
    "content": "up_str = up_case(s)"
  },
  {
    "path": "src/content/3.4/code/reason/snippet22.re",
    "content": "module Process_Tell = (W: Monad_Bind with type m('a) =\n    writer(string, 'a)) => {\n  /* Needs Reason parser >= 3.6.0 */\n  let (let*) = W.(>>=);\n  let tell = w => Writer((), w);\n\n  let process = s => {\n    let* up_str = up_case(s);\n    let* _ = tell(\"to_words \");\n    to_words(up_str);\n  };\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet23.re",
    "content": "module Process_Bind_Without_Do =\n       (W: Monad_Bind with type m('a) = writer(string, 'a)) => {\n  let tell = w => Writer((), w);\n\n  let process = s =>\n    W.(\n      up_case(s)\n      >>= (up_str => tell(\"to_words\") >>= (_ => to_words(up_str)))\n    );\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet24.re",
    "content": "module Monad_Ops = (M: Monad_Bind) => {\n  let (>>) = (m, k) => M.(m >>= (_ => k));\n};\n"
  },
  {
    "path": "src/content/3.4/code/reason/snippet25.re",
    "content": "module Process_Bind_Without_Do =\n       (W: Monad_Bind with type m('a) = writer(string, 'a)) => {\n  open Monad_Ops(W);\n\n  let tell = w => Writer((), w);\n\n  let process = s =>\n    W.(up_case(s) >>= (up_str => tell(\"to_words\") >> to_words(up_str)));\n};\n"
  },
  {
    "path": "src/content/3.4/code/scala/snippet01.scala",
    "content": "def fmap[A, B]: (A => B) => List[A] => List[B] =\n  f => {\n    case Nil => Nil\n    case x :: xs => f(x) :: fmap[A, B](f)(xs)\n  }\n\ndef sum: List[Double] => Double = _.sum\n\nimport math._\n\ndef vlen: List[Double] => Double =\n  sqrt _ compose sum compose fmap(pow(_, 2))"
  },
  {
    "path": "src/content/3.4/code/scala/snippet02.scala",
    "content": "case class Writer[W, A](run: (A, W))\n\nimplicit def writerFunctor[W] = new Functor[Writer[W, ?]] {\n  def fmap[A, B](f: A => B)(fa: Writer[W, A]): Writer[W, B] =\n    fa match {\n      case Writer((a, w)) => Writer(f(a), w)\n  }\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet03.scala",
    "content": "A => Writer[W, B]"
  },
  {
    "path": "src/content/3.4/code/scala/snippet04.scala",
    "content": "trait Monad[M[_]] {\n  def >=>[A, B, C](m1: A => M[B], m2: B => M[C]): A => M[C]\n  def pure[A](a: A): M[A]\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet05.scala",
    "content": "implicit def writerMonad[W: Monoid] = new Functor[Writer[W, ?]] {\n  def >=>[A, B, C](f: A => Writer[W, B], g: B => Writer[W, C]) =\n    a => {\n      val Writer((b, s1)) = f(a)\n      val Writer((c, s2)) = g(b)\n      Writer((c, Monoid[W].combine(s1, s2)))\n    }\n\n  def pure[A](a: A) =\n    Writer(a, Monoid[W].empty)\n}\n\nobject kleisliSyntax {\n  //allows us to use >=> as an infix operator\n  implicit class MonadOps[M[_], A, B](m1: A => M[B]) {\n    def >=>[C](m2: B => M[C])(implicit m: Monad[M]): A => M[C] = {\n      m.>=>(m1, m2)\n    }\n  }\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet06.scala",
    "content": "def tell[W](s: W): Writer[W, Unit] =\n  Writer((), s)"
  },
  {
    "path": "src/content/3.4/code/scala/snippet07.scala",
    "content": "def >=>[A, B, C](f: A => M[B], g: B => M[C]) =\n  a => {...}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet08.scala",
    "content": "def >=>[A, B, C](f: A => M[B], g: B => M[C]) =\n  a => {\n    val mb = f(a)\n    ...\n  }"
  },
  {
    "path": "src/content/3.4/code/scala/snippet09.scala",
    "content": "def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B]"
  },
  {
    "path": "src/content/3.4/code/scala/snippet10.scala",
    "content": "trait Monad[M[_]] {\n  def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B]\n  def pure[A](a: A): M[A]\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet11.scala",
    "content": "object bindSyntax {\n  //allows us to use flatMap as an infix operator\n  implicit class MonadOps[A, B, W: Monoid](wa: Writer[W, A]) {\n    def flatMap(f: A => Writer[W, B]): Writer[W, B] = wa match {\n      case Writer((a, w1)) =>\n        val Writer((b, w2)) = f(a)\n        Writer(b, Monoid[W].combine(w1, w2))\n    }\n  }\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet12.scala",
    "content": "def flatten[A](mma: M[M[A]]): M[A]"
  },
  {
    "path": "src/content/3.4/code/scala/snippet13.scala",
    "content": "def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B] =\n  flatten(fmap(f)(ma))"
  },
  {
    "path": "src/content/3.4/code/scala/snippet14.scala",
    "content": "trait Monad[M[_]] extends Functor[M] {\n  def flatten[A](mma: M[M[A]]): M[A]\n  def pure[A](a: A): M[A]\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet15.scala",
    "content": "def fmap[A, B](f: A => B)(ma: M[A]): M[B] =\n  flatMap(ma)(a => pure(f(a)))  "
  },
  {
    "path": "src/content/3.4/code/scala/snippet16.scala",
    "content": "def flatten[A, W: Monoid](wwa: Writer[W, Writer[W, A]]): Writer[W, A] =\n  wwa match {\n    case Writer((Writer((a, w2)), w1)) =>\n      Writer(a, Monoid[W].combine(w1, w2))\n  }"
  },
  {
    "path": "src/content/3.4/code/scala/snippet17.scala",
    "content": "def toWords: String => Writer[String, List[String]] =\n  s => Writer(s.split(\"\\\\s+\").toList, \"toWords \")\n\ndef process: String => Writer[String, List[String]] = {\n  import kleisliSyntax._\n  // -Ypartial-unification should be on\n  upCase >=> toWords\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet18.scala",
    "content": "def process: String => Writer[String, List[String]] =\n  s => {\n    import bindSyntax._\n    for {\n      upStr <- upCase(s)\n      words <- toWords(upStr)\n    } yield words\n  }"
  },
  {
    "path": "src/content/3.4/code/scala/snippet19.scala",
    "content": "def upCase: String => Writer[String, String] =\n  s => Writer(s.toUpperCase, \"upCase \")"
  },
  {
    "path": "src/content/3.4/code/scala/snippet20.scala",
    "content": "def process: String => Writer[String, List[String]] =\n  s => {\n    import bindSyntax._\n    upCase(s) >>= (upStr => toWords(upStr))\n  }"
  },
  {
    "path": "src/content/3.4/code/scala/snippet21.scala",
    "content": "upStr <- upCase(s)"
  },
  {
    "path": "src/content/3.4/code/scala/snippet22.scala",
    "content": "def words: String => List[String] =\n  _.split(\"\\\\s+\").toList\n\ndef process: String => Writer[String, List[String]] =\n  s => {\n    import bindSyntax._\n    for {\n      upStr <- upCase(s)\n      _ <- tell(\"toWords \")\n    } yield words(upStr)\n  }"
  },
  {
    "path": "src/content/3.4/code/scala/snippet23.scala",
    "content": "def process: String => Writer[String, List[String]] =\n  s => {\n    upCase(s).flatMap { upStr =>\n      tell(\"toWords \").flatMap { _ =>\n        writerMonad.pure(words(upStr))\n      }\n    }\n  }"
  },
  {
    "path": "src/content/3.4/code/scala/snippet24.scala",
    "content": "object moreSyntax {\n  // allows us to use >> as an infix operator\n  implicit class MoreOps[A, B, W: Monoid](m: Writer[W, A])\n      extends bindSyntax.MonadOps[A, B, W](m) {\n    def >>(k: Writer[W, B]): Writer[W, B] =\n      m >>= (_ => k)\n  }\n}"
  },
  {
    "path": "src/content/3.4/code/scala/snippet25.scala",
    "content": "def process: String => Writer[String, List[String]] = s => {\n  import moreSyntax._\n  upCase(s) flatMap (upStr =>\n    tell(\"toWords \") >>\n      writerMonad.pure(words(upStr)))\n}"
  },
  {
    "path": "src/content/3.4/monads-programmers-definition.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{P}{rogrammers have developed} a whole mythology around monads. It's\nsupposed to be one of the most abstract and difficult concepts in\nprogramming. There are people who ``get it'' and those who don't. For\nmany, the moment when they understand the concept of the monad is like a\nmystical experience. The monad abstracts the essence of so many diverse\nconstructions that we simply don't have a good analogy for it in\neveryday life. We are reduced to groping in the dark, like those blind\nmen touching different parts of the elephant end exclaiming\ntriumphantly: ``It's a rope,'' ``It's a tree trunk,'' or ``It's a\nburrito!''\n\nLet me set the record straight: The whole mysticism around the monad is\nthe result of a misunderstanding. The monad is a very simple concept.\nIt's the diversity of applications of the monad that causes the\nconfusion.\n\nAs part of research for this post I looked up duct tape (a.k.a., duck\ntape) and its applications. Here's a little sample of things that you\ncan do with it:\n\n\\begin{itemize}\n  \\tightlist\n  \\item\n        sealing ducts\n  \\item\n        fixing CO\\textsubscript{2} scrubbers on board Apollo 13\n  \\item\n        wart treatment\n  \\item\n        fixing Apple's iPhone 4 dropped call issue\n  \\item\n        making a prom dress\n  \\item\n        building a suspension bridge\n\\end{itemize}\n\n\\noindent\nNow imagine that you didn't know what duct tape was and you were trying\nto figure it out based on this list. Good luck!\n\nSo I'd like to add one more item to the collection of ``the monad is\nlike\\ldots{}'' clichés: The monad is like duct tape. Its applications\nare widely diverse, but its principle is very simple: it glues things\ntogether. More precisely, it composes things.\n\nThis partially explains the difficulties a lot of programmers,\nespecially those coming from the imperative background, have with\nunderstanding the monad. The problem is that we are not used to thinking\nof programming in terms of function composition. This is understandable.\nWe often give names to intermediate values rather than pass them\ndirectly from function to function. We also inline short segments of\nglue code rather than abstract them into helper functions. Here's an\nimperative-style implementation of the vector-length function in C:\n\n\\begin{snip}{cpp}\ndouble vlen(double * v) {\n    double d = 0.0;\n    int n;\n    for (n = 0; n < 3; ++n)\n        d += v[n] * v[n];\n    return sqrt(d);\n}\n\\end{snip}\nCompare this with the (stylized) Haskell version that makes function\ncomposition explicit:\n\n\\src{snippet01}\n(Here, to make things even more cryptic, I partially applied the\nexponentiation operator \\code{(\\^{})} by setting its second argument\nto \\code{2}.)\n\nI'm not arguing that Haskell's point-free style is always better, just\nthat function composition is at the bottom of everything we do in\nprogramming. And even though we are effectively composing functions,\nHaskell does go to great lengths to provide imperative-style syntax\ncalled the \\code{do} notation for monadic composition. We'll see its\nuse later. But first, let me explain why we need monadic composition in\nthe first place.\n\n\\section{The Kleisli Category}\n\nWe have previously arrived at the\n\\hyperref[kleisli-categories]{writer\n  monad} by embellishing regular functions. The particular embellishment\nwas done by pairing their return values with strings or, more generally,\nwith elements of a monoid. We can now recognize that such an embellishment\nis a functor:\n\n\\src{snippet02}\nWe have subsequently found a way of composing embellished functions, or\nKleisli arrows, which are functions of the form:\n\n\\src{snippet03}\nIt was inside the composition that we implemented the accumulation of\nthe log.\n\nWe are now ready for a more general definition of the Kleisli category.\nWe start with a category $\\cat{C}$ and an endofunctor $m$. The\ncorresponding Kleisli category $\\cat{K}$ has the same objects as\n$\\cat{C}$, but its morphisms are different. A morphism between two\nobjects $a$ and $b$ in $\\cat{K}$ is implemented as a\nmorphism:\n\\[a \\to m\\ b\\]\nin the original category $\\cat{C}$. It's important to keep in mind that\nwe treat a Kleisli arrow in $\\cat{K}$ as a morphism between $a$\nand $b$, and not between $a$ and $m\\ b$.\n\nIn our example, $m$ was specialized to \\code{Writer w}, for\nsome fixed monoid \\code{w}.\n\nKleisli arrows form a category only if we can define proper composition\nfor them. If there is a composition, which is associative and has an\nidentity arrow for every object, then the functor $m$ is called a\n\\newterm{monad}, and the resulting category is called the Kleisli category.\n\nIn Haskell, Kleisli composition is defined using the fish operator\n\\code{>=>}, and the identity arrow is a\npolymorphic function called \\code{return}. Here's the definition of a\nmonad using Kleisli composition:\n\n\\src{snippet04}\nKeep in mind that there are many equivalent ways of defining a monad,\nand that this is not the primary one in the Haskell ecosystem. I like it\nfor its conceptual simplicity and the intuition it provides, but there\nare other definitions that are more convenient when programming. We'll\ntalk about them momentarily.\n\nIn this formulation, monad laws are very easy to express. They cannot be\nenforced in Haskell, but they can be used for equational reasoning. They\nare simply the standard composition laws for the Kleisli category:\n\n\\begin{snip}{haskell}\n(f >=> g) >=> h = f >=> (g >=> h) -- associativity\nreturn >=> f = f                  -- left unit\nf >=> return = f                  -- right unit\n\\end{snip}\nThis kind of a definition also expresses what a monad really is: it's a\nway of composing embellished functions. It's not about side effects or\nstate. It's about composition. As we'll see later, embellished functions\nmay be used to express a variety of effects or state, but that's not\nwhat the monad is for. The monad is the sticky duct tape that ties one\nend of an embellished function to the other end of an embellished\nfunction.\n\nGoing back to our \\code{Writer} example: The logging functions (the\nKleisli arrows for the \\code{Writer} functor) form a category because\n\\code{Writer} is a monad:\n\n\\src{snippet05}\nMonad laws for \\code{Writer w} are satisfied as long as monoid laws\nfor \\code{w} are satisfied (they can't be enforced in Haskell either).\n\nThere's a useful Kleisli arrow defined for the \\code{Writer} monad\ncalled \\code{tell}. It's sole purpose is to add its argument to the\nlog:\n\n\\src{snippet06}\nWe'll use it later as a building block for other monadic functions.\n\n\\section{Fish Anatomy}\n\nWhen implementing the fish operator for different monads you quickly\nrealize that a lot of code is repeated and can be easily factored out.\nTo begin with, the Kleisli composition of two functions must return a\nfunction, so its implementation may as well start with a lambda taking\nan argument of type \\code{a}:\n\n\\src{snippet07}\nThe only thing we can do with this argument is to pass it to \\code{f}:\n\n\\src{snippet08}\nAt this point we have to produce the result of type \\code{m c},\nhaving at our disposal an object of type \\code{m b} and a function\n\\code{g :: b -> m c}. Let's define a function that\ndoes that for us. This function is called \\emph{bind} and is usually written in\nthe form of an infix operator:\n\n\\src{snippet09}\nFor every monad, instead of defining the fish operator, we may instead\ndefine bind. In fact the standard Haskell definition of a monad uses\nbind:\n\n\\src{snippet10}\nHere's the definition of bind for the \\code{Writer} monad:\n\n\\src{snippet11}\nIt is indeed shorter than the definition of the fish operator.\n\nIt's possible to further dissect bind, taking advantage of the fact that\n\\code{m} is a functor. We can use \\code{fmap} to apply the function\n\\code{a -> m b} to the contents of \\code{m a}. This\nwill turn \\code{a} into \\code{m b}. The result of the application\nis therefore of type \\code{m (m b)}. This is not exactly what we\nwant --- we need the result of type \\code{m b} --- but we're close.\nAll we need is a function that collapses or flattens the double\napplication of \\code{m}. Such a function is called \\code{join}:\n\n\\src{snippet12}\nUsing \\code{join}, we can rewrite bind as:\n\n\\src{snippet13}\nThat leads us to the third option for defining a monad:\n\n\\src{snippet14}\nHere we have explicitly requested that \\code{m} be a \\code{Functor}.\nWe didn't have to do that in the previous two definitions of the monad.\nThat's because any type constructor \\code{m} that either supports the\nfish or bind operator is automatically a functor. For instance, it's\npossible to define \\code{fmap} in terms of bind and \\code{return}:\n\n\\src{snippet15}\nFor completeness, here's \\code{join} for the \\code{Writer} monad:\n\n\\src{snippet16}\n\n\\section{The \\texttt{do} Notation}\n\nOne way of writing code using monads is to work with Kleisli arrows ---\ncomposing them using the fish operator. This mode of programming is the\ngeneralization of the point-free style. Point-free code is compact and\noften quite elegant. In general, though, it can be hard to understand,\nbordering on cryptic. That's why most programmers prefer to give names\nto function arguments and intermediate values.\n\nWhen dealing with monads it means favoring the bind operator over the\nfish operator. Bind takes a monadic value and returns a monadic value.\nThe programmer may choose to give names to those values. But that's\nhardly an improvement. What we really want is to pretend that we are\ndealing with regular values, not the monadic containers that encapsulate\nthem. That's how imperative code works --- side effects, such as\nupdating a global log, are mostly hidden from view. And that's what the\n\\code{do} notation emulates in Haskell.\n\nYou might be wondering then, why use monads at all? If we want to make\nside effects invisible, why not stick to an imperative language? The\nanswer is that the monad gives us much better control over side effects.\nFor instance, the log in the \\code{Writer} monad is passed from\nfunction to function and is never exposed globally. There is no\npossibility of garbling the log or creating a data race. Also, monadic\ncode is clearly demarcated and cordoned off from the rest of the\nprogram.\n\nThe \\code{do} notation is just syntactic sugar for monadic\ncomposition. On the surface, it looks a lot like imperative code, but it\ntranslates directly to a sequence of binds and lambda expressions.\n\nFor instance, take the example we used previously to illustrate the\ncomposition of Kleisli arrows in the \\code{Writer} monad. Using our\ncurrent definitions, it could be rewritten as:\n\n\\src{snippet17}\nThis function turns all characters in the input string to upper case and\nsplits it into words, all the while producing a log of its actions.\n\nIn the \\code{do} notation it would look like this:\n\n\\src{snippet18}\nHere, \\code{upStr} is just a \\code{String}, even though\n\\code{upCase} produces a \\code{Writer}:\n\n\\src{snippet19}\nThis is because the \\code{do} block is desugared by the compiler to:\n\n\\src{snippet20}\nThe monadic result of \\code{upCase} is bound to a lambda that takes a\n\\code{String}. It's the name of this string that shows up in the\n\\code{do} block. When reading the line:\n\n\\src{snippet21}\nwe say that \\code{upStr} \\emph{gets} the result of \\code{upCase s}.\n\nThe pseudo-imperative style is even more pronounced when we inline\n\\code{toWords}. We replace it with the call to \\code{tell}, which\nlogs the string \\code{\"toWords \"}, followed by the call to\n\\code{return} with the result of splitting the string \\code{upStr}\nusing \\code{words}. Notice that \\code{words} is a regular function\nworking on strings.\n\n\\src{snippet22}\nHere, each line in the do block introduces a new nested bind in the\ndesugared code:\n\n\\src{snippet23}\nNotice that \\code{tell} produces a unit value, so it doesn't have to\nbe passed to the following lambda. Ignoring the contents of a monadic\nresult (but not its effect --- here, the contribution to the log) is\nquite common, so there is a special operator to replace bind in that\ncase:\n\n\\src{snippet24}\nThe actual desugaring of our code looks like this:\n\n\\src{snippet25}\nIn general, \\code{do} blocks consist of lines (or sub-blocks) that\neither use the left arrow to introduce new names that are then available\nin the rest of the code, or are executed purely for side-effects. Bind\noperators are implicit between the lines of code. Incidentally, it is\npossible, in Haskell, to replace the formatting in the \\code{do}\nblocks with braces and semicolons. This provides the justification for\ndescribing the monad as a way of overloading the semicolon.\n\nNotice that the nesting of lambdas and bind operators when desugaring\nthe \\code{do} notation has the effect of influencing the execution of\nthe rest of the \\code{do} block based on the result of each line. This\nproperty can be used to introduce complex control structures, for\ninstance to simulate exceptions.\n\nInterestingly, the equivalent of the \\code{do} notation has found its\napplication in imperative languages, C++ in particular. I'm talking\nabout resumable functions or coroutines. It's not a secret that C++\n\\urlref{https://bartoszmilewski.com/2014/02/26/c17-i-see-a-monad-in-your-future/}{futures\n  form a monad}. It's an example of the continuation monad, which we'll\ndiscuss shortly. The problem with continuations is that they are very\nhard to compose. In Haskell, we use the \\code{do} notation to turn the\nspaghetti of ``my handler will call your handler'' into something that\nlooks very much like sequential code. Resumable functions make the same\ntransformation possible in C++. And the same mechanism can be applied to\nturn the\n\\urlref{https://bartoszmilewski.com/2014/04/21/getting-lazy-with-c/}{spaghetti\n  of nested loops} into list comprehensions or ``generators,'' which are\nessentially the \\code{do} notation for the list monad. Without the\nunifying abstraction of the monad, each of these problems is typically\naddressed by providing custom extensions to the language. In Haskell,\nthis is all dealt with through libraries.\n"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet01.hs",
    "content": "instance Monad [] where\n    join = concat\n    return x = [x]"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet02.hs",
    "content": "as >>= k = concat (fmap k as)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet03.hs",
    "content": "triples = do\n    z <- [1..]\n    x <- [1..z]\n    y <- [x..z]\n    guard (x^2 + y^2 == z^2)\n    return (x, y, z)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet04.hs",
    "content": "guard :: Bool -> [()]\nguard True = [()]\nguard False = []"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet05.hs",
    "content": "triples = [(x, y, z) | z <- [1..]\n                     , x <- [1..z]\n                     , y <- [x..z]\n                     , x^2 + y^2 == z^2]"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet06.hs",
    "content": "newtype Reader e a = Reader (e -> a)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet07.hs",
    "content": "runReader :: Reader e a -> e -> a\nrunReader (Reader f) e = f e"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet08.hs",
    "content": "ra >>= k = Reader (\\e -> ...)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet09.hs",
    "content": "ra >>= k = Reader (\\e -> let a = runReader ra e\n                         in ...)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet10.hs",
    "content": "ra >>= k = Reader (\\e -> let a  = runReader ra e\n                             rb = k a \n                         in ...)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet11.hs",
    "content": "ra >>= k = Reader (\\e -> let a = runReader ra e\n                             rb = k a\n                         in runReader rb e)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet12.hs",
    "content": "instance Monad (Reader e) where\n    ra >>= k = Reader (\\e -> runReader (k (runReader ra e)) e)\n    return x = Reader (\\e -> x)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet13.hs",
    "content": "newtype Writer w a = Writer (a, w)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet14.hs",
    "content": "runWriter :: Writer w a -> (a, w)\nrunWriter (Writer (a, w)) = (a, w)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet15.hs",
    "content": "instance (Monoid w) => Monad (Writer w) where\n    (Writer (a, w)) >>= k = let (a', w') = runWriter (k a)\n                            in Writer (a', w `mappend` w')\n    return a = Writer (a, mempty)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet16.hs",
    "content": "newtype State s a = State (s -> (a, s))"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet17.hs",
    "content": "runState :: State s a -> s -> (a, s)\nrunState (State f) s = f s"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet18.hs",
    "content": "sa >>= k = State (\\s -> let (a, s') = runState sa s\n                            sb = k a \n                        in runState sb s')"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet19.hs",
    "content": "instance Monad (State s) where\n    sa >>= k = State (\\s -> let (a, s') = runState sa s\n                            in runState (k a) s')\n    return a = State (\\s -> (a, s))"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet20.hs",
    "content": "get :: State s s\nget = State (\\s -> (s, s))"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet21.hs",
    "content": "put :: s -> State s ()\nput s' = State (\\s -> ((), s'))"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet22.hs",
    "content": "instance Monad Maybe where\n    Nothing >>= k = Nothing\n    Just a  >>= k = k a\n    return a = Just a"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet23.hs",
    "content": "data Cont r a = Cont ((a -> r) -> r)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet24.hs",
    "content": "runCont :: Cont r a -> (a -> r) -> r\nrunCont (Cont k) h = k h"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet25.hs",
    "content": "(>>=) :: ((a -> r) -> r) ->\n  (a -> (b -> r) -> r) ->\n  ((b -> r) -> r)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet26.hs",
    "content": "ka >>= kab = Cont (\\hb -> ...)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet27.hs",
    "content": "runCont ka (\\a -> ...)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet28.hs",
    "content": "runCont ka (\\a -> let kb = kab a \n                  in runCont kb hb)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet29.hs",
    "content": "instance Monad (Cont r) where\n  ka >>= kab = Cont (\\hb -> runCont ka (\\a -> runCont (kab a) hb))\n  return a = Cont (\\ha -> ha a)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet30.hs",
    "content": "getChar :: () -> IO Char"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet31.hs",
    "content": "main :: IO ()"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet32.hs",
    "content": "main :: () -> IO ()"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet33.hs",
    "content": "type IO a = RealWorld -> (a, RealWorld)"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet34.hs",
    "content": "type IO = State RealWorld"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet35.hs",
    "content": "putStr :: String -> IO ()"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet36.hs",
    "content": "putStr :: String -> ()"
  },
  {
    "path": "src/content/3.5/code/haskell/snippet37.hs",
    "content": "main :: IO () \nmain = do \n    putStr \"Hello \"\n    putStr \"World!\""
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet01.ml",
    "content": "module List_Monad : Monad_Join = struct\n  type 'a m = 'a list\n\n  let join = List.concat\n  let return a = [ a ]\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet02.ml",
    "content": "let ( >>= ) xs k = List.concat (List.map k xs)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet03.ml",
    "content": "module Pythagorean = struct\n  let ( let* ) = Fn.flip Gen.flat_map\n  let ( let+ ) x f = Gen.map f x\n  let guard b = if b then Gen.return () else Gen.empty\n\n  let triples =\n    let* z = Gen.init (fun i -> i + 1) in\n    let* x = Gen.init ~limit:z (fun i -> i + 1) in\n    let* y = Gen.init ~limit:z (fun i -> i + x) in\n    let+ _ = guard ((x * x) + (y * y) = z * z) in\n    Gen.return (x, y, z)\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet04.ml",
    "content": "let guard = function\n  | true  -> [ () ]\n  | false -> []\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet05.ml",
    "content": "module Pythagorean = struct\n  let ( let* ) = Fn.flip Gen.flat_map\n  let ( let+ ) x f = Gen.map f x\n  let guard b = if b then Gen.return () else Gen.empty\n\n  let triples =\n    let* z = Gen.init (fun i -> i + 1) in\n    let* x = Gen.init ~limit:z (fun i -> i + 1) in\n    let* y = Gen.init ~limit:z (fun i -> i + x) in\n    if (x * x) + (y * y) = z * z\n    then Gen.return (x, y, z)\n    else Gen.empty\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet06.ml",
    "content": "type ('e, 'a) reader = Reader of ('e -> 'a)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet07.ml",
    "content": "let run_reader (Reader f) e = f e\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet08.ml",
    "content": "let (>>=) ra k = Reader (fun e -> ...)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet09.ml",
    "content": "let (>>=) ra k = Reader (fun e -> \n  let a = run_reader ra e in\n  ...)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet10.ml",
    "content": "let (>>=) ra k = Reader (fun e ->\n  let a = run_reader ra e in\n  let rb = k a in\n  ...)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet11.ml",
    "content": "let ( >>= ) ra k =\n  Reader\n    (fun e ->\n      let a = run_reader ra e in\n      let rb = k a in\n      run_reader rb e)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet12.ml",
    "content": "module ReaderMonad (T : sig\n  type t\nend) : Monad_Bind = struct\n  type 'a m = (T.t, 'a) reader\n\n  let return a = Reader (fun e -> a)\n\n  let ( >>= ) ra k =\n    Reader (fun e -> run_reader (k (run_reader ra e)) e)\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet13.ml",
    "content": "type ('w, 'a) writer = Writer of ('a * 'w)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet14.ml",
    "content": "let run_writer (Writer (a, w)) = a, w\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet15.ml",
    "content": "module WriterMonad (W : Monoid) : Monad_Bind = struct\n  type 'a m = (W.t, 'a) writer\n\n  let return a = Writer (a, W.mempty)\n\n  let ( >>= ) (Writer (a, w)) k =\n    let a', w' = run_writer (k a) in\n    Writer (a', W.mappend w w')\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet16.ml",
    "content": "type ('s, 'a) state = State of ('s -> 'a * 's)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet17.ml",
    "content": "let run_state (State f) s = f s\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet18.ml",
    "content": "let ( >>= ) sa k =\n  State\n    (fun s ->\n      let a, s' = run_state sa s in\n      let sb = k a in\n      run_state sb s')\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet19.ml",
    "content": "module State_Monad (S : sig\n  type t\nend) : Monad_Bind = struct\n  type 'a m = (S.t, 'a) state\n\n  let ( >>= ) sa k =\n    State\n      (fun s ->\n        let a, s' = run_state sa s in\n        let sb = k a in\n        run_state sb s')\n\n\n  let return a = State (fun s -> a, s)\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet20.ml",
    "content": "let get = State (fun s -> s, s)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet21.ml",
    "content": "let put s' = State (fun s -> (), s')\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet22.ml",
    "content": "module OptionMonad : Monad_Bind = struct\n  type 'a m = 'a option\n\n  let ( >>= ) = function\n    | Some a -> fun k -> k a\n    | None   -> fun _ -> None\n\n\n  let return a = Some a\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet23.ml",
    "content": "type ('r, 'a) cont = Cont of (('a -> 'r) -> 'r)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet24.ml",
    "content": "let run_cont (Cont k) h = k h\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet25.ml",
    "content": "val ( >>= )\n  :  (('a -> 'r) -> 'r)\n  -> ('a -> ('b -> 'r) -> 'r)\n  -> ('b -> 'r)\n  -> 'r\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet26.ml",
    "content": "let (>>=) ka kab = Cont (fun hb -> ...)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet27.ml",
    "content": "run_cont ka (fun a -> ...)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet28.ml",
    "content": ";;\nrun_cont ka (fun a ->\n    let kb = kab a in\n    run_cont kb hb)\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet29.ml",
    "content": "module Cont_Monad (R : sig\n  type t\nend) : Monad_Bind = struct\n  type 'a m = (R.t, 'a) cont\n\n  let return a = Cont (fun ha -> ha a)\n\n  let ( >>= ) ka kab =\n    Cont (fun hb -> run_cont ka (fun a -> run_cont (kab a) hb))\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet30.ml",
    "content": "module type Terminal_IO = sig\n  (* OCaml doesn't have a built-in IO type*)\n  type 'a io = IO of (unit -> 'a)\n\n  val get_char : unit -> char io\nend\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet31.ml",
    "content": "val main : unit io\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet32.ml",
    "content": "val main : unit -> unit io\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet33.ml",
    "content": "type 'a io = realworld -> 'a * realworld\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet34.ml",
    "content": "type 'a io = realworld state\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet35.ml",
    "content": "val put_str : string -> unit io\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet36.ml",
    "content": "val put_str : string -> unit\n"
  },
  {
    "path": "src/content/3.5/code/ocaml/snippet37.ml",
    "content": "(* Monad implementation for type io *)\nmodule IOMonad : Monad_Bind with type 'a m = 'a io = struct\n  type 'a m = 'a io\n\n  let return x = IO (fun () -> x)\n\n  let ( >>= ) m f =\n    IO\n      (fun () ->\n        let (IO m') = m in\n        let (IO m'') = f (m' ()) in\n        m'' ())\nend\n\n(* main *)\nmodule IO_Main = struct\n  let ( let* ) = IOMonad.( >>= )\n\n  let main =\n    let* _ = put_str \"Hello\" in\n    put_str \"world!\"\nend\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet01.re",
    "content": "module List_Monad: Monad_Join = {\n  type m('a) = list('a);\n\n  let join = List.concat;\n  let return = a => [a];\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet02.re",
    "content": "let (>>=) = (xs, k) => List.concat(List.map(k, xs));\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet03.re",
    "content": "module Pythagorean = {\n  let (let*) = Fn.flip(Gen.flat_map);\n  let (let+) = (x, f) => Gen.map(f, x);\n  let guard = b => b ? Gen.return() ? Gen.empty;\n\n  let triples = {\n    let* z = Gen.init(i => i + 1);\n    let* x = Gen.init(~limit=z, i => i + 1);\n    let* y = Gen.init(~limit=z, i => i + x);\n    let+ _ = guard(x * x + y * y == z * z);\n    Gen.return((x, y, z));\n  };\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet04.re",
    "content": "let guard =\n  fun\n  | true => [()]\n  | false => [];\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet05.re",
    "content": "module Pythagorean = {\n  let (let*) = Fn.flip(Gen.flat_map);\n  let (let+) = (x, f) => Gen.map(f, x);\n  let guard = b => b ? Gen.return() : Gen.empty;\n\n  let triples = {\n    let* z = Gen.init(i => i + 1);\n    let* x = Gen.init(~limit=z, i => i + 1);\n    let* y = Gen.init(~limit=z, i => i + x);\n    if (x * x + y * y == z * z) {\n      Gen.return((x, y, z));\n    } else {\n      Gen.empty;\n    };\n  };\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet06.re",
    "content": "type reader('e, 'a) =\n  | Reader('e => 'a);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet07.re",
    "content": "let run_reader = (Reader(f), e) => f(e);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet08.re",
    "content": "let (>>=) = (ra, k) => Reader(e => ...);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet09.re",
    "content": "let (>>=) = (ra, k) => Reader(e => {\n  let a = run_reader(ra, e);\n  ...\n});"
  },
  {
    "path": "src/content/3.5/code/reason/snippet10.re",
    "content": "let (>>=) = (ra, k) => Reader(e => {\n  let a = run_reader(ra, e);\n  let rb = k(a);\n  ...\n});"
  },
  {
    "path": "src/content/3.5/code/reason/snippet11.re",
    "content": "let (>>=) = (ra, k) => Reader(e => {\n  let a = run_reader(ra, e);\n  let rb = k(a);\n  run_reader(rb, e);\n});\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet12.re",
    "content": "module ReaderMonad = (T: {type t;}) : Monad_Bind => {\n  type m('a) = reader(T.t, 'a);\n\n  let return = a => Reader(e => a);\n\n  let (>>=) = (ra, k) => \n    Reader(e => run_reader(k(run_reader(ra, e)), e));\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet13.re",
    "content": "type writer('w, 'a) =\n  | Writer(('a, 'w));\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet14.re",
    "content": "let run_writer = (Writer(a, w)) => (a, w);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet15.re",
    "content": "module WriterMonad = (W: Monoid) : Monad_Bind => {\n  type m('a) = writer(W.t, 'a);\n\n  let return = a => Writer(a, W.mempty);\n\n  let (>>=) = (Writer(a, w), k) => {\n    let (a', w') = run_writer(k(a));\n    Writer(a', W.mappend(w, w'));\n  };\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet16.re",
    "content": "type state('s, 'a) =\n  | State('s => ('a, 's));\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet17.re",
    "content": "let run_state = (State(f), s) => f(s);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet18.re",
    "content": "let (>>=) = (sa, k) => State(s => {\n  let (a, s') = run_state(sa, s);\n  let sb = k(a);\n  run_state(sb, s');\n});\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet19.re",
    "content": "module State_Monad = (S: {type t;}) : Monad_Bind => {\n  type m('a) = state(S.t, 'a);\n\n  let (>>=) = (sa, k) => State(s => {\n    let (a, s') = run_state(sa, s);\n    let sb = k(a);\n    run_state(sb, s');\n  });\n\n  let return = a => State(s => (a, s));\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet20.re",
    "content": "let get = State(s => (s, s));\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet21.re",
    "content": "let put = s' => State(s => ((), s'));\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet22.re",
    "content": "module OptionMonad: Monad_Bind = {\n  type m('a) = option('a);\n\n  let (>>=) =\n    fun\n    | Some(a) => (k => k(a))\n    | None => (_ => None);\n\n  let return = a => Some(a);\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet23.re",
    "content": "type cont('r, 'a) =\n  | Cont(('a => 'r) => 'r);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet24.re",
    "content": "let run_cont = (Cont(k), h) => k(h);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet25.re",
    "content": "let (>>=): (('a => 'r) => 'r, \n  ('a, 'b => 'r) => 'r, \n  'b => 'r) => 'r;\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet26.re",
    "content": "let (>>=) = (ka, kab) => Cont(hb => ...);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet27.re",
    "content": "run_cont(ka, a => ...);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet28.re",
    "content": "run_cont(ka,a => {\n  let kb = kab(a);\n  run_cont(kb, hb);\n});\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet29.re",
    "content": "module Cont_Monad = (R: {type t;}) : Monad_Bind => {\n  type m('a) = cont(R.t, 'a);\n\n  let return = a => Cont(ha => ha(a));\n\n  let (>>=) = (ka, kab) =>\n    Cont(hb => run_cont(ka, a => run_cont(kab(a), hb)));\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet30.re",
    "content": "module type Terminal_IO = {\n  /* ReasonML doesn't have a built-in IO type*/\n  type io('a) =\n    | IO(unit => 'a);\n\n  let get_char: unit => io(char);\n};\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet31.re",
    "content": "let main: io(unit);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet32.re",
    "content": "let main: unit => io(unit);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet33.re",
    "content": "type io('a) = realworld => ('a, realworld);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet34.re",
    "content": "type io('a) = state(realworld);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet35.re",
    "content": "let put_str: string => io(unit);\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet36.re",
    "content": "let put_str: string => unit;\n"
  },
  {
    "path": "src/content/3.5/code/reason/snippet37.re",
    "content": "/* Monad implementation for type io */\nmodule IOMonad: Monad_Bind with type m('a) = io('a) = {\n  type m('a) = io('a);\n\n  let return = x => IO(() => x);\n\n  let (>>=) = (m, f) => IO(() => {\n    let IO(m') = m;\n    let IO(m'') = f(m'());\n    m''();\n  });\n};\n\n/* main */\nmodule IO_Main = {\n  let (let*) = IOMonad.(>>=);\n\n  let main = {\n    let* _ = put_str(\"Hello\");\n    put_str(\"world!\");\n  };\n};\n"
  },
  {
    "path": "src/content/3.5/code/scala/snippet01.scala",
    "content": "implicit val listMonad = new Monad[List] {\n  def flatten[A](mma: List[List[A]]): List[A] =\n    mma.reduce(_ ++ _)\n\n  def pure[A](a: A): List[A] = List(a)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet02.scala",
    "content": "def flatMap[A, B](as: List[A])(k: A => List[B]): List[B] =\n  flatten(fmap(k)(as))"
  },
  {
    "path": "src/content/3.5/code/scala/snippet03.scala",
    "content": "// Streams in Scala can be\n// thought of as lazy lists\ndef triples = for {\n  z <- Stream.from(1)\n  x <- 1 to z\n  y <- x to z\n  _ <- guard(x * x + y * y == z * z)\n} yield (x, y, z)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet04.scala",
    "content": "def guard: Boolean => List[Unit] = {\n  case true => List(())\n  case false => List.empty[Unit]\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet05.scala",
    "content": "def triples = for {\n  z <- Stream.from(1)\n  x <- 1 to z\n  y <- x to z\n  if x * x + y * y == z * z\n} yield (x, y, z)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet06.scala",
    "content": "case class Reader[E, A](run: E => A)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet07.scala",
    "content": "def runReader[E, A]: Reader[E, A] => E => A = {\n  case Reader(f) => e => f(e)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet08.scala",
    "content": "def flatMap[A, B](ra: Reader[E, A])(k: A => Reader[E, B]): Reader[E, B] =\n  Reader { e => ... }"
  },
  {
    "path": "src/content/3.5/code/scala/snippet09.scala",
    "content": "def flatMap[A, B](ra: Reader[E, A])(k: A => Reader[E, B]): Reader[E, B] =\n  Reader { e =>\n    val a = runReader(ra)(e)\n    ...\n  }"
  },
  {
    "path": "src/content/3.5/code/scala/snippet10.scala",
    "content": "def flatMap[A, B](ra: Reader[E, A])(k: A => Reader[E, B]): Reader[E, B] =\n  Reader { e =>\n    val a = runReader(ra)(e)\n    val rb = k(a)\n    ...\n  }"
  },
  {
    "path": "src/content/3.5/code/scala/snippet11.scala",
    "content": "def flatMap[A, B](ra: Reader[E, A])(k: A => Reader[E, B]): Reader[E, B] =\n  Reader { e =>\n    val a = runReader(ra)(e)\n    val rb = k(a)\n    runReader(rb)(e)\n  }"
  },
  {
    "path": "src/content/3.5/code/scala/snippet12.scala",
    "content": "implicit def readerMonad[E] = new Monad[Reader[E, ?]] {\n  def pure[A](x: A): Reader[E, A] =\n    Reader(e => x)\n  \n  def flatMap[A, B](ra: Reader[E, A])(k: A => Reader[E, B]): Reader[E, B] =\n    Reader(e =>\n      runReader(k(runReader(ra)(e)))(e))\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet13.scala",
    "content": "case class Writer[W, A](run: (A, W))"
  },
  {
    "path": "src/content/3.5/code/scala/snippet14.scala",
    "content": "def runWriter[W, A]: Writer[W, A] => (A, W) = {\n  case Writer((a, w)) => (a, w)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet15.scala",
    "content": "implicit def writerMonad[W: Monoid] = new Monad[Writer[W, ?]] {\n  def flatMap[A, B](wa: Writer[W, A])(k: A => Writer[W, B]): Writer[W, B] =\n    wa match {\n      case Writer((a, w)) =>\n        val ((a1, w1)) = runWriter(k(a))\n        Writer((a1, Monoid[W].combine(w, w1)))\n    }\n\n  def pure[A](a: A) = Writer(a, Monoid[W].empty)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet16.scala",
    "content": "case class State[S, A](run: S => (A, S))"
  },
  {
    "path": "src/content/3.5/code/scala/snippet17.scala",
    "content": "def runState[S, A]: State[S, A] => S => (A, S) = {\n  case State(f) => s => f(s)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet18.scala",
    "content": "def flatMap[A, B](sa: State[S, A])(k: A => State[S, B]): State[S, B] =\n  State { s =>\n    val (a, s1) = runState(sa)(s)\n    val sb = k(a)\n    runState(sb)(s1)\n  }"
  },
  {
    "path": "src/content/3.5/code/scala/snippet19.scala",
    "content": "implicit def stateMonad[S] = new Monad[State[S, ?]] {\n  def flatMap[A, B](sa: State[S, A])(k: A => State[S, B]): State[S, B] =\n    State { s =>\n      val (a, s1) = runState(sa)(s)\n      runState(k(a))(s1)\n    }\n  \n  def pure[A](a: A): State[S, A] = State(s => (a, s))\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet20.scala",
    "content": "def get: State[S, S] = State(s => (s, s))"
  },
  {
    "path": "src/content/3.5/code/scala/snippet21.scala",
    "content": "def put(s1: S): State[S, Unit] = State(s => ((), s1))"
  },
  {
    "path": "src/content/3.5/code/scala/snippet22.scala",
    "content": "implicit val optionMonad = new Monad[Option] {\n  def flatMap[A, B](ma: Option[A])(k: A => Option[B]): Option[B] = \n    ma match {\n      case None => None\n      case Some(a) => k(a)\n  }\n\n  def pure[A](a: A): Option[A] = Some(a)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet23.scala",
    "content": "case class Cont[R, A](run: (A => R) => R)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet24.scala",
    "content": "def runCont[R, A]: Cont[R, A] => (A => R) => R = {\n  case Cont(k) => h => k(h)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet25.scala",
    "content": "def flatMap[A, B]: ((A => R) => R) =>\n    (A => (B => R) => R) =>\n    ((B => R) => R)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet26.scala",
    "content": "def flatMap[A, B](ka: Cont[R, A])(kab: A => Cont[R, B]): Cont[R, B] =\n  Cont(hb => ...)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet27.scala",
    "content": "runCont(ka)(a => ...)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet28.scala",
    "content": "runCont(ka) { a =>\n  val kb = kab(a)\n  runCont(kb)(hb)\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet29.scala",
    "content": "implicit def contMonad[R] = new Monad[Cont[R, ?]] {\n  def flatMap[A, B](ka: Cont[R, A])(kab: A => Cont[R, B]): Cont[R, B] =\n    Cont { hb =>\n      runCont(ka)(a => runCont(kab(a))(hb))\n    }\n\n  def pure[A](a: A): Cont[R, A] =\n    Cont(ha => ha(a))\n}"
  },
  {
    "path": "src/content/3.5/code/scala/snippet30.scala",
    "content": "def getChar: Unit => IO[Char]\n"
  },
  {
    "path": "src/content/3.5/code/scala/snippet31.scala",
    "content": "def main: IO[Unit]"
  },
  {
    "path": "src/content/3.5/code/scala/snippet32.scala",
    "content": "def main: Unit => IO[Unit]"
  },
  {
    "path": "src/content/3.5/code/scala/snippet33.scala",
    "content": "type IO[A] = RealWorld => (A, RealWorld)"
  },
  {
    "path": "src/content/3.5/code/scala/snippet34.scala",
    "content": "type IO[A] = State[RealWorld, A]"
  },
  {
    "path": "src/content/3.5/code/scala/snippet35.scala",
    "content": "def putStr: String => IO[Unit]"
  },
  {
    "path": "src/content/3.5/code/scala/snippet36.scala",
    "content": "def putStr: String => Unit"
  },
  {
    "path": "src/content/3.5/code/scala/snippet37.scala",
    "content": "def main: IO[Unit] = for {\n  _ <- putStr(\"Hello \")\n  _ <- putStr(\"World!\")\n} yield ()"
  },
  {
    "path": "src/content/3.5/monads-and-effects.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{N}{ow that we know} what the monad is for --- it lets us compose\nembellished functions --- the really interesting question is why\nembellished functions are so important in functional programming. We've\nalready seen one example, the \\code{Writer} monad, where embellishment\nlet us create and accumulate a log across multiple function calls. A\nproblem that would otherwise be solved using impure functions (e.g., by\naccessing and modifying some global state) was solved with pure\nfunctions.\n\n\\section{The Problem}\n\nHere is a short list of similar problems, copied from\nEugenio Moggi's seminal paper,\\footnote{Eugenio Moggi:\n  \\href{https://doi.org/10.1016/0890-5401(91)90052-4}{\n    Notions of Computation and Monads}. Inf. Comput. 93(1): 55-92 (1991).}\nall of which are traditionally solved by abandoning the purity of functions.\n\n\\begin{itemize}\n  \\tightlist\n  \\item\n        Partiality: Computations that may not terminate\n  \\item\n        Nondeterminism: Computations that may return many results\n  \\item\n        Side effects: Computations that access/modify state\n\n        \\begin{itemize}\n          \\tightlist\n          \\item\n                Read-only state, or the environment\n          \\item\n                Write-only state, or a log\n          \\item\n                Read/write state\n        \\end{itemize}\n  \\item\n        Exceptions: Partial functions that may fail\n  \\item\n        Continuations: Ability to save state of the program and then restore\n        it on demand\n  \\item\n        Interactive Input\n  \\item\n        Interactive Output\n\\end{itemize}\n\nWhat really is mind blowing is that all these problems may be solved\nusing the same clever trick: turning to embellished functions. Of\ncourse, the embellishment will be totally different in each case.\n\nYou have to realize that, at this stage, there is no requirement that\nthe embellishment be monadic. It's only when we insist on composition\n--- being able to decompose a single embellished function into smaller\nembellished functions --- that we need a monad. Again, since each of the\nembellishments is different, monadic composition will be implemented\ndifferently, but the overall pattern is the same. It's a very simple\npattern: composition that is associative and equipped with identity.\n\nThe next section is heavy on Haskell examples. Feel free to skim or even\nskip it if you're eager to get back to category theory or if you're\nalready familiar with Haskell's implementation of monads.\n\n\\section{The Solution}\n\nFirst, let's analyze the way we used the \\code{Writer} monad. We\nstarted with a pure function that performed a certain task --- given\narguments, it produced a certain output. We replaced this function with\nanother function that embellished the original output by pairing it with\na string. That was our solution to the logging problem.\n\nWe couldn't stop there because, in general, we don't want to deal with\nmonolithic solutions. We needed to be able to decompose one\nlog-producing function into smaller log-producing functions. It's the\ncomposition of those smaller functions that led us to the concept of a\nmonad.\n\nWhat's really amazing is that the same pattern of embellishing the\nfunction return types works for a large variety of problems that\nnormally would require abandoning purity. Let's go through our list and\nidentify the embellishment that applies to each problem in turn.\n\n\\subsection{Partiality}\n\nWe modify the return type of every function that may not terminate by\nturning it into a ``lifted'' type --- a type that contains all values of\nthe original type plus the special ``bottom'' value $\\bot$. For\ninstance, the \\code{Bool} type, as a set, would contain two elements:\n\\code{True} and \\code{False}. The lifted \\code{Bool} contains\nthree elements. Functions that return the lifted \\code{Bool} may\nproduce \\code{True} or \\code{False}, or execute forever.\n\nThe funny thing is that, in a lazy language like Haskell, a never-ending\nfunction may actually return a value, and this value may be passed to\nthe next function. We call this special value the bottom. As long as\nthis value is not explicitly needed (for instance, to be pattern\nmatched, or produced as output), it may be passed around without\nstalling the execution of the program. Because every Haskell function\nmay be potentially non-terminating, all types in Haskell are assumed to\nbe lifted. This is why we often talk about the category $\\Hask$ of\nHaskell (lifted) types and functions rather than the simpler\n$\\Set$. It is not clear, though, that $\\Hask$ is a real\ncategory (see this\n\\urlref{http://math.andrej.com/2016/08/06/hask-is-not-a-category/}{Andrej\n  Bauer post}).\n\n\\subsection{Nondeterminism}\n\nIf a function can return many different results, it may as well return\nthem all at once. Semantically, a non-deterministic function is\nequivalent to a function that returns a list of results. This makes a\nlot of sense in a lazy garbage-collected language. For instance, if all\nyou need is one value, you can just take the head of the list, and the\ntail will never be evaluated. If you need a random value, use a random\nnumber generator to pick the n-th element of the list. Laziness even\nallows you to return an infinite list of results.\n\nIn the list monad --- Haskell's implementation of nondeterministic\ncomputations --- \\code{join} is implemented as \\code{concat}.\nRemember that \\code{join} is supposed to flatten a container of\ncontainers --- \\code{concat} concatenates a list of lists into a\nsingle list. \\code{return} creates a singleton list:\n\n\\src{snippet01}\nThe bind operator for the list monad is given by the general formula:\n\\code{fmap} followed by \\code{join} which, in this case gives:\n\n\\src{snippet02}\nHere, the function \\code{k}, which itself produces a list, is applied\nto every element of the list \\code{as}. The result is a list of lists,\nwhich is flattened using \\code{concat}.\n\nFrom the programmer's point of view, working with a list is easier than,\nfor instance, calling a non-deterministic function in a loop, or\nimplementing a function that returns an iterator (although,\n\\urlref{http://ericniebler.com/2014/04/27/range-comprehensions/}{in modern\n  C++}, returning a lazy range would be almost equivalent to returning a\nlist in Haskell).\n\nA good example of using non-determinism creatively is in game\nprogramming. For instance, when a computer plays chess against a human,\nit can't predict the opponent's next move. It can, however, generate a\nlist of all possible moves and analyze them one by one. Similarly, a\nnon-deterministic parser may generate a list of all possible parses for\na given expression.\n\nEven though we may interpret functions returning lists as\nnon-deterministic, the applications of the list monad are much wider.\nThat's because stitching together computations that produce lists is a\nperfect functional substitute for iterative constructs --- loops ---\nthat are used in imperative programming. A single loop can be often\nrewritten using \\code{fmap} that applies the body of the loop to each\nelement of the list. The \\code{do} notation in the list monad can be\nused to replace complex nested loops.\n\nMy favorite example is the program that generates Pythagorean triples\n--- triples of positive integers that can form sides of right triangles.\n\n\\src{snippet03}\nThe first line tells us that \\code{z} gets an element from an infinite\nlist of positive numbers \\code{{[}1..{]}}. Then \\code{x} gets an\nelement from the (finite) list \\code{{[}1..z{]}} of numbers between 1\nand \\code{z}. Finally \\code{y} gets an element from the list of\nnumbers between \\code{x} and \\code{z}. We have three numbers\n$1 \\leqslant x \\leqslant y \\leqslant z$ at our\ndisposal. The function \\code{guard} takes a \\code{Bool} expression\nand returns a list of units:\n\n\\src{snippet04}\nThis function (which is a member of a larger class called\n\\code{MonadPlus}) is used here to filter out non-Pythagorean triples.\nIndeed, if you look at the implementation of bind (or the related\noperator \\code{>>}), you'll notice that,\nwhen given an empty list, it produces an empty list. On the other hand,\nwhen given a non-empty list (here, the singleton list containing unit\n\\code{{[}(){]}}), bind will call the continuation, here\n\\code{return (x, y, z)}, which produces a singleton list with a\nverified Pythagorean triple. All those singleton lists will be\nconcatenated by the enclosing binds to produce the final (infinite)\nresult. Of course, the caller of \\code{triples} will never be able to\nconsume the whole list, but that doesn't matter, because Haskell is\nlazy.\n\nThe problem that normally would require a set of three nested loops has\nbeen dramatically simplified with the help of the list monad and the\n\\code{do} notation. As if that weren't enough, Haskell let's you\nsimplify this code even further using list comprehension:\n\n\\src{snippet05}\nThis is just further syntactic sugar for the list monad (strictly\nspeaking, \\code{MonadPlus}).\n\nYou might see similar constructs in other functional or imperative\nlanguages under the guise of generators and coroutines.\n\n\\subsection{Read-Only State}\n\nA function that has read-only access to some external state, or\nenvironment, can be always replaced by a function that takes that\nenvironment as an additional argument. A pure function\n\\code{(a, e) -> b} (where \\code{e} is the type of\nthe environment) doesn't look, at first sight, like a Kleisli arrow. But\nas soon as we curry it to\n\\code{a -> (e -> b)} we recognize the\nembellishment as our old friend the reader functor:\n\n\\src{snippet06}\nYou may interpret a function returning a \\code{Reader} as producing a\nmini-executable: an action that given an environment produces the\ndesired result. There is a helper function \\code{runReader} to execute\nsuch an action:\n\n\\src{snippet07}\nIt may produce different results for different values of the\nenvironment.\n\nNotice that both the function returning a \\code{Reader}, and the\n\\code{Reader} action itself are pure.\n\nTo implement bind for the \\code{Reader} monad, first notice that you\nhave to produce a function that takes the environment \\code{e} and\nproduces a \\code{b}:\n\n\\src{snippet08}\nInside the lambda, we can execute the action \\code{ra} to produce an\n\\code{a}:\n\n\\src{snippet09}\nWe can then pass the \\code{a} to the continuation \\code{k} to get a\nnew action \\code{rb}:\n\n\\src{snippet10}\nFinally, we can run the action \\code{rb} with the environment\n\\code{e}:\n\n\\src{snippet11}\nTo implement \\code{return} we create an action that ignores the\nenvironment and returns the unchanged value.\n\nPutting it all together, after a few simplifications, we get the\nfollowing definition:\n\n\\src{snippet12}\n\n\\subsection{Write-Only State}\n\nThis is just our initial logging example. The embellishment is given by\nthe \\code{Writer} functor:\n\n\\src{snippet13}\nFor completeness, there's also a trivial helper \\code{runWriter} that\nunpacks the data constructor:\n\n\\src{snippet14}\nAs we've seen before, in order to make \\code{Writer} composable,\n\\code{w} has to be a monoid. Here's the monad instance for\n\\code{Writer} written in terms of the bind operator:\n\n\\src{snippet15}\n\n\\subsection{State}\n\nFunctions that have read/write access to state combine the\nembellishments of the \\code{Reader} and the \\code{Writer}. You may\nthink of them as pure functions that take the state as an extra argument\nand produce a pair value/state as a result:\n\\code{(a, s) -> (b, s)}. After currying, we get them\ninto the form of Kleisli arrows\n\\code{a -> (s -> (b, s))}, with the\nembellishment abstracted in the \\code{State} functor:\n\n\\src{snippet16}\nAgain, we can look at a Kleisli arrow as returning an action, which can\nbe executed using the helper function:\n\n\\src{snippet17}\nDifferent initial states may not only produce different results, but\nalso different final states.\n\nThe implementation of bind for the \\code{State} monad is very similar\nto that of the \\code{Reader} monad, except that care has to be taken\nto pass the correct state at each step:\n\n\\src{snippet18}\nHere's the full instance:\n\n\\src{snippet19}\nThere are also two helper Kleisli arrows that may be used to manipulate\nthe state. One of them retrieves the state for inspection:\n\n\\src{snippet20}\nand the other replaces it with a completely new state:\n\n\\src{snippet21}\n\n\\subsection{Exceptions}\n\nAn imperative function that throws an exception is really a partial\nfunction --- it's a function that's not defined for some values of its\narguments. The simplest implementation of exceptions in terms of pure\ntotal functions uses the \\code{Maybe} functor. A partial function is\nextended to a total function that returns \\code{Just a} whenever it\nmakes sense, and \\code{Nothing} when it doesn't. If we want to also\nreturn some information about the cause of the failure, we can use the\n\\code{Either} functor instead (with the first type fixed, for\ninstance, to \\code{String}).\n\nHere's the \\code{Monad} instance for \\code{Maybe}:\n\n\\src{snippet22}\nNotice that monadic composition for \\code{Maybe} correctly\nshort-circuits the computation (the continuation \\code{k} is never\ncalled) when an error is detected. That's the behavior we expect from\nexceptions.\n\n\\subsection{Continuations}\n\nIt's the ``Don't call us, we'll call you!'' situation you may experience\nafter a job interview. Instead of getting a direct answer, you are\nsupposed to provide a handler, a function to be called with the result.\nThis style of programming is especially useful when the result is not\nknown at the time of the call because, for instance, it's being\nevaluated by another thread or delivered from a remote web site. A\nKleisli arrow in this case returns a function that accepts a handler,\nwhich represents ``the rest of the computation'':\n\n\\src{snippet23}\nThe handler \\code{a -> r}, when it's eventually called,\nproduces the result of type \\code{r}, and this result is returned at\nthe end. A continuation is parameterized by the result type. (In\npractice, this is often some kind of status indicator.)\n\nThere is also a helper function for executing the action returned by the\nKleisli arrow. It takes the handler and passes it to the continuation:\n\n\\src{snippet24}\nThe composition of continuations is notoriously difficult, so its\nhandling through a monad and, in particular, the \\code{do} notation,\nis of extreme advantage.\n\nLet's figure out the implementation of bind. First let's look at the\nstripped down signature:\n\n\\src{snippet25}\nOur goal is to create a function that takes the handler\n\\code{(b -> r)} and produces the result \\code{r}. So\nthat's our starting point:\n\n\\src{snippet26}\nInside the lambda, we want to call the function \\code{ka} with the\nappropriate handler that represents the rest of the computation. We'll\nimplement this handler as a lambda:\n\n\\src{snippet27}\nIn this case, the rest of the computation involves first calling\n\\code{kab} with \\code{a}, and then passing \\code{hb} to the\nresulting action \\code{kb}:\n\n\\src{snippet28}\nAs you can see, continuations are composed inside out. The final handler\n\\code{hb} is called from the innermost layer of the computation.\nHere's the full instance:\n\n\\src{snippet29}\n\n\\subsection{Interactive Input}\n\nThis is the trickiest problem and a source of a lot of confusion.\nClearly, a function like \\code{getChar}, if it were to return a\ncharacter typed at the keyboard, couldn't be pure. But what if it\nreturned the character inside a container? As long as there was no way\nof extracting the character from this container, we could claim that the\nfunction is pure. Every time you call \\code{getChar} it would return\nexactly the same container. Conceptually, this container would contain\nthe superposition of all possible characters.\n\nIf you're familiar with quantum mechanics, you should have no problem\nunderstanding this analogy. It's just like the box with the\nSchrödinger's cat inside --- except that there is no way to open or peek\ninside the box. The box is defined using the special built-in\n\\code{IO} functor. In our example, \\code{getChar} could be declared\nas a Kleisli arrow:\n\n\\src{snippet30}\n(Actually, since a function from the unit type is equivalent to picking\na value of the return type, the declaration of \\code{getChar} is\nsimplified to \\code{getChar :: IO Char}.)\n\nBeing a functor, \\code{IO} lets you manipulate its contents using\n\\code{fmap}. And, as a functor, it can store the contents of any type,\nnot just a character. The real utility of this approach comes to light\nwhen you consider that, in Haskell, \\code{IO} is a monad. It means\nthat you are able to compose Kleisli arrows that produce \\code{IO}\nobjects.\n\nYou might think that Kleisli composition would allow you to peek at the\ncontents of the \\code{IO} object (thus ``collapsing the wave\nfunction,'' if we were to continue the quantum analogy). Indeed, you\ncould compose \\code{getChar} with another Kleisli arrow that takes a\ncharacter and, say, converts it to an integer. The catch is that this\nsecond Kleisli arrow could only return this integer as an\n\\code{(IO\\ Int)}. Again, you'll end up with a superposition of all\npossible integers. And so on. The Schrödinger's cat is never out of the\nbag. Once you are inside the \\code{IO} monad, there is no way out of\nit. There is no equivalent of \\code{runState} or \\code{runReader}\nfor the \\code{IO} monad. There is no \\code{runIO}!\n\nSo what can you do with the result of a Kleisli arrow, the \\code{IO}\nobject, other than compose it with another Kleisli arrow? Well, you can\nreturn it from \\code{main}. In Haskell, \\code{main} has the\nsignature:\n\n\\src{snippet31}\nand you are free to think of it as a Kleisli arrow:\n\n\\src{snippet32}\nFrom that perspective, a Haskell program is just one big Kleisli arrow\nin the \\code{IO} monad. You can compose it from smaller Kleisli arrows\nusing monadic composition. It's up to the runtime system to do something\nwith the resulting \\code{IO} object (also called \\code{IO} action).\n\nNotice that the arrow itself is a pure function --- it's pure functions\nall the way down. The dirty work is relegated to the system. When it\nfinally executes the \\code{IO} action returned from \\code{main}, it\ndoes all kinds of nasty things like reading user input, modifying files,\nprinting obnoxious messages, formatting a disk, and so on. The Haskell\nprogram never dirties its hands (well, except when it calls\n\\code{unsafePerformIO}, but that's a different story).\n\nOf course, because Haskell is lazy, \\code{main} returns almost\nimmediately, and the dirty work begins right away. It's during the\nexecution of the \\code{IO} action that the results of pure\ncomputations are requested and evaluated on demand. So, in reality, the\nexecution of a program is an interleaving of pure (Haskell) and dirty\n(system) code.\n\nThere is an alternative interpretation of the \\code{IO} monad that is\neven more bizarre but makes perfect sense as a mathematical model. It\ntreats the whole Universe as an object in a program. Notice that,\nconceptually, the imperative model treats the Universe as an external\nglobal object, so procedures that perform I/O have side effects by\nvirtue of interacting with that object. They can both read and modify\nthe state of the Universe.\n\nWe already know how to deal with state in functional programming --- we\nuse the state monad. Unlike simple state, however, the state of the\nUniverse cannot be easily described using standard data structures. But\nwe don't have to, as long as we never directly interact with it. It's\nenough that we assume that there exists a type \\code{RealWorld} and,\nby some miracle of cosmic engineering, the runtime is able to provide an\nobject of this type. An \\code{IO} action is just a function:\n\n\\src{snippet33}\nOr, in terms of the \\code{State} monad:\n\n\\src{snippet34}\nHowever, \\code{>=>} and \\code{return} for\nthe \\code{IO} monad have to be built into the language.\n\n\\subsection{Interactive Output}\n\nThe same \\code{IO} monad is used to encapsulate interactive output.\n\\code{RealWorld} is supposed to contain all output devices. You might\nwonder why we can't just call output functions from Haskell and pretend\nthat they do nothing. For instance, why do we have:\n\n\\src{snippet35}\nrather than the simpler:\n\n\\src{snippet36}\nTwo reasons: Haskell is lazy, so it would never call a function whose\noutput --- here, the unit object --- is not used for anything. And, even\nif it weren't lazy, it could still freely change the order of such calls\nand thus garble the output. The only way to force sequential execution\nof two functions in Haskell is through data dependency. The input of one\nfunction must depend on the output of another. Having \\code{RealWorld}\npassed between \\code{IO} actions enforces sequencing.\n\nConceptually, in this program:\n\n\\src{snippet37}\nthe action that prints ``World!'' receives, as input, the Universe in\nwhich ``Hello '' is already on the screen. It outputs a new Universe,\nwith ``Hello World!'' on the screen.\n\n\\section{Conclusion}\n\nOf course I have just scratched the surface of monadic programming.\nMonads not only accomplish, with pure functions, what normally is done\nwith side effects in imperative programming, but they also do it with a\nhigh degree of control and type safety. They are not without drawbacks,\nthough. The major complaint about monads is that they don't easily\ncompose with each other. Granted, you can combine most of the basic\nmonads using the monad transformer library. It's relatively easy to\ncreate a monad stack that combines, say, state with exceptions, but\nthere is no formula for stacking arbitrary monads together."
  },
  {
    "path": "src/content/3.6/code/haskell/snippet01.hs",
    "content": "f >=> g = join . fmap g . f"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet02.hs",
    "content": "(f >=> g) a = join (fmap g (f a))"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet03.hs",
    "content": "class Monoid m where\n    mappend :: m -> m -> m\n    mempty  :: m"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet04.hs",
    "content": "mappend :: m -> (m -> m)"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet05.hs",
    "content": "mu :: (m, m) -> m"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet06.hs",
    "content": "eta :: () -> m"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet07.hs",
    "content": "mu (x, mu (y, z)) = mu (mu (x, y), z)"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet08.hs",
    "content": "(mu . bimap id mu)(x, (y, z))"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet09.hs",
    "content": "(mu . bimap mu id)((x, y), z)"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet10.hs",
    "content": "mu . bimap id mu = mu . bimap mu id"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet11.hs",
    "content": "alpha :: ((a, b), c) -> (a, (b, c))\nalpha ((x, y), z) = (x, (y, z))"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet12.hs",
    "content": "mu . bimap id mu . alpha = mu . bimap mu id"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet13.hs",
    "content": "mu (eta (), x) = x\nmu (x, eta ()) = x"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet14.hs",
    "content": "(mu . bimap eta id) ((), x) = lambda((), x)\n(mu . bimap id eta) (x, ()) = rho (x, ())"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet15.hs",
    "content": "lambda :: ((), a) -> a\nlambda ((), x) = x"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet16.hs",
    "content": "rho :: (a, ()) -> a\nrho (x, ()) = x"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet17.hs",
    "content": "mu . bimap id eta = rho\nmu . bimap eta id = lambda"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet18.hs",
    "content": "newtype State s a = State (s -> (a, s))"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet19.hs",
    "content": "newtype Prod s a = Prod (a, s)"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet20.hs",
    "content": "newtype Reader s a = Reader (s -> a)"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet21.hs",
    "content": "instance Adjunction (Prod s) (Reader s) where\n    counit (Prod (Reader f, s)) = f s\n    unit a = Reader (\\s -> Prod (a, s))"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet22.hs",
    "content": "newtype State s a = State (s -> (a, s))"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet23.hs",
    "content": "runState :: State s a -> s -> (a, s)\nrunState (State f) s = f s"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet24.hs",
    "content": "ssa :: State s (State s a)\nrunState ssa :: s -> (State s a, s)"
  },
  {
    "path": "src/content/3.6/code/haskell/snippet25.hs",
    "content": "join :: State s (State s a) -> State s a\njoin ssa = State (uncurry runState . runState ssa)"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet01.ml",
    "content": "module Kleisli (M : MonadJoin) = struct\n  (* compose *)\n  let ( <.> ) f g x = f (g x)\n  let ( >=> ) f g = M.join <.> M.fmap g <.> f\nend\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet02.ml",
    "content": "module Kleisli (M : MonadJoin) = struct\n  let ( >=> ) f g a = M.join (M.fmap g (f a))\nend\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet03.ml",
    "content": "module type Monoid = sig\n  type m\n\n  val mappend : m -> m -> m\n  val mempty : m\nend\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet04.ml",
    "content": "val mappend : m -> m -> m\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet05.ml",
    "content": "val mu : (m, m) -> m\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet06.ml",
    "content": "val eta : unit -> m\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet07.ml",
    "content": ";;\nmu (x, mu (y, z)) = mu (mu (x, y), z)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet08.ml",
    "content": ";;\n(compose mu (bimap id mu)) (x, (y, z))\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet09.ml",
    "content": ";;\n(compose mu (bimap mu id)) ((x, y), z)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet10.ml",
    "content": ";;\ncompose mu (bimap id mu) = compose mu (bimap mu id)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet11.ml",
    "content": "let alpha ((x, y), z) = x, (y, z)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet12.ml",
    "content": ";;\ncompose mu (compose (bimap id mu) alpha) = compose mu (bimap mu id)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet13.ml",
    "content": ";;\nmu (eta (), x) = x mu (x, eta ()) = x\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet14.ml",
    "content": ";;\n(compose mu (bimap eta id)) ((), x)\n= lambda ((), x) (compose mu (bimap id eta)) (x, ())\n= rho (x, ())\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet15.ml",
    "content": "let lambda ((), x) = x\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet16.ml",
    "content": "let rho (x, ()) = x\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet17.ml",
    "content": ";;\nmu.bimap id eta = rho mu.bimap eta id = lambda\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet18.ml",
    "content": "type ('s, 'a) state = State of ('s -> 'a * 's)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet19.ml",
    "content": "type ('s, 'a) prod = Prod of 'a * 's\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet20.ml",
    "content": "type ('s, 'a) reader = Reader of ('s -> 'a)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet21.ml",
    "content": "module AdjunctionState (S : sig\n  type s\nend)\n(F : Functor with type 'a t = (S.s, 'a) prod)\n(R : Representable with type 'a t = (S.s, 'a) reader) : Adjunction =\nstruct\n  type 'a f = (S.s, 'a) prod\n  type 'a r = (S.s, 'a) reader\n\n  include F\n  include R\n\n  let unit a = Reader (fun s -> Prod (a, s))\n  let counit (Prod (Reader f, s)) = f s\nend\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet22.ml",
    "content": "type ('s, 'a) state = State of ('s -> 'a * 's)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet23.ml",
    "content": "let run_state (State f) s = f s\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet24.ml",
    "content": "val ssa : ('s, ('s, 'a) state) state\nval run_state ssa : 's -> (('s, 'a) state, 's)\n"
  },
  {
    "path": "src/content/3.6/code/ocaml/snippet25.ml",
    "content": "let join : ('s, ('s, 'a) state) state -> ('s, 'a) state =\n fun ssa -> State (uncurry run_state <.> run_state ssa)\n;;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet01.re",
    "content": "module Kleisli = (M: MonadJoin) => {\n  /* compose */\n  let (<.>) = (f, g, x) => f(g(x));\n  let (>=>) = (f, g) => M.join <.> M.fmap(g) <.> f;\n};\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet02.re",
    "content": "module Kleisli = (M: MonadJoin) => {\n  let (>=>) = (f, g, a) => M.join(M.fmap(g, f(a)));\n};\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet03.re",
    "content": "module type Monoid = {\n  type m;\n\n  let mappend: (m, m) => m;\n  let mempty: m;\n};\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet04.re",
    "content": "let mappend: (m, m) => m;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet05.re",
    "content": "let mu: (m, m) => m;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet06.re",
    "content": "let eta: unit => m = ;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet07.re",
    "content": "\nmu((x, mu((y, z)))) == mu((mu((x, y)), z));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet08.re",
    "content": "\n(compose(mu, bimap(id, mu)))((x, (y, z)));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet09.re",
    "content": "\n(compose(mu, bimap(mu, id)))(((x, y), z));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet10.re",
    "content": "\ncompose(mu, bimap(id, mu)) == compose(mu, bimap(mu, id));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet11.re",
    "content": "let alpha = (((x, y), z)) => (x, (y, z));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet12.re",
    "content": "\ncompose(mu, compose(bimap(id, mu), alpha)) == compose(mu, bimap(mu, id));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet13.re",
    "content": "\nmu((eta(), x)) == x(mu, (x, eta())) == x;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet14.re",
    "content": "\n(compose(mu, bimap(eta, id)))(((), x))\n== lambda(((), x), compose(mu, bimap(id, eta)), (x, ()))\n== rho((x, ()));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet15.re",
    "content": "let lambda = (((), x)) => x;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet16.re",
    "content": "let rho = ((x, ())) => x;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet17.re",
    "content": "mu.bimap(id, eta) == rho(mu.bimap, eta, id) == lambda;\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet18.re",
    "content": "type state('s, 'a) =\n  | State('s => ('a, 's));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet19.re",
    "content": "type prod('s, 'a) =\n  | Prod('a, 's);\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet20.re",
    "content": "type reader('s, 'a) =\n  | Reader('s => 'a);\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet21.re",
    "content": "module AdjunctionState = (\n      S: {type s;},\n      F: Functor with type t('a) = prod(S.s, 'a),\n      R: Representable with type t('a) = reader(S.s, 'a),\n    ): Adjunction => {\n  type f('a) = prod(S.s, 'a);\n  type r('a) = reader(S.s, 'a);\n\n  include F;\n  include R;\n\n  let unit = a => Reader(s => Prod(a, s));\n  let counit = (Prod(Reader(f), s)) => f(s);\n};\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet22.re",
    "content": "type state('s, 'a) =\n  | State('s => ('a, 's));\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet23.re",
    "content": "let run_state = (State(f), s) => f(s);\n"
  },
  {
    "path": "src/content/3.6/code/reason/snippet24.re",
    "content": "let ssa: state('s, state('s, 'a));\nlet run_state ssa: 's => (state('s, 'a), 's);"
  },
  {
    "path": "src/content/3.6/code/reason/snippet25.re",
    "content": "let join: state('s, state('s, 'a)) => state('s, 'a) = (\n  ssa => State(uncurry(run_state) <.> run_state(ssa)):\n    state('s, state('s, 'a)) => state('s, 'a)\n);\n"
  },
  {
    "path": "src/content/3.6/code/scala/snippet01.scala",
    "content": "(f >=> g) ==\n    (flatten compose fmap[B, T[C]](g) compose f)"
  },
  {
    "path": "src/content/3.6/code/scala/snippet02.scala",
    "content": "(f >=> g)(a) == flatten(fmap(g)(f(a)))"
  },
  {
    "path": "src/content/3.6/code/scala/snippet03.scala",
    "content": "trait Monoid[M] {\n  def combine(x: M, y: M): M\n  def empty: M\n}"
  },
  {
    "path": "src/content/3.6/code/scala/snippet04.scala",
    "content": "def combine(x: M): (M => M)"
  },
  {
    "path": "src/content/3.6/code/scala/snippet05.scala",
    "content": "def mu: ((M, M)) => M"
  },
  {
    "path": "src/content/3.6/code/scala/snippet06.scala",
    "content": "def eta: Unit => M"
  },
  {
    "path": "src/content/3.6/code/scala/snippet07.scala",
    "content": "mu (x, mu (y, z)) == mu (mu (x, y), z)"
  },
  {
    "path": "src/content/3.6/code/scala/snippet08.scala",
    "content": "mu compose bimap(identity)(mu)"
  },
  {
    "path": "src/content/3.6/code/scala/snippet09.scala",
    "content": "mu compose bimap(mu)(identity)"
  },
  {
    "path": "src/content/3.6/code/scala/snippet10.scala",
    "content": "mu.compose(bimap(identity)(mu)) ==\n    mu.compose(bimap(mu)(identity))"
  },
  {
    "path": "src/content/3.6/code/scala/snippet11.scala",
    "content": "def alpha[A, B, C]: (((A, B), C)) => ((A, (B, C))) = {\n  case ((x, y), z) => (x, (y, z))\n}"
  },
  {
    "path": "src/content/3.6/code/scala/snippet12.scala",
    "content": "mu.compose(\n  bimap(identity)(mu) compose alpha) ==\n  mu.compose(bimap(mu)(identity))"
  },
  {
    "path": "src/content/3.6/code/scala/snippet13.scala",
    "content": "mu(eta(), x) == x\nmu(x, eta()) == x"
  },
  {
    "path": "src/content/3.6/code/scala/snippet14.scala",
    "content": "mu.compose(bimap(eta)(identity[M]))(((), x)) == lambda(((), x))\n\nmu.compose(bimap(identity[M])(eta))((x, ())) == rho((x, ()))"
  },
  {
    "path": "src/content/3.6/code/scala/snippet15.scala",
    "content": "def lambda[A]: ((Unit, A)) => A = {\n  case ((), x) => x\n}"
  },
  {
    "path": "src/content/3.6/code/scala/snippet16.scala",
    "content": "def rho[A]: ((A, Unit)) => A = {\n  case (x, ()) => x\n}"
  },
  {
    "path": "src/content/3.6/code/scala/snippet17.scala",
    "content": "mu.compose(bimap(eta)(identity[M])) == lambda\nmu.compose(bimap(identity[M])(eta)) == rho"
  },
  {
    "path": "src/content/3.6/code/scala/snippet18.scala",
    "content": "case class State[S, A](run: S => (A, S))"
  },
  {
    "path": "src/content/3.6/code/scala/snippet19.scala",
    "content": "case class Prod[S, A](run: (A, S))"
  },
  {
    "path": "src/content/3.6/code/scala/snippet20.scala",
    "content": "case class Reader[S, A](run: S => A)"
  },
  {
    "path": "src/content/3.6/code/scala/snippet21.scala",
    "content": "implicit def state[S] = new Adjunction[Prod[S, ?], Reader[S, ?]] {\n  def counit[A](a: Prod[S, Reader[S, A]]): A = a match {\n    case Prod((Reader(f), s)) => f(s)\n  }\n\n  def unit[A](a: A): Reader[S, Prod[S, A]] =\n    Reader(s => Prod((a, s)))\n}"
  },
  {
    "path": "src/content/3.6/code/scala/snippet22.scala",
    "content": "case class State[S, A](run: S => (A, S))"
  },
  {
    "path": "src/content/3.6/code/scala/snippet23.scala",
    "content": "def runState[S, A]: State[S, A] => S => (A, S) = {\n  case State(f) => s => f(s)\n}"
  },
  {
    "path": "src/content/3.6/code/scala/snippet24.scala",
    "content": "def ssa[S, A]: State[S, State[S, A]]\n\ndef rss[S, A]: S => (State[S, A], S) =\n  runState[S, State[S, A]](ssa)"
  },
  {
    "path": "src/content/3.6/code/scala/snippet25.scala",
    "content": "def join[S, A]: State[S, State[S, A]] => State[S, A] =\n  ssa => {\n    State(\n      Function.uncurried(runState[S, A])\n        .tupled\n        .compose(runState(ssa))\n    )\n  }"
  },
  {
    "path": "src/content/3.6/monads-categorically.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{f you mention monads} to a programmer, you'll probably end up talking\nabout effects. To a mathematician, monads are about algebras. We'll talk\nabout algebras later --- they play an important role in programming ---\nbut first I'd like to give you a little intuition about their relation\nto monads. For now, it's a bit of a hand-waving argument, but bear with\nme.\n\nAlgebra is about creating, manipulating, and evaluating expressions.\nExpressions are built using operators. Consider this simple expression:\n\\[x^2 + 2 x + 1\\]\nThis expression is formed using variables like $x$, and constants\nlike $1$ or $2$, bound together with operators like plus or times. As\nprogrammers, we often think of expressions as trees.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/exptree.png}\n\\end{figure}\n\n\\noindent\nTrees are containers so, more generally, an expression is a container\nfor storing variables. In category theory, we represent containers as\nendofunctors. If we assign the type $a$ to the variable\n$x$, our expression will have the type $m\\ a$, where\n$m$ is an endofunctor that builds expression trees. (Nontrivial\nbranching expressions are usually created using recursively defined\nendofunctors.)\n\nWhat's the most common operation that can be performed on an expression?\nIt's substitution: replacing variables with expressions. For instance,\nin our example, we could replace $X$ with $y - 1$ to\nget:\n\\[(y - 1)^2 + 2 (y - 1) + 1\\]\nHere's what happened: We took an expression of type $m\\ a$ and\napplied a transformation of type $a \\to m\\ b$\n($b$ represents the type of $y$). The result is an\nexpression of type $m\\ b$. Let me spell it out:\n\\[m\\ a \\to (a \\to m\\ b) \\to m\\ b\\]\nYes, that's the signature of monadic bind.\n\nThat was a bit of motivation. Now let's get to the math of the monad.\nMathematicians use different notation than programmers. They prefer to\nuse the letter $T$ for the endofunctor, and Greek letters: $\\mu$ for\n\\code{join} and $\\eta$ for \\code{return}. Both \\code{join} and\n\\code{return} are polymorphic functions, so we can guess that they\ncorrespond to natural transformations.\n\nTherefore, in category theory, a monad is defined as an endofunctor\n$T$ equipped with a pair of natural transformations $\\mu$ and $\\eta$.\n\n$\\mu$ is a natural transformation from the square of the functor $T^2$\nback to $T$. The square is simply the functor composed with\nitself, $T \\circ T$ (we can only do this kind of squaring for\nendofunctors).\n\\[\\mu \\Colon T^2 \\to T\\]\nThe component of this natural transformation at an object $a$ is\nthe morphism:\n\\[\\mu_a \\Colon T (T a) \\to T a\\]\nwhich, in $\\Hask$, translates directly to our definition of\n\\code{join}.\n\n$\\eta$ is a natural transformation between the identity functor $I$\nand $T$:\n\\[\\eta \\Colon I \\to T\\]\nConsidering that the action of $I$ on the object $a$ is\njust $a$, the component of $\\eta$ is given by the morphism:\n\\[\\eta_a \\Colon a \\to T a\\]\nwhich translates directly to our definition of \\code{return}.\n\nThese natural transformations must satisfy some additional laws. One way\nof looking at it is that these laws let us define a Kleisli category for\nthe endofunctor $T$. Remember that a Kleisli arrow between\n$a$ and $b$ is defined as a morphism\n$a \\to T b$. The composition of two such arrows\n(I'll write it as a circle with the subscript $T$) can be\nimplemented using $\\mu$:\n\\[g \\circ_T f = \\mu_c \\circ (T g) \\circ f\\]\nwhere\n\\begin{gather*}\n  f \\Colon a \\to T b \\\\\n  g \\Colon b \\to T c\n\\end{gather*}\nHere $T$, being a functor, can be applied to the morphism\n$g$. It might be easier to recognize this formula in Haskell\nnotation:\n\n\\src{snippet01}\nor, in components:\n\n\\src{snippet02}\nIn terms of the algebraic interpretation, we are just composing two\nsuccessive substitutions.\n\nFor Kleisli arrows to form a category we want their composition to be\nassociative, and $\\eta_a$ to be the identity Kleisli arrow at\n$a$. This requirement can be translated to monadic laws for $\\mu$ and\n$\\eta$. But there is another way of deriving these laws that makes them look\nmore like monoid laws. In fact $\\mu$ is often called\n\\emph{multiplication}, and $\\eta$ -- \\emph{unit}.\n\nRoughly speaking, the associativity law states that the two ways of\nreducing the cube of $T$, $T^3$, down to $T$ must\ngive the same result. Two unit laws (left and right) state that when\n$\\eta$ is applied to $T$ and then reduced by $\\mu$, we\nget back $T$.\n\nThings are a little tricky because we are composing natural\ntransformations and functors. So a little refresher on horizontal\ncomposition is in order. For instance, $T^3$ can be seen as a\ncomposition of $T$ after $T^2$. We can apply to it the\nhorizontal composition of two natural transformations:\n\\[I_T \\circ \\mu\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/assoc1.png}\n\\end{figure}\n\n\\noindent\nand get $T \\circ T$; which can be further reduced to $T$ by\napplying $\\mu$. $I_T$ is the identity natural transformation\nfrom $T$ to $T$. You will often see the notation for this\ntype of horizontal composition $I_T \\circ \\mu$ shortened to\n$T \\circ \\mu$. This notation is unambiguous because it makes no sense to\ncompose a functor with a natural transformation, therefore $T$\nmust mean $I_T$ in this context.\n\n\\noindent\nWe can also draw the diagram in the (endo-) functor category ${[}\\cat{C}, \\cat{C}{]}$:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/assoc2.png}\n\\end{figure}\n\n\\noindent\nAlternatively, we can treat $T^3$ as the composition of\n$T^2 \\circ T$ and apply $\\mu \\circ T$ to it. The result is also\n$T \\circ T$ which, again, can be reduced to $T$ using $\\mu$. We\nrequire that the two paths produce the same result.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/assoc.png}\n\\end{figure}\n\n\\noindent\nSimilarly, we can apply the horizontal composition $\\eta \\circ T$ to the\ncomposition of the identity functor $I$ after $T$ to\nobtain $T^2$, which can then be reduced using $\\mu$. The\nresult should be the same as if we applied the identity natural\ntransformation directly to \\code{T}. And, by analogy, the same should\nbe true for $T \\circ \\eta$.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/unitlawcomp-1.png}\n\\end{figure}\n\n\\noindent\nYou can convince yourself that these laws guarantee that the composition\nof Kleisli arrows indeed satisfies the laws of a category.\n\nThe similarities between a monad and a monoid are striking. We have\nmultiplication $\\mu$, unit $\\eta$, associativity, and unit laws. But our\ndefinition of a monoid is too narrow to describe a monad as a monoid. So\nlet's generalize the notion of a monoid.\n\n\\section{Monoidal Categories}\n\nLet's go back to the conventional definition of a monoid. It's a set\nwith a binary operation and a special element called unit. In Haskell,\nthis can be expressed as a typeclass:\n\n\\src{snippet03}\nThe binary operation \\code{mappend} must be associative and unital\n(i.e., multiplication by the unit \\code{mempty} is a no-op).\n\nNotice that, in Haskell, the definition of \\code{mappend} is curried.\nIt can be interpreted as mapping every element of \\code{m} to a\nfunction:\n\n\\src{snippet04}\nIt's this interpretation that gives rise to the definition of a monoid\nas a single-object category where endomorphisms\n\\code{(m -> m)} represent the elements of the monoid.\nBut because currying is built into Haskell, we could as well have\nstarted with a different definition of multiplication:\n\n\\src{snippet05}\nHere, the Cartesian product \\code{(m, m)} becomes the source of pairs\nto be multiplied.\n\nThis definition suggests a different path to generalization: replacing\nthe Cartesian product with categorical product. We could start with a\ncategory where products are globally defined, pick an object \\code{m}\nthere, and define multiplication as a morphism:\n\\[\\mu \\Colon m\\times{}m \\to m\\]\nWe have one problem though: In an arbitrary category we can't peek\ninside an object, so how do we pick the unit element? There is a trick\nto it. Remember how element selection is equivalent to a function from\nthe singleton set? In Haskell, we could replace the definition of\n\\code{mempty} with a function:\n\n\\src{snippet06}\nThe singleton is the terminal object in $\\Set$, so it's natural to\ngeneralize this definition to any category that has a terminal object\n$t$:\n\\[\\eta \\Colon t \\to m\\]\nThis lets us pick the unit ``element'' without having to talk about\nelements.\n\nUnlike in our previous definition of a monoid as a single-object\ncategory, monoidal laws here are not automatically satisfied --- we have\nto impose them. But in order to formulate them we have to establish the\nmonoidal structure of the underlying categorical product itself. Let's\nrecall how monoidal structure works in Haskell first.\n\nWe start with associativity. In Haskell, the corresponding equational\nlaw is:\n\n\\src{snippet07}\nBefore we can generalize it to other categories, we have to rewrite it\nas an equality of functions (morphisms). We have to abstract it away\nfrom its action on individual variables --- in other words, we have to\nuse point-free notation. Knowing that the Cartesian product is a\nbifunctor, we can write the left hand side as:\n\n\\src{snippet08}\nand the right hand side as:\n\n\\src{snippet09}\nThis is almost what we want. Unfortunately, the Cartesian product is not\nstrictly associative --- \\code{(x, (y, z))} is not the same as\n\\code{((x, y), z)} --- so we can't just write point-free:\n\n\\src{snippet10}\nOn the other hand, the two nestings of pairs are isomorphic. There is an\ninvertible function called the associator that converts between them:\n\n\\src{snippet11}\nWith the help of the associator, we can write the point-free\nassociativity law for \\code{mu}:\n\n\\src{snippet12}\nWe can apply a similar trick to unit laws which, in the new notation,\ntake the form:\n\n\\src{snippet13}\nThey can be rewritten as:\n\n\\src{snippet14}\nThe isomorphisms \\code{lambda} and \\code{rho} are called the left\nand right unitor, respectively. They witness the fact that the unit\n\\code{()} is the identity of the Cartesian product up to isomorphism:\n\n\\src{snippet15}\n\n\\src{snippet16}\nThe point-free versions of the unit laws are therefore:\n\n\\src{snippet17}\nWe have formulated point-free monoidal laws for \\code{mu} and\n\\code{eta} using the fact that the underlying Cartesian product itself\nacts like a monoidal multiplication in the category of types. Keep in\nmind though that the associativity and unit laws for the Cartesian\nproduct are valid only up to isomorphism.\n\nIt turns out that these laws can be generalized to any category with\nproducts and a terminal object. Categorical products are indeed\nassociative up to isomorphism and the terminal object is the unit, also\nup to isomorphism. The associator and the two unitors are natural\nisomorphisms. The laws can be represented by commuting diagrams.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/assocmon.png}\n\\end{figure}\n\n\\noindent\nNotice that, because the product is a bifunctor, it can lift a pair of\nmorphisms --- in Haskell this was done using \\code{bimap}.\n\nWe could stop here and say that we can define a monoid on top of any\ncategory with categorical products and a terminal object. As long as we\ncan pick an object $m$ and two morphisms $\\mu$ and $\\eta$ that satisfy\nmonoidal laws, we have a monoid. But we can do better than that. We\ndon't need a full-blown categorical product to formulate the laws for $\\mu$\nand $\\eta$. Recall that a product is defined through a universal construction\nthat uses projections. We haven't used any projections in our\nformulation of monoidal laws.\n\nA bifunctor that behaves like a product without being a product is\ncalled a \\newterm{tensor product}, often denoted by the infix operator $\\otimes$. A\ndefinition of a tensor product in general is a bit tricky, but we won't\nworry about it. We'll just list its properties --- the most important\nbeing associativity up to isomorphism.\n\nSimilarly, we don't need the object $t$ to be terminal. We never\nused its terminal property --- namely, the existence of a unique\nmorphism from any object to it. What we require is that it works well in\nconcert with the tensor product. Which means that we want it to be the\nunit of the tensor product, again, up to isomorphism. Let's put it all\ntogether:\n\nA monoidal category is a category $\\cat{C}$ equipped with a bifunctor\ncalled the tensor product:\n\\[\\otimes \\Colon \\cat{C}\\times{}\\cat{C} \\to \\cat{C}\\]\nand a distinct object $i$ called the unit object, together with\nthree natural isomorphisms called, respectively, the associator and the\nleft and right unitors:\n\\begin{align*}\n  \\alpha_{a b c} & \\Colon (a \\otimes b) \\otimes c \\to a \\otimes (b \\otimes c) \\\\\n  \\lambda_a      & \\Colon i \\otimes a \\to a                                   \\\\\n  \\rho_a         & \\Colon a \\otimes i \\to a\n\\end{align*}\n(There is also a coherence condition for simplifying a quadruple tensor\nproduct.)\n\nWhat's important is that a tensor product describes many familiar\nbifunctors. In particular, it works for a product, a coproduct and, as\nwe'll see shortly, for the composition of endofunctors (and also for\nsome more esoteric products like Day convolution). Monoidal categories\nwill play an essential role in the formulation of enriched categories.\n\n\\section{Monoid in a Monoidal Category}\n\nWe are now ready to define a monoid in a more general setting of a\nmonoidal category. We start by picking an object $m$. Using the\ntensor product we can form powers of $m$. The square of\n$m$ is $m \\otimes m$. There are two ways of forming the cube\nof $m$, but they are isomorphic through the associator. Similarly\nfor higher powers of $m$ (that's where we need the coherence\nconditions). To form a monoid we need to pick two morphisms:\n\\begin{align*}\n  \\mu  & \\Colon m \\otimes m \\to m \\\\\n  \\eta & \\Colon i \\to m\n\\end{align*}\nwhere $i$ is the unit object for our tensor product.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/monoid-1.jpg}\n\\end{figure}\n\n\\noindent\nThese morphisms have to satisfy associativity and unit laws, which can\nbe expressed in terms of the following commuting diagrams:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/assoctensor.jpg}\n\\end{figure}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/unitmon.jpg}\n\\end{figure}\n\n\\noindent\nNotice that it's essential that the tensor product be a bifunctor\nbecause we need to lift pairs of morphisms to form products such as\n$\\mu \\otimes \\id$ or $\\eta \\otimes \\id$. These diagrams are just a\nstraightforward generalization of our previous results for categorical\nproducts.\n\n\\section{Monads as Monoids}\n\nMonoidal structures pop up in unexpected places. One such place is the\nfunctor category. If you squint a little, you might be able to see\nfunctor composition as a form of multiplication. The problem is that not\nany two functors can be composed --- the target category of one has to\nbe the source category of the other. That's just the usual rule of\ncomposition of morphisms --- and, as we know, functors are indeed\nmorphisms in the category $\\Cat$. But just like endomorphisms\n(morphisms that loop back to the same object) are always composable, so\nare endofunctors. For any given category $\\cat{C}$, endofunctors from\n$\\cat{C}$ to $\\cat{C}$ form the functor category ${[}\\cat{C}, \\cat{C}{]}$. Its\nobjects are endofunctors, and morphisms are natural transformations\nbetween them. We can take any two objects from this category, say\nendofunctors $F$ and $G$, and produce a third object $F \\circ G$ ---\nan endofunctor that's their composition.\n\nIs endofunctor composition a good candidate for a tensor product? First,\nwe have to establish that it's a bifunctor. Can it be used to lift a\npair of morphisms --- here, natural transformations? The signature of\nthe analog of \\code{bimap} for the tensor product would look something\nlike this:\n\\[\\mathit{bimap} \\Colon (a \\to b) \\to (c \\to d) \\to (a \\otimes c \\to b \\otimes d)\\]\nIf you replace objects by endofunctors, arrows by natural\ntransformations, and tensor products by composition, you get:\n\\[(F \\to F') \\to (G \\to G') \\to (F \\circ G \\to F' \\circ G')\\]\nwhich you may recognize as the special case of horizontal composition.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/horizcomp.png}\n\\end{figure}\n\n\\noindent\nWe also have at our disposal the identity endofunctor $I$, which\ncan serve as the identity for endofunctor composition --- our new tensor\nproduct. Moreover, functor composition is associative. In fact\nassociativity and unit laws are strict --- there's no need for the\nassociator or the two unitors. So endofunctors form a strict monoidal\ncategory with functor composition as tensor product.\n\nWhat's a monoid in this category? It's an object --- that is an\nendofunctor $T$; and two morphisms --- that is natural\ntransformations:\n\\begin{gather*}\n  \\mu \\Colon T \\circ T \\to T \\\\\n  \\eta \\Colon I \\to T\n\\end{gather*}\nNot only that, here are the monoid laws:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/assoc.png}\n\\end{figure}\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.5\\textwidth]{images/unitlawcomp.png}\n\\end{figure}\n\n\\noindent\nThey are exactly the monad laws we've seen before. Now you understand\nthe famous quote from Saunders Mac Lane:\n\n\\begin{quote}\n  All told, monad is just a monoid in the category of endofunctors.\n\\end{quote}\nYou might have seen it emblazoned on some t-shirts at functional\nprogramming conferences.\n\n\\section{Monads from Adjunctions}\n\nAn \\hyperref[adjunctions]{adjunction}\\footnote{See ch.18 on \\hyperref[adjunctions]{adjunctions}.}\n$L \\dashv R$, is a pair of functors going back and forth between two\ncategories $\\cat{C}$ and $\\cat{D}$. There are two ways of composing them\ngiving rise to two endofunctors, $R \\circ L$ and $L \\circ R$.\nAs per an adjunction, these endofunctors are related to identity\nfunctors through two natural transformations called unit and counit:\n\\begin{gather*}\n  \\eta \\Colon I_{\\cat{D}} \\to R \\circ L \\\\\n  \\varepsilon \\Colon L \\circ R \\to I_{\\cat{C}}\n\\end{gather*}\nImmediately we see that the unit of an adjunction looks just like the\nunit of a monad. It turns out that the endofunctor $R \\circ L$ is\nindeed a monad. All we need is to define the appropriate $\\mu$ to go with\nthe $\\eta$. That's a natural transformation between the square of our\nendofunctor and the endofunctor itself or, in terms of the adjoint\nfunctors:\n\\[R \\circ L \\circ R \\circ L \\to R \\circ L\\]\nAnd, indeed, we can use the counit to collapse the $L \\circ R$ in\nthe middle. The exact formula for $\\mu$ is given by the horizontal\ncomposition:\n\\[\\mu = R \\circ \\varepsilon \\circ L\\]\nMonadic laws follow from the identities satisfied by the unit and counit\nof the adjunction and the interchange law.\n\nWe don't see a lot of monads derived from adjunctions in Haskell,\nbecause an adjunction usually involves two categories. However, the\ndefinitions of an exponential, or a function object, is an exception.\nHere are the two endofunctors that form this adjunction:\n\\begin{gather*}\n  L z = z\\times{}s \\\\\n  R b = s \\Rightarrow b\n\\end{gather*}\nYou may recognize their composition as the familiar state monad:\n\\[R (L z) = s \\Rightarrow (z\\times{}s)\\]\nWe've seen this monad before in Haskell:\n\n\\src{snippet18}\nLet's also translate the adjunction to Haskell. The left functor is the\nproduct functor:\n\n\\src{snippet19}\nand the right functor is the reader functor:\n\n\\src{snippet20}\nThey form the adjunction:\n\n\\src{snippet21}\nYou can easily convince yourself that the composition of the reader\nfunctor after the product functor is indeed equivalent to the state\nfunctor:\n\n\\src{snippet22}\nAs expected, the \\code{unit} of the adjunction is equivalent to the\n\\code{return} function of the state monad. The \\code{counit} acts by\nevaluating a function acting on its argument. This is recognizable as\nthe uncurried version of the function \\code{runState}:\n\n\\src{snippet23}\n(uncurried, because in \\code{counit} it acts on a pair).\n\nWe can now define \\code{join} for the state monad as a component of\nthe natural transformation $\\mu$. For that we need a horizontal composition\nof three natural transformations:\n\\[\\mu = R \\circ \\varepsilon \\circ L\\]\nIn other words, we need to sneak the counit $\\varepsilon$ across one level of the\nreader functor. We can't just call \\code{fmap} directly, because the\ncompiler would pick the one for the \\code{State} functor, rather than\nthe \\code{Reader} functor. But recall that \\code{fmap} for the\nreader functor is just left function composition. So we'll use function\ncomposition directly.\n\nWe have to first peel off the data constructor \\code{State} to expose\nthe function inside the \\code{State} functor. This is done using\n\\code{runState}:\n\n\\src{snippet24}\nThen we left-compose it with the counit, which is defined by\n\\code{uncurry runState}. Finally, we clothe it back in the\n\\code{State} data constructor:\n\n\\src{snippet25}\nThis is indeed the implementation of \\code{join} for the\n\\code{State} monad.\n\nIt turns out that not only every adjunction gives rise to a monad, but\nthe converse is also true: every monad can be factorized into a\ncomposition of two adjoint functors. Such a factorization is not unique\nthough.\n\nWe'll talk about the other endofunctor $L \\circ R$ in the next\nsection.\n"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet01.hs",
    "content": "a -> m b"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet02.hs",
    "content": "w a -> b"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet03.hs",
    "content": "(=>=) :: (w a -> b) -> (w b -> c) -> (w a -> c)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet04.hs",
    "content": "extract :: w a -> a"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet05.hs",
    "content": "class Functor w => Comonad w where\n    (=>=) :: (w a -> b) -> (w b -> c) -> (w a -> c)\n    extract :: w a -> a"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet06.hs",
    "content": "(a, e) -> b"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet07.hs",
    "content": "a -> (e -> b)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet08.hs",
    "content": "data Product e a = Prod e a deriving Functor"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet09.hs",
    "content": "(=>=) :: (Product e a -> b) -> (Product e b -> c) -> (Product e a -> c)\nf =>= g = \\(Prod e a) -> let b = f (Prod e a)\n                          c = g (Prod e b) \n                      in c"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet10.hs",
    "content": "extract (Prod e a) = a"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet11.hs",
    "content": "(=>=) :: (w a -> b) -> (w b -> c) -> (w a -> c)\nf =>= g = g ... "
  },
  {
    "path": "src/content/3.7/code/haskell/snippet12.hs",
    "content": "extend :: (w a -> b) -> w a -> w b"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet13.hs",
    "content": "f =>= g = g . extend f"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet14.hs",
    "content": "duplicate :: w a -> w (w a)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet15.hs",
    "content": "class Functor w => Comonad w where\n    extract :: w a -> a\n    duplicate :: w a -> w (w a)\n    duplicate = extend id\n    extend :: (w a -> b) -> w a -> w b\n    extend f = fmap f . duplicate"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet16.hs",
    "content": "data Stream a = Cons a (Stream a)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet17.hs",
    "content": "instance Functor Stream where\n    fmap f (Cons a as) = Cons (f a) (fmap f as)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet18.hs",
    "content": "extract (Cons a _) = a"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet19.hs",
    "content": "duplicate (Cons a as) = Cons (Cons a as) (duplicate as)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet20.hs",
    "content": "instance Comonad Stream where\n    extract (Cons a _) = a \n    duplicate (Cons a as) = Cons (Cons a as) (duplicate as)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet21.hs",
    "content": "tail :: Stream a -> Stream a\ntail (Cons a as) = as"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet22.hs",
    "content": "sumS :: Num a => Int -> Stream a -> a\nsumS n (Cons a as) = if n <= 0 then 0 else a + sumS (n - 1) as"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet23.hs",
    "content": "average :: Fractional a => Int -> Stream a -> a\naverage n stm = (sumS n stm) / (fromIntegral n)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet24.hs",
    "content": "movingAvg :: Fractional a => Int -> Stream a -> Stream a\nmovingAvg n = extend (average n)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet25.hs",
    "content": "class Comonoid m where\n    split :: m -> (m, m)\n    destroy :: m -> ()"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet26.hs",
    "content": "destroy _ = ()"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet27.hs",
    "content": "split x = (f x, g x)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet28.hs",
    "content": "lambda . bimap destroy id . split = id\nrho . bimap id destroy . split = id"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet29.hs",
    "content": "lambda (bimap destroy id (split x))\n= lambda (bimap destroy id (f x, g x))\n= lambda ((), g x)\n= g x"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet30.hs",
    "content": "split x = (x, x)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet31.hs",
    "content": "data Store s a = Store (s -> a) s"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet32.hs",
    "content": "counit (Prod (Reader f) s)) = f s"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet33.hs",
    "content": "extract (Store f s) = f s"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet34.hs",
    "content": "unit :: a -> Reader s (Product a s)\nunit a = Reader (\\s -> Prod a s)"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet35.hs",
    "content": "Store f :: s -> Store f s"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet36.hs",
    "content": "duplicate (Store f s) = Store (Store f) s"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet37.hs",
    "content": "instance Comonad (Store s) where\n    extract (Store f s) = f s\n    duplicate (Store f s) = Store (Store f) s"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet38.hs",
    "content": "a -> Store s a"
  },
  {
    "path": "src/content/3.7/code/haskell/snippet39.hs",
    "content": "set :: a -> s -> a\nget :: a -> s"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet01.ml",
    "content": "'a -> 'b m\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet02.ml",
    "content": "'a w -> 'b\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet03.ml",
    "content": "module type CoKleisli = sig\n  type 'a w\n\n  val ( =>= ) : ('a w -> 'b) -> ('b w -> 'c) -> 'a w -> 'c\nend\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet04.ml",
    "content": "val extract : 'a w -> 'a\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet05.ml",
    "content": "module type Comonad = sig\n  type 'a w\n\n  include Functor with type 'a t := 'a w\n\n  val extract : 'a w -> 'a\n  val ( =>= ) : ('a w -> 'b) -> ('b w -> 'c) -> 'a w -> 'c\nend\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet06.ml",
    "content": "'a * 'e -> 'b\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet07.ml",
    "content": "'a -> ('e -> 'b)\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet08.ml",
    "content": "type ('e, 'a) product = P of 'e * 'a\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet09.ml",
    "content": "let ( =>= ) f g (P (e, a)) =\n  let b = f (P (e, a)) in\n  let c = g (P (e, b)) in\n  c\n;;\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet10.ml",
    "content": "let extract (P (e, a)) = a\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet11.ml",
    "content": "module CoKleisliImpl = struct\ntype 'a w\nlet (=>=) : ('a w -> 'b) -> ('b w -> 'c) -> ('a w -> 'c) = fun f g ->\n  g ...\nend\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet12.ml",
    "content": "val extend : ('a w -> 'b) -> 'a w -> 'b w\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet13.ml",
    "content": "module type CoKleisliExtend = sig\n  type 'a w\n\n  val extend : ('a w -> 'b) -> 'a w -> 'b w\nend\n\nmodule CoKleisliImpl (C : CoKleisliExtend) = struct\n  type 'a w = 'a C.w\n\n  let ( =>= ) : ('a w -> 'b) -> ('b w -> 'c) -> 'a w -> 'c =\n   fun f g -> compose g (C.extend f)\n ;;\nend\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet14.ml",
    "content": "val duplicate : 'a w -> 'a w w\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet15.ml",
    "content": "module type ComonadBase = sig\n  type 'a w\n\n  include Functor with type 'a t = 'a w\n\n  val extract : 'a w -> 'a\nend\n\nmodule type ComonadDuplicate = sig\n  type 'a w\n\n  val duplicate : 'a w -> 'a w w\nend\n\nmodule type ComonadExtend = sig\n  type 'a w\n\n  val extend : ('a w -> 'b) -> 'a w -> 'b w\nend\n\nmodule type Comonad = sig\n  type 'a w\n\n  include ComonadBase with type 'a w := 'a w\n  include ComonadExtend with type 'a w := 'a w\n  include ComonadDuplicate with type 'a w := 'a w\nend\n\n(* Construct a full comonad instance using one of the following modules *)\nmodule ComonadImplViaExtend : functor\n  (C : ComonadBase)\n  (D : ComonadDuplicate with type 'a w = 'a C.w)\n  -> Comonad with type 'a w = 'a C.w =\nfunctor\n  (C : ComonadBase)\n  (D : ComonadDuplicate with type 'a w = 'a C.w)\n  ->\n  struct\n    include C\n    include D\n\n    let extend f wa = (C.fmap f) (D.duplicate wa)\n  end\n\nmodule ComonadImplViaDuplicate : functor\n  (C : ComonadBase)\n  (E : ComonadExtend with type 'a w = 'a C.w)\n  -> Comonad with type 'a w = 'a C.w =\nfunctor\n  (C : ComonadBase)\n  (E : ComonadExtend with type 'a w = 'a C.w)\n  ->\n  struct\n    include C\n    include E\n\n    let duplicate (wa : 'a w) : 'a w w = E.extend id wa\n  end\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet16.ml",
    "content": "type 'a stream = Cons of 'a * 'a stream Lazy.t\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet17.ml",
    "content": "module StreamFunctor : Functor with type 'a t = 'a stream = struct\n  type 'a t = 'a stream\n\n  let rec fmap f = function\n    | Cons (x, xs) ->\n      Cons (f x, Lazy.from_val (fmap f (Lazy.force xs)))\n  ;;\nend\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet18.ml",
    "content": "let extract (Cons (x, _)) = x\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet19.ml",
    "content": "let rec duplicate (Cons (x, xs)) =\n  Cons (Cons (x, xs), Lazy.from_val (duplicate (Lazy.force xs)))\n;;\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet20.ml",
    "content": "(* Implement Extract *)\nmodule StreamComonadBase (F : Functor with type 'a t = 'a stream) :\n  ComonadBase with type 'a w = 'a stream = struct\n  type 'a w = 'a stream\n\n  include F\n\n  let extract (Cons (x, _)) = x\nend\n\n(* Implement duplicate *)\nmodule StreamComonadDuplicate :\n  ComonadDuplicate with type 'a w = 'a stream = struct\n  type 'a w = 'a stream\n\n  let rec duplicate (Cons (x, xs)) =\n    Cons (Cons (x, xs), Lazy.from_val (duplicate (Lazy.force xs)))\n  ;;\nend\n\n(* Generate full Comonad Instance *)\nmodule StreamComonad : Comonad with type 'a w = 'a stream =\n  ComonadImplViaExtend\n    (StreamComonadBase (StreamFunctor)) (StreamComonadDuplicate)\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet21.ml",
    "content": "let tail (Cons (_, xs)) = Lazy.force xs\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet22.ml",
    "content": "let rec sum_s n (Cons (x, xs)) =\n  if n <= 0 then 0 else x + sum_s (n - 1) (Lazy.force xs)\n;;\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet23.ml",
    "content": "let average n stm = Float.(of_int (sum_s n stm) /. of_int n)\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet24.ml",
    "content": "let moving_average n = StreamComonad.extend (average n)\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet25.ml",
    "content": "module type Comonoid = sig\n  type m\n\n  val split : m -> m * m\n  val destroy : m -> unit\nend\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet26.ml",
    "content": "let destroy _ = ()\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet27.ml",
    "content": "let split x = f x, g x\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet28.ml",
    "content": "(* lambda is the left unitor and rho is the right unitor *)\n(* <.> is used as compose below *)\n\n;;\nlambda\n<.> bimap destroy id\n<.> split\n= id rho\n<.> bimap id destroy\n<.> split\n= id\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet29.ml",
    "content": ";;\nlambda (bimap destroy id (split x))\n= lambda (bimap destroy id (f x, g x))\n= lambda ((), g x)\n= g x\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet30.ml",
    "content": "let split x = x, x\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet31.ml",
    "content": "type ('s, 'a) store = Store of (('s -> 'a) * 's)\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet32.ml",
    "content": "let counit (Prod (Reader f, s)) = f s\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet33.ml",
    "content": "let extract (Store (f, s)) = f s\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet34.ml",
    "content": "let unit a = Reader (fun s -> Prod (a, s))\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet35.ml",
    "content": "let make_store f s = Store (f, s)\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet36.ml",
    "content": "let duplicate (Store (f, s)) = Store (make_store f, s)\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet37.ml",
    "content": "module StoreComonadBase (S : sig\n  type s\nend)\n(F : Functor with type 'a t = (S.s, 'a) store) :\n  ComonadBase with type 'a w = (S.s, 'a) store = struct\n  type 'a w = (S.s, 'a) store\n\n  include F\n\n  let extract (Store (f, s)) = f s\nend\n\nmodule StoreComonadDuplicate (S : sig\n  type s\nend) : ComonadDuplicate with type 'a w = (S.s, 'a) store = struct\n  type 'a w = (S.s, 'a) store\n\n  let duplicate (Store (f, s)) = Store (make_store f, s)\nend\n\n(* Generate Full comonad *)\nmodule StoreComonad (S : sig\n  type s\nend)\n(F : Functor with type 'a t = (S.s, 'a) store) :\n  Comonad with type 'a w = (S.s, 'a) store =\n  ComonadImplViaExtend\n    (StoreComonadBase (S) (F)) (StoreComonadDuplicate (S))\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet38.ml",
    "content": "'a -> ('s, 'a) store\n"
  },
  {
    "path": "src/content/3.7/code/ocaml/snippet39.ml",
    "content": "val get : 'a -> 's\nval set : 'a -> 's -> 'a\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet01.re",
    "content": "'a => m('b);"
  },
  {
    "path": "src/content/3.7/code/reason/snippet02.re",
    "content": "w('a) => 'b;"
  },
  {
    "path": "src/content/3.7/code/reason/snippet03.re",
    "content": "module type CoKleisli = {\n  type w('a);\n\n  let (=>=): (w('a) => 'b, w('b) => 'c, w('a)) => 'c;\n};\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet04.re",
    "content": "let extract: w('a) => 'a;\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet05.re",
    "content": "module type Comonad = {\n  type w('a);\n\n  include Functor with type t('a) := w('a);\n\n  let extract: w('a) => 'a;\n  let (=>=): (w('a) => 'b, w('b) => 'c, w('a)) => 'c;\n};\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet06.re",
    "content": "(('a, 'e)) => 'b;"
  },
  {
    "path": "src/content/3.7/code/reason/snippet07.re",
    "content": "('a, 'e) => 'b;"
  },
  {
    "path": "src/content/3.7/code/reason/snippet08.re",
    "content": "type product('e, 'a) =\n  | P('e, 'a);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet09.re",
    "content": "let (=>=) = (f, g, P(e, a)) => {\n  let b = f(P(e, a));\n  let c = g(P(e, b));\n  c;\n};\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet10.re",
    "content": "let extract = (P(e, a)) => a;\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet11.re",
    "content": "module CoKleisliImpl = {\n  type w('a);\n  let (=>=): (w('a) => 'b, w('b) => 'c, w('a)) => 'c = (f, g) =>\n    g ... \n};\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet12.re",
    "content": "let extend: (w('a) => 'b, w('a)) => w('b);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet13.re",
    "content": "module type CoKleisliExtend = {\n  type w('a);\n\n  let extend: (w('a) => 'b, w('a)) => w('b);\n};\n\nmodule CoKleisliImpl = (C: CoKleisliExtend) => {\n  type w('a) = C.w('a);\n\n  let (=>=): (w('a) => 'b, w('b) => 'c, w('a)) => 'c = (\n    (f, g) => compose(g, C.extend(f)):\n      (w('a) => 'b, w('b) => 'c, w('a)) => 'c\n  );\n};\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet14.re",
    "content": "let duplicate: w('a) => w(w('a));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet15.re",
    "content": "module type ComonadBase = {\n  type w('a);\n\n  include Functor with type t('a) = w('a);\n\n  let extract: w('a) => 'a;\n};\n\nmodule type ComonadDuplicate = {\n  type w('a);\n\n  let duplicate: w('a) => w(w('a));\n};\n\nmodule type ComonadExtend = {\n  type w('a);\n\n  let extend: (w('a) => 'b, w('a)) => w('b);\n};\n\nmodule type Comonad = {\n  type w('a);\n\n  include ComonadBase with type w('a) := w('a);\n  include ComonadExtend with type w('a) := w('a);\n  include ComonadDuplicate with type w('a) := w('a);\n};\n\n/* Construct a full comonad instance using one of the \n* following modules */\nmodule ComonadImplViaExtend:\n  (C: ComonadBase, D: ComonadDuplicate with type w('a) = C.w('a)) =>\n   Comonad with type w('a) = C.w('a) =\n  (C: ComonadBase, D: ComonadDuplicate with type w('a) = C.w('a)) => {\n    include C;\n    include D;\n\n    let extend = (f, wa) => (C.fmap(f))(D.duplicate(wa));\n  };\n\nmodule ComonadImplViaDuplicate:\n  (C: ComonadBase, E: ComonadExtend with type w('a) = C.w('a)) =>\n   Comonad with type w('a) = C.w('a) =\n  (C: ComonadBase, E: ComonadExtend with type w('a) = C.w('a)) => {\n    include C;\n    include E;\n\n    let duplicate = (wa: w('a)): w(w('a)) => E.extend(id, wa);\n  };\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet16.re",
    "content": "type stream('a) =\n  | Cons('a, Lazy.t(stream('a)));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet17.re",
    "content": "module StreamFunctor: Functor with type t('a) = stream('a) = {\n  type t('a) = stream('a);\n\n  let rec fmap = f =>\n    fun\n    | Cons(x, xs) => Cons(f(x), Lazy.from_val(fmap(f, Lazy.force(xs))));\n};\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet18.re",
    "content": "let extract = (Cons(x, _)) => x;\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet19.re",
    "content": "let rec duplicate = (Cons(x, xs)) =>\n  Cons(Cons(x, xs), Lazy.from_val(duplicate(Lazy.force(xs))));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet20.re",
    "content": "/* Implement Extract */\nmodule StreamComonadBase =\n       (F: Functor with type t('a) = stream('a))\n       : (ComonadBase with type w('a) = stream('a)) => {\n  type w('a) = stream('a);\n\n  include F;\n\n  let extract = (Cons(x, _)) => x;\n};\n\n/* Implement duplicate */\nmodule StreamComonadDuplicate: ComonadDuplicate with type w('a) =\n    stream('a) = {\n  type w('a) = stream('a);\n\n  let rec duplicate = (Cons(x, xs)) =>\n    Cons(Cons(x, xs), Lazy.from_val(duplicate(Lazy.force(xs))));\n};\n\n/* Generate full Comonad Instance */\nmodule StreamComonad: Comonad with type w('a) = stream('a) =\n  ComonadImplViaExtend(\n    (StreamComonadBase(StreamFunctor)),\n    StreamComonadDuplicate,\n  );\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet21.re",
    "content": "let tail = (Cons(_, xs)) => Lazy.force(xs);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet22.re",
    "content": "let rec sum_s = (n, Cons(x, xs)) =>\n  n <= 0 ? 0 : x + sum_s(n - 1, Lazy.force(xs))\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet23.re",
    "content": "let average = (n, stm) => Float.(of_int(sum_s(n, stm)) /. of_int(n));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet24.re",
    "content": "let moving_average = n => StreamComonad.extend(average(n));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet25.re",
    "content": "module type Comonoid = {\n  type m;\n\n  let split: m => (m, m);\n  let destroy: m => unit;\n};\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet26.re",
    "content": "let destroy = _ => ();\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet27.re",
    "content": "let split = x => (f(x), g(x));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet28.re",
    "content": "/* lambda is the left unitor and rho is the right unitor */\n/* <.> is used as compose below */\n\nlambda\n<.> bimap(destroy, id)\n<.> split == id(rho)\n<.> bimap(id, destroy)\n<.> split == id;\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet29.re",
    "content": "lambda(bimap(destroy, id, split(x)))\n== lambda(bimap(destroy, id, (f(x), g(x))))\n== lambda(((), g(x)))\n== g(x);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet30.re",
    "content": "let split = x => (x, x);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet31.re",
    "content": "type store('s, 'a) =\n  | Store(('s => 'a, 's));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet32.re",
    "content": "let counit = (Prod(Reader(f), s)) => f(s);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet33.re",
    "content": "let extract = (Store(f, s)) => f(s);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet34.re",
    "content": "let unit = a => Reader(s => Prod(a, s));\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet35.re",
    "content": "let make_store = (f, s) => Store(f, s);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet36.re",
    "content": "let duplicate = (Store(f, s)) => Store(make_store(f), s);\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet37.re",
    "content": "module StoreComonadBase =\n       (S: {type s;}, F: Functor with type t('a) = store(S.s, 'a))\n       : (ComonadBase with type w('a) = store(S.s, 'a)) => {\n  type w('a) = store(S.s, 'a);\n\n  include F;\n\n  let extract = (Store(f, s)) => f(s);\n};\n\nmodule StoreComonadDuplicate =\n       (S: {type s;})\n       : (ComonadDuplicate with type w('a) = store(S.s, 'a)) => {\n  type w('a) = store(S.s, 'a);\n\n  let duplicate = (Store(f, s)) => Store(make_store(f), s);\n};\n\n/* Generate Full comonad */\nmodule StoreComonad =\n       (S: {type s;}, F: Functor with type t('a) = store(S.s, 'a))\n       : (Comonad with type w('a) = store(S.s, 'a)) =>\n  ComonadImplViaExtend(\n    (StoreComonadBase(S, F)),\n    (StoreComonadDuplicate(S)),\n  );\n"
  },
  {
    "path": "src/content/3.7/code/reason/snippet38.re",
    "content": "'a => store('s, 'a);"
  },
  {
    "path": "src/content/3.7/code/reason/snippet39.re",
    "content": "let get: 'a => 's;\nlet set: ('a, 's) => 'a;\n"
  },
  {
    "path": "src/content/3.7/code/scala/snippet01.scala",
    "content": "A => M[B]"
  },
  {
    "path": "src/content/3.7/code/scala/snippet02.scala",
    "content": "W[A] => B"
  },
  {
    "path": "src/content/3.7/code/scala/snippet03.scala",
    "content": "def =>=[A, B, C](w1: W[A] => B)(w2: W[B] => C): W[A] => C\n"
  },
  {
    "path": "src/content/3.7/code/scala/snippet04.scala",
    "content": "def extract[A](wa: W[A]): A"
  },
  {
    "path": "src/content/3.7/code/scala/snippet05.scala",
    "content": "trait Comonad[W[_]] extends Functor[W] {\n  def =>=[A, B, C](w1: W[A] => B)(w2: W[B] => C): W[A] => C\n  def extract[A](wa: W[A]): A\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet06.scala",
    "content": "((A, E)) => B"
  },
  {
    "path": "src/content/3.7/code/scala/snippet07.scala",
    "content": "A => (E => B)"
  },
  {
    "path": "src/content/3.7/code/scala/snippet08.scala",
    "content": "case class Product[E, A](run: (E, A))\n\n// implicit def productFunctor = ..."
  },
  {
    "path": "src/content/3.7/code/scala/snippet09.scala",
    "content": "def =>=[E, A, B, C]: (Product[E, A] => B) => (Product[E, B] => C) =>\n    (Product[E, A] => C) = f => g => {\n  case Product((e, a)) =>\n    val b = f(Product((e, a)))\n    val c = g(Product((e, b)))\n    c\n  }\n"
  },
  {
    "path": "src/content/3.7/code/scala/snippet10.scala",
    "content": "def extract[E, A]: Product[E, A] => A = {\n  case Product((e, a)) => a\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet11.scala",
    "content": "def =>=[W[_], A, B, C]: (W[A] => B) => (W[B] => C) => (W[A] => C) =\n  f => g => g ..."
  },
  {
    "path": "src/content/3.7/code/scala/snippet12.scala",
    "content": "def extend[W[_], A, B]: (W[A] => B) => W[A] => W[B]"
  },
  {
    "path": "src/content/3.7/code/scala/snippet13.scala",
    "content": "def =>=[W[_], A, B, C]: (W[A] => B) => (W[B] => C) => (W[A] => C) =\n  f => g => g compose extend(f)"
  },
  {
    "path": "src/content/3.7/code/scala/snippet14.scala",
    "content": "def duplicate[W[_], A]: W[A] => W[W[A]]"
  },
  {
    "path": "src/content/3.7/code/scala/snippet15.scala",
    "content": "trait Comonad[W[_]] extends Functor[W] {\n  def extract[A](wa: W[A]): A\n\n  def duplicate[A](wa: W[A]): W[W[A]] =\n    extend(identity[W[A]])(wa)\n\n  def extend[A, B](f: W[A] => B)(wa: W[A]): W[B] =\n    (fmap(f) _ compose duplicate)(wa)\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet16.scala",
    "content": "case class Stream[A](h: () => A, t: () => Stream[A])"
  },
  {
    "path": "src/content/3.7/code/scala/snippet17.scala",
    "content": "implicit val streamFunctor = new Functor[Stream] {\n  def fmap[A, B](f: A => B)(fa: Stream[A]): Stream[B] = fa match {\n    case Stream(a, as) =>\n      Stream(() => f(a()), () => fmap(f)(as()))\n  }\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet18.scala",
    "content": "def extract[A](wa: Stream[A]): A = wa match {\n  case Stream(a, _) => a()\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet19.scala",
    "content": "def duplicateS[A](wa: Stream[A]): Stream[Stream[A]] = wa match {\n  case s @ Stream(a, as) =>\n    Stream(() => s, () => duplicateS(as()))\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet20.scala",
    "content": "implicit val streamComonad = new Comonad[Stream] {\n  def extract[A](wa: Stream[A]): A =\n    wa match {\n      case Stream(a, _) => a()\n    }\n\n  def duplicate[A](wa: Stream[A]): Stream[Stream[A]] = wa match {\n    case s @ Stream(a, as) =>\n      Stream(() => s, () => duplicate(as()))\n  }\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet21.scala",
    "content": "def tail[A]: Stream[A] => Stream[A] = {\n  case Stream(a, as) => as()\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet22.scala",
    "content": "def sumS[A](n: Int)(stm: Stream[A])(implicit numeric: Numeric[A]): A =\n  stm match {\n    case Stream(a, as) =>\n      import numeric._\n      if (n <= 0) zero else a() + sumS(n - 1)(as())\n  }"
  },
  {
    "path": "src/content/3.7/code/scala/snippet23.scala",
    "content": "def average[A](n: Int)\n    (implicit fractional: Fractional[A]): Stream[A] => A = stm => {\n  import fractional._\n  sumS(n)(stm) / fromInt(n)\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet24.scala",
    "content": "def movingAvg[A](n: Int)(stm: Stream[A])\n    (implicit fractional: Fractional[A]): Stream[A] =\n  streamComonad.\n    extend(average(n)(fractional))(stm)"
  },
  {
    "path": "src/content/3.7/code/scala/snippet25.scala",
    "content": "trait Comonoid[M] {\n  def split(x: M): (M, M)\n  def destroy(x: M): Unit\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet26.scala",
    "content": "def destroy(x: M): Unit = ()"
  },
  {
    "path": "src/content/3.7/code/scala/snippet27.scala",
    "content": "def split(x: M): (M, M) = (f(x), g(x))"
  },
  {
    "path": "src/content/3.7/code/scala/snippet28.scala",
    "content": "(lambda compose bimap(destroy)(identity[M]))\n  .compose(split) == identity[M]\n\n(rho compose bimap(identity[M])(destroy))\n  .compose(split) == identity[M]"
  },
  {
    "path": "src/content/3.7/code/scala/snippet29.scala",
    "content": "lambda(bimap(destroy)(identity[M])(split(x))) ==\n  lambda(bimap(destroy)(identity[M])((f(x), g(x)))) ==\n  lambda(((), g(x))) ==\n  g(x)"
  },
  {
    "path": "src/content/3.7/code/scala/snippet30.scala",
    "content": "def split(x: M): (M, M) = (x, x)"
  },
  {
    "path": "src/content/3.7/code/scala/snippet31.scala",
    "content": "case class Store[S, A](run: S => A, s: S)"
  },
  {
    "path": "src/content/3.7/code/scala/snippet32.scala",
    "content": "def counit[S, A](a: Product[S, Reader[S, A]]): A = a match {\n  case Product((Reader(f), s)) => f(s)\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet33.scala",
    "content": "def extract[A](wa: Store[S, A]): A = wa match {\n  case Store(f, s) => f(s)\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet34.scala",
    "content": "def unit[S, A](a: A): Reader[S, Product[S, A]] =\n  Reader(s => Product((a, s)))"
  },
  {
    "path": "src/content/3.7/code/scala/snippet35.scala",
    "content": "object Store {\n  def apply[S, A](run: S => A): S => Store[S, A] =\n    s => new Store(run, s)\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet36.scala",
    "content": "def duplicate[A](wa: Store[S, A]): Store[S, Store[S, A]] = wa match {\n  case Store(f, s) => Store(Store(f), s)\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet37.scala",
    "content": "implicit def storeComonad[S] = new Comonad[Store[S, ?]] {\n  def extract[A](wa: Store[S, A]): A = wa match {\n    case Store(f, s) => f(s)\n  }\n\n  override def duplicate[A](wa: Store[S, A]): Store[S, Store[S, A]] =\n    wa match {\n      case Store(f, s) => Store(Store(f), s)\n    }\n}"
  },
  {
    "path": "src/content/3.7/code/scala/snippet38.scala",
    "content": "A => Store[S, A]"
  },
  {
    "path": "src/content/3.7/code/scala/snippet39.scala",
    "content": "def set[A, S]: A => S => A\ndef get[A, S]: A => S"
  },
  {
    "path": "src/content/3.7/comonads.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{N}{ow that we have covered} monads, we can reap the benefits of duality and\nget comonads for free simply by reversing the arrows and working in the\nopposite category.\n\nRecall that, at the most basic level, monads are about composing Kleisli\narrows:\n\n\\src{snippet01}\nwhere \\code{m} is a functor that is a monad. If we use the letter\n\\code{w} (upside down \\code{m}) for the comonad, we can define\nco-Kleisli arrows as morphism of the type:\n\n\\src{snippet02}\nThe analog of the fish operator for co-Kleisli arrows is defined as:\n\n\\src{snippet03}\nFor co-Kleisli arrows to form a category we also have to have an\nidentity co-Kleisli arrow, which is called \\code{extract}:\n\n\\src{snippet04}\nThis is the dual of \\code{return}. We also have to impose the laws of\nassociativity as well as left- and right-identity. Putting it all\ntogether, we could define a comonad in Haskell as:\n\n\\src{snippet05}\nIn practice, we use slightly different primitives, as we'll see shortly.\n\nThe question is, what's the use for comonads in programming?\n\n\\section{Programming with Comonads}\n\nLet's compare the monad with the comonad. A monad provides a way of\nputting a value in a container using \\code{return}. It doesn't give\nyou access to a value or values stored inside. Of course, data\nstructures that implement monads might provide access to their contents,\nbut that's considered a bonus. There is no common interface for\nextracting values from a monad. And we've seen the example of the\n\\code{IO} monad that prides itself in never exposing its contents.\n\nA comonad, on the other hand, provides the means of extracting a single\nvalue from it. It does not give the means to insert values. So if you\nwant to think of a comonad as a container, it always comes pre-filled\nwith contents, and it lets you peek at it.\n\nJust as a Kleisli arrow takes a value and produces some embellished\nresult --- it embellishes it with context --- a co-Kleisli arrow takes a\nvalue together with a whole context and produces a result. It's an\nembodiment of \\newterm{contextual computation}.\n\n\\section{The Product Comonad}\n\nRemember the reader monad? We introduced it to tackle the problem of\nimplementing computations that need access to some read-only environment\n\\code{e}. Such computations can be represented as pure functions of\nthe form:\n\n\\src{snippet06}\nWe used currying to turn them into Kleisli arrows:\n\n\\src{snippet07}\nBut notice that these functions already have the form of co-Kleisli\narrows. Let's massage their arguments into the more convenient functor\nform:\n\n\\src{snippet08}\nWe can easily define the composition operator by making the same\nenvironment available to the arrows that we are composing:\n\n\\src{snippet09}\nThe implementation of \\code{extract} simply ignores the environment:\n\n\\src{snippet10}\nNot surprisingly, the product comonad can be used to perform exactly the\nsame computations as the reader monad. In a way, the comonadic\nimplementation of the environment is more natural --- it follows the\nspirit of ``computation in context.'' On the other hand, monads come\nwith the convenient syntactic sugar of the \\code{do} notation.\n\nThe connection between the reader monad and the product comonad goes\ndeeper, having to do with the fact that the reader functor is the right\nadjoint of the product functor. In general, though, comonads cover\ndifferent notions of computation than monads. We'll see more examples\nlater.\n\nIt's easy to generalize the \\code{Product} comonad to arbitrary\nproduct types including tuples and records.\n\n\\section{Dissecting the Composition}\n\nContinuing the process of dualization, we could go ahead and dualize\nmonadic bind and join. Alternatively, we can repeat the process we used\nwith monads, where we studied the anatomy of the fish operator. This\napproach seems more enlightening.\n\nThe starting point is the realization that the composition operator must\nproduce a co-Kleisli arrow that takes \\code{w a} and produces a\n\\code{c}. The only way to produce a \\code{c} is to apply the second\nfunction to an argument of the type \\code{w b}:\n\n\\src{snippet11}\nBut how can we produce a value of type \\code{w b} that could be fed\nto \\code{g}? We have at our disposal the argument of type\n\\code{w a} and the function \\code{f :: w a -> b}.\nThe solution is to define the dual of bind, which is called extend:\n\n\\src{snippet12}\nUsing \\code{extend} we can implement composition:\n\n\\src{snippet13}\nCan we next dissect \\code{extend}? You might be tempted to say, why\nnot just apply the function \\code{w a -> b} to the\nargument \\code{w a}, but then you quickly realize that you'd have no\nway of converting the resulting \\code{b} to \\code{w b}. Remember,\nthe comonad provides no means of lifting values. At this point, in the\nanalogous construction for monads, we used \\code{fmap}. The only way\nwe could use \\code{fmap} here would be if we had something of the type\n\\code{w (w a)} at our disposal. If we could only turn \\code{w a}\ninto\\\\ \\code{w (w a)}. And, conveniently, that would be exactly the\ndual of \\code{join}. We call it \\code{duplicate}:\n\n\\src{snippet14}\nSo, just like with the definitions of the monad, we have three\nequivalent definitions of the comonad: using co-Kleisli arrows,\n\\code{extend}, or \\code{duplicate}. Here's the Haskell definition\ntaken directly from\\\\ \\code{Control.Comonad} library:\n\n\\src{snippet15}\nProvided are the default implementations of \\code{extend} in terms of\n\\code{duplicate} and vice versa, so you only need to override one of\nthem.\n\nThe intuition behind these functions is based on the idea that, in\ngeneral, a comonad can be thought of as a container filled with values\nof type \\code{a} (the product comonad was a special case of just one\nvalue). There is a notion of the ``current'' value, one that's easily\naccessible through \\code{extract}. A co-Kleisli arrow performs some\ncomputation that is focused on the current value, but it has access to\nall the surrounding values. Think of the Conway's game of life. Each\ncell contains a value (usually just \\code{True} or \\code{False}). A\ncomonad corresponding to the game of life would be a grid of cells\nfocused on the ``current'' cell.\n\nSo what does \\code{duplicate} do? It takes a comonadic container\n\\code{w a} and produces a container of containers \\code{w (w a)}.\nThe idea is that each of these containers is focused on a different\n\\code{a} inside \\code{w a}. In the game of life, you would get a\ngrid of grids, each cell of the outer grid containing an inner grid\nthat's focused on a different cell.\n\nNow look at \\code{extend}. It takes a co-Kleisli arrow and a comonadic\ncontainer \\code{w a} filled with \\code{a}s. It applies the\ncomputation to all of these \\code{a}s, replacing them with\n\\code{b}s. The result is a comonadic container filled with\n\\code{b}s. \\code{extend} does it by shifting the focus from one\n\\code{a} to another and applying the co-Kleisli arrow to each of them\nin turn. In the game of life, the co-Kleisli arrow would calculate the\nnew state of the current cell. To do that, it would look at its context\n--- presumably its nearest neighbors. The default implementation of\n\\code{extend} illustrates this process. First we call\n\\code{duplicate} to produce all possible foci and then we apply\n\\code{f} to each of them.\n\n\\section{The Stream Comonad}\n\nThis process of shifting the focus from one element of the container to\nanother is best illustrated with the example of an infinite stream. Such\na stream is just like a list, except that it doesn't have the empty\nconstructor:\n\n\\src{snippet16}\nIt's trivially a \\code{Functor}:\n\n\\src{snippet17}\nThe focus of a stream is its first element, so here's the implementation\nof \\code{extract}:\n\n\\src{snippet18}\n\\code{duplicate} produces a stream of streams, each focused on a\ndifferent element.\n\n\\src{snippet19}\nThe first element is the original stream, the second element is the tail\nof the original stream, the third element is its tail, and so on, ad\ninfinitum.\n\nHere's the complete instance:\n\n\\src{snippet20}\nThis is a very functional way of looking at streams. In an imperative\nlanguage, we would probably start with a method \\code{advance} that\nshifts the stream by one position. Here, \\code{duplicate} produces all\nshifted streams in one fell swoop. Haskell's laziness makes this\npossible and even desirable. Of course, to make a \\code{Stream}\npractical, we would also implement the analog of \\code{advance}:\n\n\\src{snippet21}\nbut it's never part of the comonadic interface.\n\nIf you had any experience with digital signal processing, you'll see\nimmediately that a co-Kleisli arrow for a stream is just a digital\nfilter, and \\code{extend} produces a filtered stream.\n\nAs a simple example, let's implement the moving average filter. Here's a\nfunction that sums \\code{n} elements of a stream:\n\n\\src{snippet22}\nHere's the function that calculates the average of the first \\code{n}\nelements of the stream:\n\n\\src{snippet23}\nPartially applied \\code{average n} is a co-Kleisli arrow, so we can\n\\code{extend} it over the whole stream:\n\n\\src{snippet24}\nThe result is the stream of running averages.\n\nA stream is an example of a unidirectional, one-dimensional comonad. It\ncan be easily made bidirectional or extended to two or more dimensions.\n\n\\section{Comonad Categorically}\n\nDefining a comonad in category theory is a straightforward exercise in\nduality. As with the monad, we start with an endofunctor $T$. The\ntwo natural transformations, $\\eta$ and $\\mu$, that define the monad are simply\nreversed for the comonad:\n\\begin{align*}\n  \\varepsilon & \\Colon T \\to I   \\\\\n  \\delta      & \\Colon T \\to T^2\n\\end{align*}\nThe components of these transformations correspond to \\code{extract}\nand \\code{duplicate}. Comonad laws are the mirror image of monad laws.\nNo big surprise here.\n\nThen there is the derivation of the monad from an adjunction. Duality\nreverses an adjunction: the left adjoint becomes the right adjoint and\nvice versa. And, since the composition $R \\circ L$ defines a monad,\n$L \\circ R$ must define a comonad. The counit of the adjunction:\n\\[\\varepsilon \\Colon L \\circ R \\to I\\]\nis indeed the same $\\varepsilon$ that we see in the definition of the comonad ---\nor, in components, as Haskell's \\code{extract}. We can also use the\nunit of the adjunction:\n\\[\\eta \\Colon I \\to R \\circ L\\]\nto insert an $R \\circ L$ in the middle of $L \\circ R$ and\nproduce $L \\circ R \\circ L \\circ R$. Making $T^2$ from $T$\ndefines the $\\delta$, and that completes the definition of the comonad.\n\nWe've also seen that the monad is a monoid. The dual of this statement\nwould require the use of a comonoid, so what's a comonoid? The original\ndefinition of a monoid as a single-object category doesn't dualize to\nanything interesting. When you reverse the direction of all\nendomorphisms, you get another monoid. Recall, however, that in our\napproach to a monad, we used a more general definition of a monoid as an\nobject in a monoidal category. The construction was based on two\nmorphisms:\n\\begin{align*}\n  \\mu  & \\Colon m \\otimes m \\to m \\\\\n  \\eta & \\Colon i \\to m\n\\end{align*}\nThe reversal of these morphisms produces a comonoid in a monoidal\ncategory:\n\\begin{align*}\n  \\delta      & \\Colon m \\to m \\otimes m \\\\\n  \\varepsilon & \\Colon m \\to i\n\\end{align*}\nOne can write a definition of a comonoid in Haskell:\n\n\\src{snippet25}\nbut it is rather trivial. Obviously \\code{destroy} ignores its\nargument.\n\n\\src{snippet26}\n\\code{split} is just a pair of functions:\n\n\\src{snippet27}\nNow consider comonoid laws that are dual to the monoid unit laws.\n\n\\src{snippet28}\nHere, \\code{lambda} and \\code{rho} are the left and right unitors,\nrespectively (see the definition of\n\\hyperref[monads-categorically]{monoidal\n  categories}). Plugging in the definitions, we get:\n\n\\src{snippet29}\nwhich proves that \\code{g = id}. Similarly, the second law expands\nto \\code{f = id}. In conclusion:\n\n\\src{snippet30}\nwhich shows that in Haskell (and, in general, in the category\n$\\Set$) every object is a trivial comonoid.\n\nFortunately there are other more interesting monoidal categories in\nwhich to define comonoids. One of them is the category of endofunctors.\nAnd it turns out that, just like the monad is a monoid in the category\nof endofunctors,\n\n\\begin{quote}\n  The comonad is a comonoid in the category of endofunctors.\n\\end{quote}\n\n\\section{The Store Comonad}\n\nAnother important example of a comonad is the dual of the state monad.\nIt's called the costate comonad or, alternatively, the store comonad.\n\nWe've seen before that the state monad is generated by the adjunction\nthat defines the exponentials:\n\\begin{align*}\n  L z & = z\\times{}s      \\\\\n  R a & = s \\Rightarrow a\n\\end{align*}\nWe'll use the same adjunction to define the costate comonad. A comonad\nis defined by the composition $L \\circ R$:\n\\[L (R a) = (s \\Rightarrow a)\\times{}s\\]\nTranslating this to Haskell, we start with the adjunction between the\n\\code{Product} functor on the left and the \\code{Reader} functor or the\nright. Composing \\code{Product} after \\code{Reader} is equivalent to\nthe following definition:\n\n\\src{snippet31}\nThe counit of the adjunction taken at the object $a$ is the\nmorphism:\n\\[\\varepsilon_a \\Colon ((s \\Rightarrow a)\\times{}s) \\to a\\]\nor, in Haskell notation:\n\n\\src{snippet32}\nThis becomes our \\code{extract}:\n\n\\src{snippet33}\nThe unit of the adjunction:\n\n\\src{snippet34}\ncan be rewritten as partially applied data constructor:\n\n\\src{snippet35}\nWe construct $\\delta$, or \\code{duplicate}, as the horizontal composition:\n\\begin{align*}\n  \\delta & \\Colon L \\circ R \\to L \\circ R \\circ L \\circ R \\\\\n  \\delta & = L \\circ \\eta \\circ R\n\\end{align*}\nWe have to sneak $\\eta$ through the leftmost $L$, which is the\n\\code{Product} functor. It means acting with $\\eta$, or \\code{Store f}, on\nthe left component of the pair (that's what \\code{fmap} for\n\\code{Product} would do). We get:\n\n\\src{snippet36}\n(Remember that, in the formula for $\\delta$, $L$ and $R$ stand\nfor identity natural transformations whose components are identity\nmorphisms.)\n\nHere's the complete definition of the \\code{Store} comonad:\n\n\\src{snippet37}\nYou may think of the \\code{Reader} part of \\code{Store} as a\ngeneralized container of \\code{a}s that are keyed using elements of\nthe type \\code{s}. For instance, if \\code{s} is \\code{Int},\n\\code{Reader Int a} is an infinite bidirectional stream of\n\\code{a}s. \\code{Store} pairs this container with a value of the key\ntype. For instance, \\code{Reader Int a} is paired with an\n\\code{Int}. In this case, \\code{extract} uses this integer to index\ninto the infinite stream. You may think of the second component of\n\\code{Store} as the current position.\n\nContinuing with this example, \\code{duplicate} creates a new infinite\nstream indexed by an \\code{Int}. This stream contains streams as its\nelements. In particular, at the current position, it contains the\noriginal stream. But if you use some other \\code{Int} (positive or\nnegative) as the key, you'd obtain a shifted stream positioned at that\nnew index.\n\nIn general, you can convince yourself that when \\code{extract} acts on\nthe \\code{duplicate}d \\code{Store} it produces the original\n\\code{Store} (in fact, the identity law for the comonad states that\n\\code{extract . duplicate = id}).\n\nThe \\code{Store} comonad plays an important role as the theoretical\nbasis for the \\code{lens} library. Conceptually, the\n\\code{Store s a} comonad encapsulates the idea of ``focusing'' (like\na lens) on a particular substructure of the data type \\code{a} using\nthe type \\code{s} as an index. In particular, a function of the type:\n\n\\src{snippet38}\nis equivalent to a pair of functions:\n\n\\src{snippet39}\nIf \\code{a} is a product type, \\code{set} could be implemented as\nsetting the field of type \\code{s} inside of \\code{a} while\nreturning the modified version of \\code{a}. Similarly, \\code{get}\ncould be implemented to read the value of the \\code{s} field from\n\\code{a}. We'll explore these ideas more in the next section.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Implement the Conway's Game of Life using the \\code{Store} comonad.\n        Hint: What type do you pick for \\code{s}?\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet01.hs",
    "content": "type Algebra f a = f a -> a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet02.hs",
    "content": "data MonF a = MEmpty | MAppend a a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet03.hs",
    "content": "data RingF a = RZero\n             | ROne\n             | RAdd a a\n             | RMul a a\n             | RNeg a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet04.hs",
    "content": "evalZ :: Algebra RingF Integer\nevalZ RZero      = 0\nevalZ ROne       = 1\nevalZ (RAdd m n) = m + n\nevalZ (RMul m n) = m * n\nevalZ (RNeg n)   = -n"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet05.hs",
    "content": "data Expr = RZero \n          | ROne\n          | RAdd Expr Expr\n          | RMul Expr Expr\n          | RNeg Expr"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet06.hs",
    "content": "evalZ :: Expr -> Integer\nevalZ RZero        = 0\nevalZ ROne         = 1\nevalZ (RAdd e1 e2) = evalZ e1 + evalZ e2\nevalZ (RMul e1 e2) = evalZ e1 * evalZ e2\nevalZ (RNeg e)     = -(evalZ e)"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet07.hs",
    "content": "type RingF1 a = RingF (RingF a)"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet08.hs",
    "content": "type RingF2 a = RingF (RingF (RingF a))"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet09.hs",
    "content": "type RingF2 a = RingF (RingF1 a)"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet10.hs",
    "content": "newtype Fix f = Fix (f (Fix f))"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet11.hs",
    "content": "newtype Fix f = In (f (Fix f))"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet12.hs",
    "content": "Fix :: f (Fix f) -> Fix f"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet13.hs",
    "content": "unFix :: Fix f -> f (Fix f)\nunFix (Fix x) = x"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet14.hs",
    "content": "data NatF a = ZeroF | SuccF a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet15.hs",
    "content": "data Nat = Zero | Succ Nat"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet16.hs",
    "content": "cata :: Functor f => (f a -> a) -> Fix f -> a\ncata alg = alg . fmap (cata alg) . unFix"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet17.hs",
    "content": "data NatF a = ZeroF | SuccF a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet18.hs",
    "content": "fib :: NatF (Int, Int) -> (Int, Int)\nfib ZeroF = (1, 1)\nfib (SuccF (m, n)) = (n, m + n)"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet19.hs",
    "content": "data ListF e a = NilF | ConsF e a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet20.hs",
    "content": "data List e = Nil | Cons e (List e)"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet21.hs",
    "content": "lenAlg :: ListF e Int -> Int\nlenAlg (ConsF e n) = n + 1\nlenAlg NilF = 0"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet22.hs",
    "content": "length = foldr (\\e n -> n + 1) 0"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet23.hs",
    "content": "sumAlg :: ListF Double Double -> Double\nsumAlg (ConsF e s) = e + s\nsumAlg NilF = 0.0"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet24.hs",
    "content": "sum = foldr (\\e s -> e + s) 0.0"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet25.hs",
    "content": "ana :: Functor f => (a -> f a) -> a -> Fix f\nana coalg = Fix . fmap (ana coalg) . coalg"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet26.hs",
    "content": "data StreamF e a = StreamF e a\n  deriving Functor"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet27.hs",
    "content": "data Stream e = Stream e (Stream e)"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet28.hs",
    "content": "era :: [Int] -> StreamF Int [Int]\nera (p : ns) = StreamF p (filter (notdiv p) ns)\n    where notdiv p n = n `mod` p /= 0"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet29.hs",
    "content": "primes = ana era [2..]"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet30.hs",
    "content": "toListC :: Fix (StreamF e) -> [e]\ntoListC = cata al\n    where al :: StreamF e [e] -> [e] \n          al (StreamF e a) = e : a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet31.hs",
    "content": "unfoldr :: (b -> Maybe (a, b)) -> b -> [a]"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet32.hs",
    "content": "set :: a -> s -> a\nget :: a -> s"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet33.hs",
    "content": "a -> (s, s -> a)"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet34.hs",
    "content": "a -> Store s a"
  },
  {
    "path": "src/content/3.8/code/haskell/snippet35.hs",
    "content": "data Store s a = Store (s -> a) s"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet01.ml",
    "content": "module type Algebra = functor\n  (F : sig\n     type 'a f\n   end)\n  -> sig\n  type 'a algebra = 'a F.f -> 'a\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet02.ml",
    "content": "type 'a mon_f =\n  | MEmpty\n  | Mappend of ('a * 'a)\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet03.ml",
    "content": "type 'a ring_f =\n  | RZero\n  | ROne\n  | RAdd of ('a * 'a)\n  | RMul of ('a * 'a)\n  | RNeg of 'a\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet04.ml",
    "content": "module Ring = struct\n  module RingAlg = Algebra (struct\n    type 'a f = 'a ring_f\n  end)\n\n  let eval_z : 'a RingAlg.algebra = function\n    | RZero -> 0\n    | ROne -> 1\n    | RAdd (m, n) -> m + n\n    | RMul (m, n) -> m * n\n    | RNeg n -> -n\n  ;;\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet05.ml",
    "content": "type expr =\n  | RZero\n  | ROne\n  | RAdd of (expr * expr)\n  | RMul of (expr * expr)\n  | RNeg of expr\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet06.ml",
    "content": "let rec eval_z : expr -> int = function\n  | RZero -> 0\n  | ROne -> 1\n  | RAdd (e1, e2) -> eval_z e1 + eval_z e2\n  | RMul (e1, e2) -> eval_z e1 * eval_z e2\n  | RNeg e -> -eval_z e\n;;\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet07.ml",
    "content": "type 'a ring_f1 = 'a ring_f ring_f\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet08.ml",
    "content": "type 'a ring_f2 = 'a ring_f ring_f ring_f\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet09.ml",
    "content": "type 'a ring_f2 = 'a ring_f ring_f1\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet10.ml",
    "content": "module Fix (F : Functor) = struct\n  type 'a fix = Fix of 'a fix F.t\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet11.ml",
    "content": "module Fix (F : Functor) = struct\n  type 'a fix = In of 'a fix F.t\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet12.ml",
    "content": "module Fix (F : Functor) = struct\n  type 'a fix = Fix of 'a fix F.t\n\n  let fix : 'a fix F.t -> 'a fix = fun f -> Fix f\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet13.ml",
    "content": "module Fix (F : Functor) = struct\n  type 'a fix = Fix of 'a fix F.t\n\n  let unfix : 'a fix -> 'a fix F.t = fun (Fix f) -> f\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet14.ml",
    "content": "type 'a nat_f =\n  | ZeroF\n  | SuccF of 'a\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet15.ml",
    "content": "type nat =\n  | Zero\n  | Succ of nat\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet16.ml",
    "content": "module Cata (F : Functor) = struct\n  type 'a fix = Fix of 'a fix F.t\n\n  let fix : 'a fix F.t -> 'a fix = fun f -> Fix f\n  let unfix : 'a fix -> 'a fix F.t = fun (Fix f) -> f\n\n  let rec cata : ('a F.t -> 'a) -> 'a fix -> 'a =\n   fun alg fixf -> alg (F.fmap (cata alg) (unfix fixf))\n ;;\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet17.ml",
    "content": "type 'a nat_f =\n  | ZeroF\n  | SuccF of 'a\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet18.ml",
    "content": "let rec fib = function\n  | ZeroF -> 1, 1\n  | SuccF (m, n) -> n, m + n\n;;\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet19.ml",
    "content": "type ('e, 'a) list_f =\n  | NilF\n  | ConsF of ('e * 'a)\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet20.ml",
    "content": "type 'e list' =\n  | Nil\n  | Cons of ('e * 'e list')\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet21.ml",
    "content": "let len_alg = function\n  | ConsF (e, n) -> n + 1\n  | NilF -> 0\n;;\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet22.ml",
    "content": "let length xs = List.fold_right (fun e n -> n + 1) xs 0\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet23.ml",
    "content": "let sum_alg = function\n  | ConsF (e, s) -> e +. s\n  | NilF -> 0.0\n;;\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet24.ml",
    "content": "let sum xs = List.fold_right (fun e s -> e +. s) xs 0.0\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet25.ml",
    "content": "module Ana (F : Functor) = struct\n  type 'a fix = Fix of 'a fix F.t\n\n  let rec ana : ('a -> 'a F.t) -> 'a -> 'a fix =\n   fun coalg a -> Fix (F.fmap (ana coalg) (coalg a))\n ;;\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet26.ml",
    "content": "type ('e, 'a) stream_f = StreamF of ('e * 'a)\n\nmodule Stream_Functor (E : sig\n  type e\nend) : Functor with type 'a t = (E.e, 'a) stream_f = struct\n  type 'a t = (E.e, 'a) stream_f\n\n  let fmap f = function\n    | StreamF (e, a) -> StreamF (e, f a)\n  ;;\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet27.ml",
    "content": "type 'e stream = Stream of ('e * 'e stream)\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet28.ml",
    "content": "(* OCaml library `gen` provides useful helpers for \n   potentially infinite iterators. You can install it\n   with `opam install gen`. To use it in the toplevel,\n   you need to `#require \"gen\"` *)\nlet era : int Gen.t -> (int, int Gen.t) stream_f =\n fun ilist ->\n  let notdiv p n = n mod p != 0 in\n  let p = Gen.get_exn ilist in\n  StreamF (p, Gen.filter (notdiv p) ilist)\n;;\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet29.ml",
    "content": "module Stream_Int = Stream_Functor (struct\n  type e = int\nend)\n\nmodule Ana_Stream = Ana (Stream_Int)\n\n(* The fixpoint translated to OCaml is eager in its evaluation. \nHence, executing the following function will cause overflow.\nSo, wrapping it inside a lazy *)\nlet primes = lazy (Ana_Stream.ana era (Gen.init (fun i -> i + 2)))\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet30.ml",
    "content": "module List_C (E : sig\n  type e\nend) =\nstruct\n  module Stream_F : Functor with type 'a t = (E.e, 'a) stream_f =\n    Stream_Functor (E)\n\n  module Cata_Stream = Cata (Stream_F)\n\n  let to_list_c : E.e list Cata_Stream.fix -> E.e list =\n   fun s_fix ->\n    Cata_Stream.cata (fun (StreamF (e, a)) -> e :: a) s_fix\n ;;\nend\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet31.ml",
    "content": "(* Gen.t is used to represent infinite data structures like haskell's\n   lazy list *)\nval unfold : ('b -> ('a * 'b) option) -> 'b -> 'a Gen.t\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet32.ml",
    "content": "val set : 'a -> 's -> 'a\nval get : 'a -> 's\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet33.ml",
    "content": "(a, (s, s -> a))\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet34.ml",
    "content": "'a -> ('s, 'a) store\n"
  },
  {
    "path": "src/content/3.8/code/ocaml/snippet35.ml",
    "content": "(* Store is the comonad version of State *)\ntype ('s, 'a) store = Store of ('s -> 'a) * 's\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet01.re",
    "content": "module type Algebra =\n  (F: {type f('a);}) => {type algebra('a) = F.f('a) => 'a;};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet02.re",
    "content": "type mon_f('a) =\n  | MEmpty\n  | Mappend(('a, 'a));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet03.re",
    "content": "type ring_f('a) =\n  | RZero\n  | ROne\n  | RAdd(('a, 'a))\n  | RMul(('a, 'a))\n  | RNeg('a);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet04.re",
    "content": "module Ring = {\n  module RingAlg = Algebra({type f('a) = ring_f('a);});\n\n  let eval_z: RingAlg.algebra('a) = (\n    fun\n    | RZero => 0\n    | ROne => 1\n    | RAdd(m, n) => m + n\n    | RMul(m, n) => m * n\n    | RNeg(n) => - n\n  );\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet05.re",
    "content": "type expr =\n  | RZero\n  | ROne\n  | RAdd((expr, expr))\n  | RMul((expr, expr))\n  | RNeg(expr);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet06.re",
    "content": "let rec eval_z: expr => int = (\n  fun\n  | RZero => 0\n  | ROne => 1\n  | RAdd(e1, e2) => eval_z(e1) + eval_z(e2)\n  | RMul(e1, e2) => eval_z(e1) * eval_z(e2)\n  | RNeg(e) => - eval_z(e)\n);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet07.re",
    "content": "type ring_f1('a) = ring_f(ring_f('a));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet08.re",
    "content": "type ring_f2('a) = ring_f(ring_f(ring_f('a)));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet09.re",
    "content": "type ring_f2('a) = ring_f1(ring_f('a));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet10.re",
    "content": "module Fix = (F: Functor) => {\n  type fix('a) =\n    | Fix(F.t(fix('a)));\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet11.re",
    "content": "module Fix = (F: Functor) => {\n  type fix('a) =\n    | In(F.t(fix('a)));\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet12.re",
    "content": "module Fix = (F: Functor) => {\n  type fix('a) =\n    | Fix(F.t(fix('a)));\n\n  let fix: F.t(fix('a)) => fix('a) = (\n    f => Fix(f): F.t(fix('a)) => fix('a)\n  );\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet13.re",
    "content": "module Fix = (F: Functor) => {\n  type fix('a) =\n    | Fix(F.t(fix('a)));\n\n  let unfix: fix('a) => F.t(fix('a)) = (\n    (Fix(f)) => f: fix('a) => F.t(fix('a))\n  );\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet14.re",
    "content": "type nat_f('a) =\n  | ZeroF\n  | SuccF('a);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet15.re",
    "content": "type nat =\n  | Zero\n  | Succ(nat);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet16.re",
    "content": "module Cata = (F: Functor) => {\n  type fix('a) =\n    | Fix(F.t(fix('a)));\n\n  let fix: F.t(fix('a)) => fix('a) = (\n    f => Fix(f): F.t(fix('a)) => fix('a)\n  );\n  let unfix: fix('a) => F.t(fix('a)) = (\n    (Fix(f)) => f: fix('a) => F.t(fix('a))\n  );\n\n  let rec cata: (F.t('a) => 'a, fix('a)) => 'a = (\n    (alg, fixf) => alg(F.fmap(cata(alg), unfix(fixf))):\n      (F.t('a) => 'a, fix('a)) => 'a\n  );\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet17.re",
    "content": "type nat_f('a) =\n  | ZeroF\n  | SuccF('a);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet18.re",
    "content": "let rec fib =\n  fun\n  | ZeroF => (1, 1)\n  | SuccF(m, n) => (n, m + n);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet19.re",
    "content": "type list_f('e, 'a) =\n  | NilF\n  | ConsF(('e, 'a));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet20.re",
    "content": "type list'('e) =\n  | Nil\n  | Cons(('e, list'('e)));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet21.re",
    "content": "let len_alg =\n  fun\n  | ConsF(e, n) => n + 1\n  | NilF => 0;\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet22.re",
    "content": "let length = xs => List.fold_right((e, n) => n + 1, xs, 0);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet23.re",
    "content": "let sum_alg =\n  fun\n  | ConsF(e, s) => e +. s\n  | NilF => 0.0;\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet24.re",
    "content": "let sum = xs => List.fold_right((e, s) => e +. s, xs, 0.0);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet25.re",
    "content": "module Ana = (F: Functor) => {\n  type fix('a) =\n    | Fix(F.t(fix('a)));\n\n  let rec ana: ('a => F.t('a), 'a) => fix('a) = (\n    (coalg, a) => Fix(F.fmap(ana(coalg), coalg(a))):\n      ('a => F.t('a), 'a) => fix('a)\n  );\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet26.re",
    "content": "type stream_f('e, 'a) =\n  | StreamF(('e, 'a));\n\nmodule Stream_Functor = (E: {type e;}) : \n       (Functor with type t('a) = stream_f(E.e, 'a)) => {\n  type t('a) = stream_f(E.e, 'a);\n\n  let fmap = f =>\n    fun\n    | StreamF(e, a) => StreamF(e, f(a));\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet27.re",
    "content": "type stream('e) =\n  | Stream(('e, stream('e)));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet28.re",
    "content": "/* OCaml library `gen` provides useful helpers for\n   potentially infinite iterators. You can install it\n   with `opam install gen`. To use it in the toplevel,\n   you need to `#require \"gen\"` */\nlet era: Gen.t(int) => stream_f(int, Gen.t(int)) = (ilist => {\n    let notdiv = (p, n) => n mod p !== 0;\n    let p = Gen.get_exn(ilist);\n    StreamF(p, Gen.filter(notdiv(p), ilist));\n});"
  },
  {
    "path": "src/content/3.8/code/reason/snippet29.re",
    "content": "module Stream_Int = Stream_Functor({type e = int;});\n\nmodule Ana_Stream = Ana(Stream_Int);\n\n/* The fixpoint translated to ReasonML is eager in its evaluation.\n   Hence, executing the following function will cause overflow.\n   So, wrapping it inside a lazy */\nlet primes = lazy(Ana_Stream.ana(era, Gen.init(i => i + 2)));\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet30.re",
    "content": "module List_C = (E: {type e;}) => {\n  module Stream_F: Functor with type t('a) = stream_f(E.e, 'a) =\n    Stream_Functor(E);\n\n  module Cata_Stream = Cata(Stream_F);\n\n  let to_list_c: Cata_Stream.fix(list(E.e)) => list(E.e) = (\n    s_fix => Cata_Stream.cata((StreamF(e, a)) => [e, ...a], s_fix):\n      Cata_Stream.fix(list(E.e)) => list(E.e)\n  );\n};\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet31.re",
    "content": "/* Gen.t is used to represent infinite data structures \n   like haskell's lazy list */\nlet unfold: ('b => option(('a, 'b)), 'b) => Gen.t('a);\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet32.re",
    "content": "let set: ('a, 's) => 'a;\nlet get: 'a => 's;\n"
  },
  {
    "path": "src/content/3.8/code/reason/snippet33.re",
    "content": "(a, (s, s => a));"
  },
  {
    "path": "src/content/3.8/code/reason/snippet34.re",
    "content": "'a => store('s, 'a);"
  },
  {
    "path": "src/content/3.8/code/reason/snippet35.re",
    "content": "/* Store is the comonad version of State */\ntype store('s, 'a) =\n  | Store('s => 'a, 's);\n"
  },
  {
    "path": "src/content/3.8/code/scala/snippet01.scala",
    "content": "type Algebra[F[_], A] = F[A] => A"
  },
  {
    "path": "src/content/3.8/code/scala/snippet02.scala",
    "content": "sealed trait MonF[+A]\ncase object MEmpty extends MonF[Nothing]\ncase class MAppend[A](m: A, n: A) extends MonF[A]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet03.scala",
    "content": "sealed trait RingF[+A]\ncase object RZero extends RingF[Nothing]\ncase object ROne extends RingF[Nothing]\ncase class RAdd[A](m: A, n: A) extends RingF[A]\ncase class RMul[A](m: A, n: A) extends RingF[A]\ncase class RNeg[A](n: A) extends RingF[A]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet04.scala",
    "content": "def evalZ: Algebra[RingF, Int] = {\n  case RZero => 0\n  case ROne => 1\n  case RAdd(m, n) => m + n\n  case RMul(m, n) => m * n\n  case RNeg(n) => -n\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet05.scala",
    "content": "sealed trait Expr\ncase object RZero extends Expr\ncase object ROne extends Expr\ncase class RAdd(e1: Expr, e2: Expr) extends Expr\ncase class RMul(e1: Expr, e2: Expr) extends Expr\ncase class RNeg(e: Expr) extends Expr"
  },
  {
    "path": "src/content/3.8/code/scala/snippet06.scala",
    "content": "def evalZ: Expr => Int = {\n  case RZero => 0\n  case ROne => 1\n  case RAdd(e1, e2) => evalZ(e1) + evalZ(e2)\n  case RMul(e1, e2) => evalZ(e1) * evalZ(e2)\n  case RNeg(e) => -evalZ(e)\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet07.scala",
    "content": "type RingF1[A] = RingF[RingF[A]]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet08.scala",
    "content": "type RingF2[A] = RingF[RingF[RingF[A]]]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet09.scala",
    "content": "type RingF2[A] = RingF[RingF1[A]]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet10.scala",
    "content": "case class Fix[F[_]](x: F[Fix[F]])"
  },
  {
    "path": "src/content/3.8/code/scala/snippet11.scala",
    "content": "sealed trait Fix[F[_]]\ncase class In[F[_]](f: F[Fix[F]])"
  },
  {
    "path": "src/content/3.8/code/scala/snippet12.scala",
    "content": "object Fix {\n  def apply[F[_]](f: F[Fix[F]]): Fix[F] = new Fix(f)\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet13.scala",
    "content": "def unFix[F[_]]: Fix[F] => F[Fix[F]] = {\n  case Fix(x) => x\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet14.scala",
    "content": "sealed trait NatF[+A]\ncase object ZeroF extends NatF[Nothing]\ncase class SuccF[A](a: A) extends NatF[A]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet15.scala",
    "content": "sealed trait Nat\ncase object Zero extends Nat\ncase class Succ(n: Nat) extends Nat"
  },
  {
    "path": "src/content/3.8/code/scala/snippet16.scala",
    "content": "def cata[F[_], A](alg: F[A] => A)\n                 (implicit F: Functor[F]): Fix[F] => A =\n  alg.compose(F.fmap(cata(alg)) _ compose unFix)"
  },
  {
    "path": "src/content/3.8/code/scala/snippet17.scala",
    "content": "sealed trait NatF[+A]\ncase object ZeroF extends NatF[Nothing]\ncase class SuccF[A](a: A) extends NatF[A]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet18.scala",
    "content": "def fib: NatF[(Int, Int)] => (Int, Int) = {\n  case ZeroF => (1, 1)\n  case SuccF((m, n)) => (n, m + n)\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet19.scala",
    "content": "sealed trait ListF[+E, +A]\ncase object NilF extends ListF[Nothing, Nothing]\ncase class ConsF[E, A](h: E, t: A) extends ListF[E, A]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet20.scala",
    "content": "sealed trait List[+E]\ncase object Nil extends List[Nothing]\ncase class Cons[E](h: E, t: List[E]) extends List[E]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet21.scala",
    "content": "def lenAlg[E]: ListF[E, Int] => Int = {\n  case ConsF(e, n) => n + 1\n  case NilF => 0\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet22.scala",
    "content": "def length[E](l: List[E]): Int =\n  l.foldRight(0)((e, n) => n + 1)"
  },
  {
    "path": "src/content/3.8/code/scala/snippet23.scala",
    "content": "def sumAlg: ListF[Double, Double] => Double = {\n  case ConsF(e, s) => e + s\n  case NilF => 0.0\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet24.scala",
    "content": "def sum(l: List[Double]): Double =\n  l.foldRight(0.0)((e, s) => e + s)"
  },
  {
    "path": "src/content/3.8/code/scala/snippet25.scala",
    "content": "def ana[F[_], A](coalg: A => F[A])\n                (implicit F: Functor[F]): A => Fix[F] =\n  (Fix.apply[F] _).compose(F.fmap(ana(coalg)) _ compose coalg)"
  },
  {
    "path": "src/content/3.8/code/scala/snippet26.scala",
    "content": "case class StreamF[E, A](h: E, t: A)\n\nimplicit def streamFFunctor[E] = new Functor[StreamF[E, ?]] {\n  def fmap[A, B](f: A => B)(fa: StreamF[E, A]): StreamF[E, B] =\n    ...\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet27.scala",
    "content": "case class Stream[E](h: E, t: Stream[E])"
  },
  {
    "path": "src/content/3.8/code/scala/snippet28.scala",
    "content": "def era: List[Int] => StreamF[Int, List[Int]] = {\n  case p :: ns =>\n    def notdiv(p: Int)(n: Int): Boolean =\n      n % p != 0\n    StreamF(p, ns.filter(notdiv(p)))\n}\n"
  },
  {
    "path": "src/content/3.8/code/scala/snippet29.scala",
    "content": "// just imagine that the list is infinite\ndef primes =\n  ana(era)(streamFFunctor)((1 to 10).toList)"
  },
  {
    "path": "src/content/3.8/code/scala/snippet30.scala",
    "content": "def toListC[E]: Fix[StreamF[E, ?]] => List[E] = {\n  def al: StreamF[E, List[E]] => List[E] = {\n    case StreamF(e, a) => e :: a\n  }\n  cata[StreamF[E, ?], List[E]](al)\n}"
  },
  {
    "path": "src/content/3.8/code/scala/snippet31.scala",
    "content": "def unfoldr[A, B]: (B => Option[(A, B)]) => B => List[A]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet32.scala",
    "content": "def set[A, S]: A => S => A\ndef get[A, S]: A => S"
  },
  {
    "path": "src/content/3.8/code/scala/snippet33.scala",
    "content": "A => ((S, S => A))"
  },
  {
    "path": "src/content/3.8/code/scala/snippet34.scala",
    "content": "A => Store[S, A]"
  },
  {
    "path": "src/content/3.8/code/scala/snippet35.scala",
    "content": "case class Store[S, A](run: S => A, s: S)"
  },
  {
    "path": "src/content/3.8/f-algebras.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{W}{e've seen several formulations} of a monoid: as a set, as a\nsingle-object category, as an object in a monoidal category. How much\nmore juice can we squeeze out of this simple concept?\n\nLet's try. Take this definition of a monoid as a set $m$ with a\npair of functions:\n\\begin{align*}\n  \\mu  & \\Colon m\\times{}m \\to m \\\\\n  \\eta & \\Colon 1 \\to m\n\\end{align*}\nHere, 1 is the terminal object in $\\Set$ --- the singleton set.\nThe first function defines multiplication (it takes a pair of elements\nand returns their product), the second selects the unit element from\n$m$. Not every choice of two functions with these signatures\nresults in a monoid. For that we need to impose additional conditions:\nassociativity and unit laws. But let's forget about that for a moment\nand just consider ``potential monoids.'' A pair of functions is an\nelement of a Cartesian product of two sets of functions. We know that\nthese sets may be represented as exponential objects:\n\\begin{align*}\n  \\mu  & \\in m^{m\\times{}m} \\\\\n  \\eta & \\in m^1\n\\end{align*}\nThe Cartesian product of these two sets is:\n\\[m^{m\\times{}m}\\times{}m^1\\]\nUsing some high-school algebra (which works in every Cartesian closed\ncategory), we can rewrite it as:\n\\[m^{m\\times{}m + 1}\\]\nThe $+$ sign stands for the coproduct in $\\Set$. We have just\nreplaced a pair of functions with a single function --- an element of\nthe set:\n\\[m\\times{}m + 1 \\to m\\]\nAny element of this set of functions is a potential monoid.\n\nThe beauty of this formulation is that it leads to interesting\ngeneralizations. For instance, how would we describe a group using this\nlanguage? A group is a monoid with one additional function that assigns\nthe inverse to every element. The latter is a function of the type\n$m \\to m$. As an example, integers form a group with\naddition as a binary operation, zero as the unit, and negation as the\ninverse. To define a group we would start with a triple of functions:\n\\begin{align*}\n  m\\times{}m \\to m \\\\\n  m \\to m          \\\\\n  1 \\to m\n\\end{align*}\nAs before, we can combine all these triples into one set of functions:\n\\[m\\times{}m + m + 1 \\to m\\]\nWe started with one binary operator (addition), one unary operator\n(negation), and one nullary operator (identity --- here zero). We\ncombined them into one function. All functions with this signature\ndefine potential groups.\n\nWe can go on like this. For instance, to define a ring, we would add one\nmore binary operator and one nullary operator, and so on. Each time we\nend up with a function type whose left-hand side is a sum of powers\n(possibly including the zeroth power --- the terminal object), and the\nright-hand side being the set itself.\n\nNow we can go crazy with generalizations. First of all, we can replace\nsets with objects and functions with morphisms. We can define n-ary\noperators as morphisms from n-ary products. It means that we need a\ncategory that supports finite products. For nullary operators we require\nthe existence of the terminal object. So we need a Cartesian category.\nIn order to combine these operators we need exponentials, so that's a\nCartesian closed category. Finally, we need coproducts to complete our\nalgebraic shenanigans.\n\nAlternatively, we can just forget about the way we derived our formulas\nand concentrate on the final product. The sum of products on the left\nhand side of our morphism defines an endofunctor. What if we pick an\narbitrary endofunctor $F$ instead? In that case we don't have to\nimpose any constraints on our category. What we obtain is called an\n$F$-algebra.\n\nAn $F$-algebra is a triple consisting of an endofunctor $F$, an\nobject $a$, and a morphism\n\\[F a \\to a\\]\nThe object is often called the carrier, an underlying object or, in the\ncontext of programming, the carrier \\emph{type}. The morphism is often\ncalled the evaluation function or the structure map. Think of the\nfunctor $F$ as forming expressions and the morphism as evaluating\nthem.\n\nHere's the Haskell definition of an $F$-algebra:\n\n\\src{snippet01}\nIt identifies the algebra with its evaluation function.\n\nIn the monoid example, the functor in question is:\n\n\\src{snippet02}\nThis is Haskell for $1 + a\\times{}a$ (remember\n\\hyperref[simple-algebraic-data-types]{algebraic\n  data structures}).\n\nA ring would be defined using the following functor:\n\n\\src{snippet03}\nwhich is Haskell for $1 + 1 + a\\times{}a + a\\times{}a + a$.\n\nAn example of a ring is the set of integers. We can choose\n\\code{Integer} as the carrier type and define the evaluation function\nas:\n\n\\src{snippet04}\nThere are more $F$-algebras based on the same functor \\code{RingF}. For\ninstance, polynomials form a ring and so do square matrices.\n\nAs you can see, the role of the functor is to generate expressions that\ncan be evaluated using the evaluator of the algebra. So far we've only\nseen very simple expressions. We are often interested in more elaborate\nexpressions that can be defined using recursion.\n\n\\section{Recursion}\n\nOne way to generate arbitrary expression trees is to replace the\nvariable \\code{a} inside the functor definition with recursion. For\ninstance, an arbitrary expression in a ring is generated by this\ntree-like data structure:\n\n\\src{snippet05}\nWe can replace the original ring evaluator with its recursive version:\n\n\\src{snippet06}\nThis is still not very practical, since we are forced to represent all\nintegers as sums of ones, but it will do in a pinch.\n\nBut how can we describe expression trees using the language of\n$F$-algebras? We have to somehow formalize the process of replacing the\nfree type variable in the definition of our functor, recursively, with\nthe result of the replacement. Imagine doing this in steps. First,\ndefine a depth-one tree as:\n\n\\src{snippet07}\nWe are filling the holes in the definition of \\code{RingF} with\ndepth-zero trees generated by \\code{RingF a}. Depth-2 trees are\nsimilarly obtained as:\n\n\\src{snippet08}\nwhich we can also write as:\n\n\\src{snippet09}\nContinuing this process, we can write a symbolic equation:\n\n\\begin{snipv}\ntype RingF\\textsubscript{n+1} a = RingF (RingF\\textsubscript{n} a)\n\\end{snipv}\nConceptually, after repeating this process infinitely many times, we end\nup with our \\code{Expr}. Notice that \\code{Expr} does not depend on\n\\code{a}. The starting point of our journey doesn't matter, we always\nend up in the same place. This is not always true for an arbitrary\nendofunctor in an arbitrary category, but in the category $\\Set$\nthings are nice.\n\nOf course, this is a hand-waving argument, and I'll make it more\nrigorous later.\n\nApplying an endofunctor infinitely many times produces a \\newterm{fixed\n  point}, an object defined as:\n\\[\\mathit{Fix}\\ f = f\\ (\\mathit{Fix}\\ f)\\]\nThe intuition behind this definition is that, since we applied\n$f$ infinitely many times to get $\\mathit{Fix}\\ f$, applying it one\nmore time doesn't change anything. In Haskell, the definition of a fixed\npoint is:\n\n\\src{snippet10}\nArguably, this would be more readable if the constructor's name were\ndifferent than the name of the type being defined, as in:\n\n\\src{snippet11}\nbut I'll stick with the accepted notation. The constructor \\code{Fix}\n(or \\code{In}, if you prefer) can be seen as a function:\n\n\\src{snippet12}\nThere is also a function that peels off one level of functor\napplication:\n\n\\src{snippet13}\nThe two functions are the inverse of each other. We'll use these\nfunctions later.\n\n\\section{Category of $F$-Algebras}\n\nHere's the oldest trick in the book: Whenever you come up with a way of\nconstructing some new objects, see if they form a category. Not\nsurprisingly, algebras over a given endofunctor $F$ form a\ncategory. Objects in that category are algebras --- pairs consisting of\na carrier object $a$ and a morphism\n$F a \\to a$, both from the original category\n$\\cat{C}$.\n\nTo complete the picture, we have to define morphisms in the category of\n$F$-algebras. A morphism must map one algebra $(a, f)$ to another\nalgebra $(b, g)$. We'll define it as a morphism $m$ that\nmaps the carriers --- it goes from $a$ to $b$ in the\noriginal category. Not any morphism will do: we want it to be compatible\nwith the two evaluators. (We call such a structure-preserving morphism a\n\\newterm{homomorphism}.) Here's how you define a homomorphism of\n$F$-algebras. First, notice that we can lift $m$ to the mapping:\n\\[F m \\Colon F a \\to F b\\]\nwe can then follow it with $g$ to get to $b$.\nEquivalently, we can use $f$ to go from $F a$ to\n$a$ and then follow it with $m$. We want the two paths to\nbe equal:\n\\[g \\circ F m = m \\circ f\\]\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/alg.png}\n\\end{figure}\n\n\\noindent\nIt's easy to convince yourself that this is indeed a category (hint:\nidentity morphisms from $\\cat{C}$ work just fine, and a composition of\nhomomorphisms is a homomorphism).\n\nAn initial object in the category of $F$-algebras, if it exists, is called\nthe \\newterm{initial algebra}. Let's call the carrier of this initial\nalgebra $i$ and its evaluator $j \\Colon F i \\to i$. It turns out that $j$,\nthe evaluator of the initial algebra, is an isomorphism. This result is\nknown as Lambek's theorem. The proof relies on the definition of the\ninitial object, which requires that there be a unique homomorphism\n$m$ from it to any other $F$-algebra. Since $m$ is a\nhomomorphism, the following diagram must commute:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/alg2.png}\n\\end{figure}\n\n\\noindent\nNow let's construct an algebra whose carrier is $F i$. The\nevaluator of such an algebra must be a morphism from $F (F i)$\nto $F i$. We can easily construct such an evaluator simply by\nlifting $j$:\n\\[F j \\Colon F (F i) \\to F i\\]\nBecause $(i, j)$ is the initial algebra, there must be a unique\nhomomorphism $m$ from it to $(F i, F j)$. The following\ndiagram must commute:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/alg3a.png}\n\\end{figure}\n\n\\noindent\nBut we also have this trivially commuting diagram (both paths are the\nsame!):\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.3\\textwidth]{images/alg3.png}\n\\end{figure}\n\n\\noindent\nwhich can be interpreted as showing that $j$ is a homomorphism of\nalgebras, mapping $(F i, F j)$ to $(i, j)$. We can\nglue these two diagrams together to get:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.6\\textwidth]{images/alg4.png}\n\\end{figure}\n\n\\noindent\nThis diagram may, in turn, be interpreted as showing that\n$j \\circ m$ is a homomorphism of algebras. Only in this case the\ntwo algebras are the same. Moreover, because $(i, j)$ is\ninitial, there can only be one homomorphism from it to itself, and\nthat's the identity morphism $\\id_i$ --- which we know is a\nhomomorphism of algebras. Therefore $j \\circ m = \\id_i$. Using this\nfact and the commuting property of the left diagram we can prove that\n$m \\circ j = \\id_{Fi}$. This shows that $m$ is the inverse of\n$j$ and therefore $j$ is an isomorphism between\n$F i$ and $i$:\n\\[F i \\cong i\\]\nBut that is just saying that $i$ is a fixed point of $F$.\nThat's the formal proof behind the original hand-waving argument.\n\nBack to Haskell: We recognize $i$ as our \\code{Fix f},\n$j$ as our constructor \\code{Fix}, and its inverse as\n\\code{unFix}. The isomorphism in Lambek's theorem tells us that, in\norder to get the initial algebra, we take the functor $f$ and\nreplace its argument $a$ with \\code{Fix f}. We also see why\nthe fixed point does not depend on $a$.\n\n\\section{Natural Numbers}\n\nNatural numbers can also be defined as an $F$-algebra. The starting point\nis the pair of morphisms:\n\\begin{align*}\n  zero & \\Colon 1 \\to N \\\\\n  succ & \\Colon N \\to N\n\\end{align*}\nThe first one picks the zero, and the second one maps all numbers to\ntheir successors. As before, we can combine the two into one:\n\\[1 + N \\to N\\]\nThe left hand side defines a functor which, in Haskell, can be written\nlike this:\n\n\\src{snippet14}\nThe fixed point of this functor (the initial algebra that it generates)\ncan be encoded in Haskell as:\n\n\\src{snippet15}\nA natural number is either zero or a successor of another number. This\nis known as the Peano representation for natural numbers.\n\n\\section{Catamorphisms}\n\nLet's rewrite the initiality condition using Haskell notation. We call\nthe initial algebra \\code{Fix f}. Its evaluator is the constructor\n\\code{Fix}. There is a unique morphism \\code{m} from the initial\nalgebra to any other algebra over the same functor. Let's pick an\nalgebra whose carrier is \\code{a} and the evaluator is \\code{alg}.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/alg5.png}\n\\end{figure}\n\n\\noindent\nBy the way, notice what \\code{m} is: It's an evaluator for the fixed\npoint, an evaluator for the whole recursive expression tree. Let's find\na general way of implementing it.\n\nLambek's theorem tells us that the constructor \\code{Fix} is an\nisomorphism. We called its inverse \\code{unFix}. We can therefore flip\none arrow in this diagram to get:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/alg6.png}\n\\end{figure}\n\n\\noindent\nLet's write down the commutation condition for this diagram:\n\n\\begin{snip}{haskell}\nm = alg . fmap m . unFix\n\\end{snip}\nWe can interpret this equation as a recursive definition of \\code{m}.\nThe recursion is bound to terminate for any finite tree created using\nthe functor \\code{f}. We can see that by noticing that\n\\code{fmap m} operates underneath the top layer of the functor\n\\code{f}. In other words, it works on the children of the original\ntree. The children are always one level shallower than the original\ntree.\n\nHere's what happens when we apply \\code{m} to a tree constructed using\n\\code{Fix\\ f}. The action of \\code{unFix} peels off the constructor,\nexposing the top level of the tree. We then apply \\code{m} to all the\nchildren of the top node. This produces results of type \\code{a}.\nFinally, we combine those results by applying the non-recursive\nevaluator \\code{alg}. The key point is that our evaluator \\code{alg}\nis a simple non-recursive function.\n\nSince we can do this for any algebra \\code{alg}, it makes sense to\ndefine a higher order function that takes the algebra as a parameter and\ngives us the function we called \\code{m}. This higher order function\nis called a catamorphism:\n\n\\src{snippet16}\nLet's see an example of that. Take the functor that defines natural\nnumbers:\n\n\\src{snippet17}\nLet's pick \\code{(Int, Int)} as the carrier type and define our\nalgebra as:\n\n\\src{snippet18}\nYou can easily convince yourself that the catamorphism for this algebra,\n\\code{cata fib}, calculates Fibonacci numbers.\n\nIn general, an algebra for \\code{NatF} defines a recurrence relation:\nthe value of the current element in terms of the previous element. A\ncatamorphism then evaluates the n-th element of that sequence.\n\n\\section{Folds}\n\nA list of \\code{e} is the initial algebra of the following functor:\n\n\\src{snippet19}\nIndeed, replacing the variable \\code{a} with the result of recursion,\nwhich we'll call \\code{List e}, we get:\n\n\\src{snippet20}\nAn algebra for a list functor picks a particular carrier type and\ndefines a function that does pattern matching on the two constructors.\nIts value for \\code{NilF} tells us how to evaluate an empty list, and\nits value for \\code{ConsF} tells us how to combine the current element\nwith the previously accumulated value.\n\nFor instance, here's an algebra that can be used to calculate the length\nof a list (the carrier type is \\code{Int}):\n\n\\src{snippet21}\nIndeed, the resulting catamorphism \\code{cata lenAlg} calculates the\nlength of a list. Notice that the evaluator is a combination of (1) a\nfunction that takes a list element and an accumulator and returns a new\naccumulator, and (2) a starting value, here zero. The type of the value\nand the type of the accumulator are given by the carrier type.\n\nCompare this to the traditional Haskell definition:\n\n\\src{snippet22}\nThe two arguments to \\code{foldr} are exactly the two components of\nthe algebra.\n\nLet's try another example:\n\n\\src{snippet23}\nAgain, compare this with:\n\n\\src{snippet24}\nAs you can see, \\code{foldr} is just a convenient specialization of a\ncatamorphism to lists.\n\n\\section{Coalgebras}\n\nAs usual, we have a dual construction of an F-coalgebra, where the\ndirection of the morphism is reversed:\n\\[a \\to F a\\]\nCoalgebras for a given functor also form a category, with homomorphisms\npreserving the coalgebraic structure. The terminal object\n$(t, u)$ in that category is called the terminal (or final)\ncoalgebra. For every other algebra $(a, f)$ there is a unique\nhomomorphism $m$ that makes the following diagram commute:\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.4\\textwidth]{images/alg7.png}\n\\end{figure}\n\n\\noindent\nA terminal coalgebra is a fixed point of the functor, in the sense that\nthe morphism $u \\Colon t \\to F t$ is an isomorphism\n(Lambek's theorem for coalgebras):\n\\[F t \\cong t\\]\nA terminal coalgebra is usually interpreted in programming as a recipe\nfor generating (possibly infinite) data structures or transition\nsystems.\n\nJust like a catamorphism can be used to evaluate an initial algebra, an\nanamorphism can be used to coevaluate a terminal coalgebra:\n\n\\src{snippet25}\nA canonical example of a coalgebra is based on a functor whose fixed\npoint is an infinite stream of elements of type \\code{e}. This is the\nfunctor:\n\n\\src{snippet26}\nand this is its fixed point:\n\n\\src{snippet27}\nA coalgebra for \\code{StreamF e} is a function that takes the seed of\ntype \\code{a} and produces a pair (\\code{StreamF} is a fancy name\nfor a pair) consisting of an element and the next seed.\n\nYou can easily generate simple examples of coalgebras that produce\ninfinite sequences, like the list of squares, or reciprocals.\n\nA more interesting example is a coalgebra that produces a list of\nprimes. The trick is to use an infinite list as a carrier. Our starting\nseed will be the list \\code{{[}2..{]}}. The next seed will be the tail\nof this list with all multiples of 2 removed. It's a list of odd numbers\nstarting with 3. In the next step, we'll take the tail of this list and\nremove all multiples of 3, and so on. You might recognize the makings of\nthe sieve of Eratosthenes. This coalgebra is implemented by the\nfollowing function:\n\n\\src{snippet28}\nThe anamorphism for this coalgebra generates the list of primes:\n\n\\src{snippet29}\nA stream is an infinite list, so it should be possible to convert it to\na Haskell list. To do that, we can use the same functor \\code{StreamF}\nto form an algebra, and we can run a catamorphism over it. For instance,\nthis is a catamorphism that converts a stream to a list:\n\n\\src{snippet30}\nHere, the same fixed point is simultaneously an initial algebra and a\nterminal coalgebra for the same endofunctor. It's not always like this,\nin an arbitrary category. In general, an endofunctor may have many (or\nno) fixed points. The initial algebra is the so called least fixed\npoint, and the terminal coalgebra is the greatest fixed point. In\nHaskell, though, both are defined by the same formula, and they\ncoincide.\n\nThe anamorphism for lists is called unfold. To create finite lists, the\nfunctor is modified to produce a \\code{Maybe} pair:\n\n\\src{snippet31}\nThe value of \\code{Nothing} will terminate the generation of the list.\n\nAn interesting case of a coalgebra is related to lenses. A lens can be\nrepresented as a pair of a getter and a setter:\n\n\\src{snippet32}\nHere, \\code{a} is usually some product data type with a field of type\n\\code{s}. The getter retrieves the value of that field and the setter\nreplaces this field with a new value. These two functions can be\ncombined into one:\n\n\\src{snippet33}\nWe can rewrite this function further as:\n\n\\src{snippet34}\nwhere we have defined a functor:\n\n\\src{snippet35}\nNotice that this is not a simple algebraic functor constructed from sums\nof products. It involves an exponential $a^s$.\n\nA lens is a coalgebra for this functor with the carrier type \\code{a}.\nWe've seen before that \\code{Store s} is also a comonad. It turns out\nthat a very well behaved lens corresponds to a coalgebra that is compatible\nwith the comonad structure. We'll talk about this in the next section.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        Implement the evaluation function for a ring of polynomials of one\n        variable. You can represent a polynomial as a list of coefficients in\n        front of powers of $x$. For instance, $4x^2-1$ would be\n        represented as (starting with the zero'th power)\n        \\code{{[}-1, 0, 4{]}}.\n  \\item\n        Generalize the previous construction to polynomials of many\n        independent variables, like $x^2y-3y^3z$.\n  \\item\n        Implement the algebra for the ring of $2\\times{}2$ matrices.\n  \\item\n        Define a coalgebra whose anamorphism produces a list of squares of\n        natural numbers.\n  \\item\n        Use \\code{unfoldr} to generate a list of the first $n$ primes.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.9/algebras-for-monads.tex",
    "content": "% !TEX root = ../../ctfp-print.tex\n\n\\lettrine[lhang=0.17]{I}{f we interpret} endofunctors as ways of defining expressions, algebras\nlet us evaluate them and monads let us form and manipulate them. By\ncombining algebras with monads we not only gain a lot of functionality\nbut we can also answer a few interesting questions.\n\nOne such question concerns the relation between monads and adjunctions.\nAs we've seen, every adjunction \\hyperref[monads-categorically]{defines\n  a monad} (and a comonad). The question is: Can every monad (comonad) be\nderived from an adjunction? The answer is positive. There is a whole\nfamily of adjunctions that generate a given monad. I'll show you two\nsuch adjunctions.\n\n\\begin{figure}[H]\n  \\centering\n  \\includegraphics[width=0.25\\textwidth]{images/pigalg.png}\n\\end{figure}\n\n\\noindent\nLet's review the definitions. A monad is an endofunctor $m$\nequipped with two natural transformations that satisfy some coherence\nconditions. The components of these transformations at $a$ are:\n\\begin{align*}\n  \\eta_a & \\Colon a \\to m\\ a         \\\\\n  \\mu_a  & \\Colon m\\ (m\\ a) \\to m\\ a\n\\end{align*}\nAn algebra for the same endofunctor is a selection of a particular\nobject --- the carrier $a$ --- together with the morphism:\n\\[\\mathit{alg} \\Colon m\\ a \\to a\\]\nThe first thing to notice is that the algebra goes in the opposite\ndirection to $\\eta_a$. The intuition is that $\\eta_a$ creates a\ntrivial expression from a value of type $a$. The first coherence\ncondition that makes the algebra compatible with the monad ensures that\nevaluating this expression using the algebra whose carrier is $a$\ngives us back the original value:\n\\[\\mathit{alg} \\circ \\eta_a = \\id_a\\]\nThe second condition arises from the fact that there are two ways of\nevaluating the doubly nested expression $m\\ (m\\ a)$. We can first\napply $\\mu_a$ to flatten the expression, and then use the evaluator\nof the algebra; or we can apply the lifted evaluator to evaluate the\ninner expressions, and then apply the evaluator to the result. We'd like\nthe two strategies to be equivalent:\n\\[\\mathit{alg} \\circ \\mu_a = \\mathit{alg} \\circ m\\ \\mathit{alg}\\]\nHere, $m\\ \\mathit{alg}$ is the morphism resulting from lifting\n$\\mathit{alg}$ using the functor $m$. The following commuting\ndiagrams describe the two conditions (I replaced $m$ with\n$T$ in anticipation of what follows):\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      a \\arrow[rd, equal] \\arrow[r, \"\\eta_a\"]\n      & Ta \\arrow[d, \"\\mathit{alg}\"] \\\\\n      & a\n    \\end{tikzcd}\n  \\end{subfigure}\n  \\hspace{1cm}\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      T(Ta) \\arrow[r, \"T\\ \\mathit{alg}\"] \\arrow[d, \"\\mu_a\"]\n      & Ta \\arrow[d, \"\\mathit{alg}\"] \\\\\n      Ta \\arrow[r, \"\\mathit{alg}\"]\n      & a\n    \\end{tikzcd}\n  \\end{subfigure}\n\\end{figure}\n\n\\noindent\nWe can also express these conditions in Haskell:\n\n\\src{snippet01}\nLet's look at a small example. An algebra for a list endofunctor\nconsists of some type \\code{a} and a function that produces an\n\\code{a} from a list of \\code{a}.\nSuppose that we can express this function using\n\\code{foldr} by choosing both the element type and the accumulator\ntype to be equal to \\code{a}:\n\n\\src{snippet02}\nThis particular algebra is specified by a two-argument function, let's\ncall it \\code{f}, and a value \\code{z}. The list functor happens to\nalso be a monad, with \\code{return} turning a value into a singleton\nlist. The composition of the algebra, here \\code{foldr f z}, after\n\\code{return} takes \\code{x} to:\n\n\\src{snippet03}\nwhere the action of \\code{f} is written in the infix notation. The\nalgebra is compatible with the monad if the following coherence\ncondition is satisfied for every \\code{x}:\n\n\\src{snippet04}\nIf we look at \\code{f} as a binary operator, this condition tells us\nthat \\code{z} is the right unit.\n\nThe second coherence condition operates on a list of lists. The action\nof \\code{join} concatenates the individual lists. We can then fold the\nresulting list. On the other hand, we can first fold the individual\nlists, and then fold the resulting list. Again, if we interpret\n\\code{f} as a binary operator, this condition tells us that this\nbinary operation is associative. These conditions are certainly\nfulfilled when \\code{(a, f, z)} is a monoid.\n\n\\section{$T$-algebras}\n\nSince mathematicians prefer to call their monads $T$, they call\nalgebras compatible with them $T$-algebras. $T$-algebras for a given monad $T$\nin a category $\\cat{C}$ form a category called the Eilenberg-Moore\ncategory, often denoted by $\\cat{C}^T$. Morphisms in that\ncategory are homomorphisms of algebras. These are the same homomorphisms\nwe've seen defined for $F$-algebras.\n\nA $T$-algebra is a pair consisting of a carrier object and an evaluator,\n$(a, f)$. There is an obvious forgetful functor $U^T$ from\n$\\cat{C}^T$ to $\\cat{C}$, which maps $(a, f)$ to $a$. It\nalso maps a homomorphism of $T$-algebras to a corresponding morphism\nbetween carrier objects in $\\cat{C}$. You may remember from our discussion of\nadjunctions that the left adjoint to a forgetful functor is called a\nfree functor.\n\nThe left adjoint to $U^T$ is called $F^T$. It maps an object\n$a$ in $\\cat{C}$ to a free algebra in $\\cat{C}^T$. The carrier\nof this free algebra is $T a$. Its evaluator is a morphism from\n$T (T a)$ back to $T a$. Since $T$ is a monad,\nwe can use the monadic $\\mu_a$ (\\code{join} in Haskell) as the\nevaluator.\n\nWe still have to show that this is a $T$-algebra. For that, two coherence\nconditions must be satisfied:\n\\begin{align*}\n  \\mathit{alg} & \\circ \\eta_{Ta} = \\id_{Ta}     \\\\\n  \\mathit{alg} & \\circ \\mu_a = \\mathit{alg} \\circ T\\ \\mathit{alg}\n\\end{align*}\nBut these are just monadic laws, if you plug in $\\mu$ for the\nalgebra.\n\nAs you may recall, every adjunction defines a monad. It turns out that\nthe adjunction between $F^T$ and $U^T$\ndefines the very monad $T$ that was used in the construction of\nthe Eilenberg-Moore category. Since we can perform this construction for\nevery monad, we conclude that every monad can be generated from an\nadjunction. Later I'll show you that there is another adjunction that\ngenerates the same monad.\n\nHere's the plan: First I'll show you that $F^T$ is indeed the left\nadjoint of $U^T$. I'll do it by defining the unit and the counit\nof this adjunction and proving that the corresponding triangular\nidentities are satisfied. Then I'll show you that the monad generated by\nthis adjunction is indeed our original monad.\n\nThe unit of the adjunction is the natural transformation:\n\\[\\eta \\Colon I \\to U^T \\circ F^T\\]\nLet's calculate the $a$ component of this transformation. The\nidentity functor gives us $a$. The free functor produces the free\nalgebra $(T a, \\mu_a)$, and the forgetful functor reduces it to\n$T a$. Altogether we get a mapping from $a$ to\n$T a$. We'll simply use the unit of the monad $T$ as the\nunit of this adjunction.\n\nLet's look at the counit:\n\\[\\varepsilon \\Colon F^T \\circ U^T \\to I\\]\nLet's calculate its component at some $T$-algebra $(a, f)$. The\nforgetful functor forgets the $f$, and the free functor produces\nthe pair $(T a, \\mu_a)$. So in order to define the component of\nthe counit $\\varepsilon$ at $(a, f)$, we need the right morphism in\nthe Eilenberg-Moore category, or a homomorphism of $T$-algebras:\n\\[(T a, \\mu_a) \\to (a, f)\\]\nSuch a homomorphism should map the carrier $T a$ to $a$.\nLet's just resurrect the forgotten evaluator $f$. This time we'll\nuse it as a homomorphism of $T$-algebras. Indeed, the same commuting\ndiagram that makes $f$ a $T$-algebra may be re-interpreted to show\nthat it's a homomorphism of $T$-algebras:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{tikzcd}[column sep=large, row sep=large]\n    T(Ta) \\arrow[r, \"T f\"] \\arrow[d, \"\\mu_a\"]\n    & Ta \\arrow[d, \"f\"] \\\\\n    Ta \\arrow[r, \"f\"]\n    & a\n  \\end{tikzcd}\n\\end{figure}\n\n\\noindent\nWe have thus defined the component of the counit natural transformation\n$\\varepsilon$ at $(a, f)$ (an object in the category of $T$-algebras)\nto be $f$.\n\nTo complete the adjunction we also need to show that the unit and the\ncounit satisfy triangular identities. These are:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      Ta \\arrow[rd, equal] \\arrow[r, \"T \\eta_a\"]\n      & T(Ta) \\arrow[d, \"\\mu_a\"] \\\\\n      & Ta\n    \\end{tikzcd}\n  \\end{subfigure}%\n  \\hspace{1cm}\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      a \\arrow[rd, equal] \\arrow[r, \"\\eta_a\"]\n      & Ta \\arrow[d, \"f\"] \\\\\n      & a\n    \\end{tikzcd}\n  \\end{subfigure}\n\\end{figure}\n\n\\noindent\nThe first one holds because of the unit law for the monad $T$.\nThe second is just the law of the $T$-algebra $(a, f)$.\n\nWe have established that the two functors form an adjunction:\n\\[F^T \\dashv U^T\\]\nEvery adjunction gives rise to a monad. The round trip\n\\[U^T \\circ F^T\\]\nis the endofunctor in $\\cat{C}$ that gives rise to the corresponding monad.\nLet's see what its action on an object $a$ is. The free algebra\ncreated by $F^T$ is $(T a, \\mu_a)$. The forgetful functor\n$U^T$ drops the evaluator. So, indeed, we have:\n\\[U^T \\circ F^T = T\\]\nAs expected, the unit of the adjunction is the unit of the monad $T$.\n\nYou may remember that the counit of the adjunction produces monadic\nmultiplication through the following formula:\n\\[\\mu = R \\circ \\varepsilon \\circ L\\]\nThis is a horizontal composition of three natural transformations, two\nof them being identity natural transformations mapping, respectively,\n$L$ to $L$ and $R$ to $R$. The one in the\nmiddle, the counit, is a natural transformation whose component at an\nalgebra $(a, f)$ is $f$.\n\nLet's calculate the component $\\mu_a$. We first horizontally compose\n$\\varepsilon$ after $F^T$, which results in the component of\n$\\varepsilon$ at $F^T a$. Since $F^T$ takes $a$ to the\nalgebra $(T a, \\mu_a)$, and $\\varepsilon$ picks the evaluator, we end\nup with $\\mu_a$. Horizontal composition on the left with $U^T$\ndoesn't change anything, since the action of $U^T$ on morphisms is\ntrivial. So, indeed, the $\\mu$ obtained from the adjunction is the\nsame as the $\\mu$ of the original monad $T$.\n\n\\section{The Kleisli Category}\n\nWe've seen the Kleisli category before. It's a category constructed from\nanother category $\\cat{C}$ and a monad $T$. We'll call this\ncategory $\\cat{C}_T$. The objects in the Kleisli category\n$\\cat{C}_T$ are the objects of $\\cat{C}$, but the morphisms\nare different. A morphism $f_{\\cat{K}}$ from $a$ to $b$ in\nthe Kleisli category corresponds to a morphism $f$ from\n$a$ to $T b$ in the original category. We call this\nmorphism a Kleisli arrow from $a$ to $b$.\n\nComposition of morphisms in the Kleisli category is defined in terms of\nmonadic composition of Kleisli arrows. For instance, let's compose\n$g_{\\cat{K}}$ after $f_{\\cat{K}}$. In the Kleisli category we have:\n\\begin{gather*}\n  f_{\\cat{K}} \\Colon a \\to b \\\\\n  g_{\\cat{K}} \\Colon b \\to c\n\\end{gather*}\nwhich, in the category $\\cat{C}$, corresponds to:\n\\begin{gather*}\n  f \\Colon a \\to T b \\\\\n  g \\Colon b \\to T c\n\\end{gather*}\nWe define the composition:\n\\[h_{\\cat{K}} = g_{\\cat{K}} \\circ f_{\\cat{K}}\\]\nas a Kleisli arrow in $\\cat{C}$\n\\begin{align*}\n  h & \\Colon a \\to T c          \\\\\n  h & = \\mu \\circ (T g) \\circ f\n\\end{align*}\nIn Haskell we would write it as:\n\n\\src{snippet05}\nThere is a functor $F$ from $\\cat{C}$ to $\\cat{C}_T$\nwhich acts trivially on objects. On morphisms, it maps $f$ in\n$\\cat{C}$ to a morphism in $\\cat{C}_T$ by creating a\nKleisli arrow that embellishes the return value of $f$. Given a\nmorphism:\n\\[f \\Colon a \\to b\\]\nit creates a morphism in $\\cat{C}_T$ with the\ncorresponding Kleisli arrow:\n\\[\\eta \\circ f\\]\nIn Haskell we'd write it as:\n\n\\src{snippet06}\nWe can also define a functor $G$ from $\\cat{C}_T$\nback to $\\cat{C}$. It takes an object $a$ from the Kleisli\ncategory and maps it to an object $T a$ in $\\cat{C}$. Its action\non a morphism $f_{\\cat{K}}$ corresponding to a Kleisli arrow:\n\\[f \\Colon a \\to T b\\]\nis a morphism in $\\cat{C}$:\n\\[T a \\to T b\\]\ngiven by first lifting $f$ and then applying $\\mu$:\n\\[\\mu_{T b} \\circ T f\\]\nIn Haskell notation this would read:\n\n\\begin{snipv}\nG f\\textsubscript{T} = join . fmap f\n\\end{snipv}\nYou may recognize this as the definition of monadic bind in terms of\n\\code{join}.\n\nIt's easy to see that the two functors form an adjunction:\n\\[F \\dashv G\\]\nand their composition $G \\circ F$ reproduces the original monad $T$.\n\nSo this is the second adjunction that produces the same monad. In fact\nthere is a whole category of adjunctions $\\cat{Adj}(\\cat{C}, T)$ that result\nin the same monad $T$ on $\\cat{C}$. The Kleisli adjunction we've\njust seen is the initial object in this category, and the\nEilenberg-Moore adjunction is the terminal object.\n\n\\section{Coalgebras for Comonads}\n\nAnalogous constructions can be done for any\n\\hyperref[comonads]{comonad}\n$W$. We can define a category of coalgebras that are compatible\nwith a comonad. They make the following diagrams commute:\n\n\\begin{figure}[H]\n  \\centering\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      a \\arrow[rd, equal]\n      & Wa \\arrow[l, \"\\varepsilon_a\"'] \\\\\n      & a \\arrow[u, \"\\mathit{coa}\"']\n    \\end{tikzcd}\n  \\end{subfigure}%\n  \\hspace{1cm}\n  \\begin{subfigure}\n    \\centering\n    \\begin{tikzcd}[column sep=large, row sep=large]\n      W(Wa)\n      & Wa \\arrow[l, \"W\\ \\mathit{coa}\"'] \\\\\n      Wa \\arrow[u, \"\\delta_a\"]\n      & a \\arrow[u, \"\\mathit{coa}\"] \\arrow[l, \"\\mathit{coa}\"']\n    \\end{tikzcd}\n  \\end{subfigure}\n\\end{figure}\n\n\\noindent\nwhere $\\mathit{coa}$ is the coevaluation morphism of the coalgebra whose\ncarrier is $a$:\n\\[\\mathit{coa} \\Colon a \\to W a\\]\nand $\\varepsilon$ and $\\delta$ are the two natural transformations\ndefining the comonad (in Haskell, their components are called\n\\code{extract} and \\code{duplicate}).\n\nThere is an obvious forgetful functor $U^W$ from the category of\nthese coalgebras to $\\cat{C}$. It just forgets the coevaluation. We'll\nconsider its right adjoint $F^W$.\n\\[U^W \\dashv F^W\\]\nThe right adjoint to a forgetful functor is called a cofree functor.\n$F^W$ generates cofree coalgebras. It assigns, to an object\n$a$ in $\\cat{C}$, the coalgebra $(W a, \\delta_a)$. The\nadjunction reproduces the original comonad as the composite\n$U^W \\circ F^W$.\n\nSimilarly, we can construct a co-Kleisli category with co-Kleisli arrows\nand regenerate the comonad from the corresponding adjunction.\n\n\\section{Lenses}\n\nLet's go back to our discussion of lenses. A lens can be written as a\ncoalgebra:\n\\[\\mathit{coalg}_s \\Colon a \\to \\mathit{Store}\\ s\\ a\\]\nfor the functor $\\mathit{Store}\\ s$:\n\n\\src{snippet07}\nThis coalgebra can be also expressed as a pair of functions:\n\\begin{align*}\n  \\mathit{set} & \\Colon a \\to s \\to a \\\\\n  \\mathit{get} & \\Colon a \\to s\n\\end{align*}\n(Think of $a$ as standing for ``all,'' and $s$ as a\n``small'' part of it.) In terms of this pair, we have:\n\\[\\mathit{coalg}_s\\ a = \\mathit{Store}\\ (\\mathit{set}\\ a)\\ (\\mathit{get}\\ a)\\]\nHere, $a$ is a value of type $a$. Notice that partially\napplied \\code{set} is a function $s \\to a$.\n\nWe also know that $\\mathit{Store}\\ s$ is a comonad:\n\n\\src{snippet08}\nThe question is: Under what conditions is a lens a coalgebra for this\ncomonad? The first coherence condition:\n\\[\\varepsilon_a \\circ \\mathit{coalg} = \\idarrow[a]\\]\ntranslates to:\n\n\\src{snippet16}\nThis is the lens law that expresses the fact that if you set a field of\nthe structure $a$ to its previous value, nothing changes.\nThis law is also known as GETPUT.\n\nThe second condition:\n\\[\\mathit{fmap}\\ \\mathit{coalg} \\circ \\mathit{coalg} = \\delta_a \\circ \\mathit{coalg}\\]\nrequires a little more work. First, recall the definition of\n\\code{fmap} for the \\code{Store} functor:\n\n\\src{snippet09}\nApplying \\code{fmap coalg} to the result of \\code{coalg} gives us:\n\n\\src{snippet10}\nOn the other hand, applying \\code{duplicate} to the result of\n\\code{coalg} produces:\n\n\\src{snippet11}\nFor these two expressions to be equal, the two functions under\n\\code{Store} must be equal when acting on an arbitrary \\code{s}:\n\n\\src{snippet12}\nExpanding \\code{coalg}, we get:\n\n\\src{snippet13}\nThis is equivalent to two remaining lens laws. The first one:\n\n\\src{snippet14}\ntells us that setting the value of a field twice is the same as setting\nit once. This law is also known as PUTPUT. The second law:\n\n\\src{snippet15}\ntells us that getting a value of a field that was set to $s$\ngives $s$ back. This law is also known as PUTGET.\n\nA lens that satisfies GETPUT and PUTGET is called a well-behaved lens.\nIf the lens also satisfies PUTPUT, it is called a very well behaved lens.\nSo, in other words, a very well behaved lens is indeed a comonad coalgebra for\nthe \\code{Store} functor.\n\n\\section{Challenges}\n\n\\begin{enumerate}\n  \\tightlist\n  \\item\n        What is the action of the free functor\n        $F^T \\Colon C \\to C^T$ on morphisms. Hint: use the\n        naturality condition for monadic $\\mu$.\n  \\item\n        Define the adjunction:\n        \\[U^W \\dashv F^W\\]\n  \\item\n        Prove that the above adjunction reproduces the original comonad.\n\\end{enumerate}\n"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet01.hs",
    "content": "alg . return = id\nalg . join = alg . fmap alg"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet02.hs",
    "content": "foldr :: (a -> a -> a) -> a -> [a] -> a"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet03.hs",
    "content": "foldr f z [x] = x `f` z"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet04.hs",
    "content": "x `f` z = x"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet05.hs",
    "content": "h = join . fmap g . f"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet06.hs",
    "content": "return . f"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet07.hs",
    "content": "data Store s a = Store (s -> a) s"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet08.hs",
    "content": "instance Comonad (Store s) where\n    extract (Store f s) = f s\n    duplicate (Store f s) = Store (Store f) s"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet09.hs",
    "content": "fmap g (Store f s) = Store (g . f) s"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet10.hs",
    "content": "Store (coalg . set a) (get a)"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet11.hs",
    "content": "Store (Store (set a)) (get a)"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet12.hs",
    "content": "coalg (set a s) = Store (set a) s"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet13.hs",
    "content": "Store (set (set a s)) (get (set a s)) = Store (set a) s"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet14.hs",
    "content": "set (set a s) = set a"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet15.hs",
    "content": "get (set a s) = s"
  },
  {
    "path": "src/content/3.9/code/haskell/snippet16.hs",
    "content": "set a (get a) = a\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet01.ml",
    "content": ";;\ncompose alg return = id compose alg join = compose alg (fmap alg)\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet02.ml",
    "content": "val fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet03.ml",
    "content": "(* List module in the OCaml standard library accepts list before z *)\n\n;;\nList.fold_right f [ x ] z = f x z\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet04.ml",
    "content": ";;\nf x z = x\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet05.ml",
    "content": "module Kleisli_Composition (T : MonadJoin) = struct\n  let h g f = T.join <.> T.fmap g <.> f\nend\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet06.ml",
    "content": "module C_to_CT (T : Monad) = struct\n  let on_objects = T.return <.> f\nend\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet07.ml",
    "content": "type ('s, 'a) store = Store of ('s -> 'a) * 's\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet08.ml",
    "content": "module Store_comonad (S : sig\n  type s\nend)\n(F : Functor with type 'a t = (S.s, 'a) store) :\n  Comonad with type 'a w = (S.s, 'a) store = struct\n  type 'a w = (S.s, 'a) store\n\n  include F\n\n  let extract : 'a w -> 'a = fun (Store (f, s)) -> f s\n\n  let duplicate : 'a w -> 'a w w =\n   fun (Store (f, s)) -> Store ((fun s -> Store (f, s)), s)\n ;;\nend\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet09.ml",
    "content": "module Store_Functor (S : sig\n  type s\nend) : Functor with type 'a t = (S.s, 'a) store = struct\n  type 'a w = (S.s, 'a) store\n  type 'a t = 'a w\n\n  let fmap g (Store (f, s)) = Store (compose g f, s)\nend\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet10.ml",
    "content": "(* Assume <.> acts as compose *)\n\n;;\nStore (coalg_store <.> set a, get a)\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet11.ml",
    "content": ";;\nStore ((fun s -> Store (set a, s)), get a)\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet12.ml",
    "content": "(* Pseudo OCaml *)\nlet coalg_store (set a s) = Store ((set a), s)\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet13.ml",
    "content": "(* Expaning coalg_store *)\n\n;;\nStore (set (set a s), get (set a s)) = Store (set a, s)\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet14.ml",
    "content": ";;\nset (set a s) = set a\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet15.ml",
    "content": ";;\nget (set a s) = s\n"
  },
  {
    "path": "src/content/3.9/code/ocaml/snippet16.ml",
    "content": ";;\nset a (get a) = a\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet01.re",
    "content": "compose(alg, return) == id(compose, alg, join) == compose(alg, fmap(alg));\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet02.re",
    "content": "let fold_right: (('a, 'b) => 'b, list('a), 'b) => 'b;\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet03.re",
    "content": "/* List module in the OCaml standard library accepts list before z */\nList.fold_right(f, [x], z) == f(x, z);\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet04.re",
    "content": "f(x, z) == x;\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet05.re",
    "content": "module Kleisli_Composition = (T: MonadJoin) => {\n  let h = (g, f) => T.join <.> T.fmap(g) <.> f;\n};\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet06.re",
    "content": "module C_to_CT = (T: Monad) => {\n  let on_objects = T.return <.> f;\n};\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet07.re",
    "content": "type store('s, 'a) =\n  | Store('s => 'a, 's);\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet08.re",
    "content": "module Store_comonad =\n       (S: {type s;}, F: Functor with type t('a) = store(S.s, 'a))\n       : (Comonad with type w('a) = store(S.s, 'a)) => {\n  type w('a) = store(S.s, 'a);\n\n  include F;\n\n  let extract: w('a) => 'a = ((Store(f, s)) => f(s): w('a) => 'a);\n\n  let duplicate: w('a) => w(w('a)) = (\n    (Store(f, s)) => Store(s => Store(f, s), s): w('a) => w(w('a))\n  );\n};\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet09.re",
    "content": "module Store_Functor = (S: {type s;}) : \n       (Functor with type t('a) = store(S.s, 'a)) => {\n  type w('a) = store(S.s, 'a);\n  type t('a) = w('a);\n\n  let fmap = (g, Store(f, s)) => Store(compose(g, f), s);\n};\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet10.re",
    "content": "/* Assume <.> acts as compose */\n\nStore(coalg_store <.> set(a), get(a));\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet11.re",
    "content": "Store(s => Store(set(a), s), get(a));\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet12.re",
    "content": "/* Pseudo ReasonML */\nlet coalg_store = (set, a, s) => Store((set(a)), s)\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet13.re",
    "content": "/* Expaning coalg_store */\n\nStore(set(set(a, s)), get(set(a, s))) == Store(set(a), s);\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet14.re",
    "content": "set(set(a, s)) == set(a);\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet15.re",
    "content": "get(set(a, s)) == s;\n"
  },
  {
    "path": "src/content/3.9/code/reason/snippet16.re",
    "content": "set(a, get(a))) == a;\n"
  },
  {
    "path": "src/content/3.9/code/scala/snippet01.scala",
    "content": "alg compose pure == id\nalg compose flatten == alg compose fmap(alg)"
  },
  {
    "path": "src/content/3.9/code/scala/snippet02.scala",
    "content": "def foldr[A]: (A => A => A) => A => List[A] => A"
  },
  {
    "path": "src/content/3.9/code/scala/snippet03.scala",
    "content": "def foldr[A]: (A => A => A) => A => List[A] => A =\n  f => z => {\n    case x :: Nil => f(x)(z)\n  }"
  },
  {
    "path": "src/content/3.9/code/scala/snippet04.scala",
    "content": "f(x)(z) == x"
  },
  {
    "path": "src/content/3.9/code/scala/snippet05.scala",
    "content": "h == flatten.compose(fmap(g) _ compose f)"
  },
  {
    "path": "src/content/3.9/code/scala/snippet06.scala",
    "content": "unit compose f"
  },
  {
    "path": "src/content/3.9/code/scala/snippet07.scala",
    "content": "case class Store[S, A](run: S => A, s: S)\n\n// convenient partially applied constructor\nobject Store {\n  def apply[S, A](run: S => A): S => Store[S, A] =\n    s => new Store(run, s)\n}"
  },
  {
    "path": "src/content/3.9/code/scala/snippet08.scala",
    "content": "implicit def storeComonad[S] = new Comonad[Store[S, ?]] {\n  def extract[A](wa: Store[S, A]): A = wa match {\n    case Store(f, s) => f(s)\n  }\n  \n  def duplicate[A](wa: Store[S, A]): Store[S, Store[S, A]] = wa match {\n    case Store(f, s) => Store(Store(f), s)\n  }\n}"
  },
  {
    "path": "src/content/3.9/code/scala/snippet09.scala",
    "content": "implicit def storeFunctor[S] = new Functor[Store[S, ?]] {\n  def fmap[A, B](g: A => B)(fa: Store[S, A]): Store[S, B] = fa match {\n    case Store(f, s) =>\n      Store(g compose f, s)\n  }\n}"
  },
  {
    "path": "src/content/3.9/code/scala/snippet10.scala",
    "content": "Store(coalg compose set(a), get(a))"
  },
  {
    "path": "src/content/3.9/code/scala/snippet11.scala",
    "content": "Store(Store(set(a)), get(a))"
  },
  {
    "path": "src/content/3.9/code/scala/snippet12.scala",
    "content": "coalg(set(a)(s)) == Store(set(a))(s)"
  },
  {
    "path": "src/content/3.9/code/scala/snippet13.scala",
    "content": "Store(set(set(a)(s)))(get(set(a)(s))) == Store(set(a))(s)"
  },
  {
    "path": "src/content/3.9/code/scala/snippet14.scala",
    "content": "set(set(a)(s)) == set(a)"
  },
  {
    "path": "src/content/3.9/code/scala/snippet15.scala",
    "content": "get(set(a)(s)) == s"
  },
  {
    "path": "src/content/3.9/code/scala/snippet16.scala",
    "content": "set(a)(get(a)) == a\n"
  },
  {
    "path": "src/content/editor-note.tex",
    "content": "% !TEX root = ../ctfp-print.tex\n\n\\ifdefined\\OPTCustomLanguage{%\n    \\chapter*{A note from the editor}\n    \\addcontentsline{toc}{chapter}{A note from the editor}\n    \\input{content/\\OPTCustomLanguage/editor-note}\n  }\n\\fi"
  },
  {
    "path": "src/content/ocaml/colophon.tex",
    "content": "OCaml code translation was done by \\urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{Arulselvan Madhavan}\nand reviewed by \\urlref{http://www.mseri.me}{Marcello Seri} and \\urlref{https://github.com/XVilka}{Anton Kochkov}."
  },
  {
    "path": "src/content/ocaml/editor-note.tex",
    "content": "% !TEX root = ctfp-print.tex\n\n\\lettrine[lhang=0.17]{T}{his is the} OCaml edition of \\emph{Category Theory for Programmers}.\nIt's been a tremendous success, making Bartosz Milewski's blog post series available as a nicely-\ntypeset \\acronym{PDF}, as well as a hardcover book. There have been numerous contributions made\nto improve the book, by fixing typos and errors, as well as translating the code snippets into\nother programming languages.\n\nI am thrilled to present this edition of the book, containing the original Haskell code, followed by\nits OCaml counterpart. The OCaml code snippets were generously provided by\n\\urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{ocaml-ctfp} contributors, slightly\nmodified to suit the format of this book.\n\nTo support code snippets in multiple languages, I am using a \\LaTeX{} macro to load the code snippets\nfrom external files. This allows easily extending the book with other languages, while leaving the\noriginal text intact. Which is why you should mentally append the words ``and OCaml'' whenever you see\n``in Haskell'' in the text.\n\nThe code is laid out in the following manner: the original Haskell code, followed by OCaml code.\nTo distinguish between them, the code snippets are braced from the left with a vertical bar, in the primary\ncolor of the language's logo, \\raisebox{-.2mm}{\\includegraphics[height=.3cm]{fig/icons/haskell.png}},\nand \\raisebox{-.2mm}{\\includegraphics[height=.3cm]{fig/icons/ocaml.png}} respectively, e.g.:\n\n\\srcsnippet{content/1.1/code/haskell/snippet03.hs}{blue}{haskell}\n\\unskip\n\\srcsnippet{content/1.1/code/ocaml/snippet03.ml}{orange}{ocaml}\n\\NoIndentAfterThis"
  },
  {
    "path": "src/content/reason/colophon.tex",
    "content": "ReasonML code translation was done by \\urlref{https://github.com/fhammerschmidt/}{Florian Hammerschmidt}."
  },
  {
    "path": "src/content/reason/editor-note.tex",
    "content": "% !TEX root = ctfp-print.tex\n\n\\lettrine[lhang=0.17]{T}{his is the} ReasonML edition of \\emph{Category Theory for Programmers}.\nIt's been a tremendous success, making Bartosz Milewski's blog post series available as a nicely-\ntypeset \\acronym{PDF}, as well as a hardcover book. There have been numerous contributions made\nto improve the book, by fixing typos and errors, as well as translating the code snippets into\nother programming languages.\n\nI am thrilled to present this edition of the book, containing the original Haskell code, followed by\nits ReasonML counterpart. The ReasonML code snippets were converted from the OCaml snippets which were\ngenerously provided by \\urlref{https://github.com/ArulselvanMadhavan/ocaml-ctfp}{ocaml-ctfp} contributors,\nand slightly modified to suit the format of this book.\n\nTo support code snippets in multiple languages, I am using a \\LaTeX{} macro to load the code snippets\nfrom external files. This allows easily extending the book with other languages, while leaving the\noriginal text intact. Which is why you should mentally append the words ``and ReasonML'' whenever you see\n``in Haskell'' in the text.\n\nThe code is laid out in the following manner: the original Haskell code, followed by ReasonML code.\nTo distinguish between them, the code snippets are braced from the left with a vertical bar, in the primary\ncolor of the language's logo, \\raisebox{-.2mm}{\\includegraphics[height=.3cm]{fig/icons/haskell.png}},\nand \\raisebox{-.2mm}{\\includegraphics[height=.3cm]{fig/icons/reason.png}} respectively, e.g.:\n\n\\srcsnippet{content/1.1/code/haskell/snippet03.hs}{blue}{haskell}\n\\unskip\n\\srcsnippet{content/1.1/code/reason/snippet03.re}{RedOrange}{reason}\n\\NoIndentAfterThis"
  },
  {
    "path": "src/content/scala/colophon.tex",
    "content": "Scala code translation was done by \\urlref{https://github.com/typelevel/CT_from_Programmers.scala}{Typelevel} contributors."
  },
  {
    "path": "src/content/scala/editor-note.tex",
    "content": "% !TEX root = ctfp-print.tex\n\n\\lettrine[lhang=0.17]{T}{his is the Scala edition} of \\emph{Category Theory for Programmers}.\nIt's been a tremendous success, making Bartosz Milewski's blog post series available as a nicely\ntypeset \\acronym{PDF}, as well as a hardcover book. There have been numerous contributions made\nto improve the book, by fixing typos and errors, as well as translating the code snippets into\nother programming languages.\n\nI am thrilled to present this edition of the book, containing the original Haskell code, followed by\nits Scala counterpart. The Scala code snippets were generously provided by\n\\urlref{https://github.com/typelevel/CT_from_Programmers.scala}{Typelevel} contributors, slightly\nmodified to suit the format of this book.\n\nTo support code snippets in multiple languages, I am using a \\LaTeX{} macro to load the code snippets\nfrom external files. This allows easily extending the book with other languages, while leaving the\noriginal text intact. Which is why you should mentally append the words ``and Scala'' whenever you see\n``in Haskell'' in the text.\n\nThe code is laid out in the following manner: the original Haskell code, followed by Scala code.\nTo distinguish between them, the code snippets are braced from the left with a vertical bar, in the primary\ncolor of the language's logo, \\raisebox{-.2mm}{\\includegraphics[height=.3cm]{fig/icons/haskell.png}},\nand \\raisebox{-.2mm}{\\includegraphics[height=.3cm]{fig/icons/scala.png}} respectively, e.g.:\n\n\\srcsnippet{content/3.6/code/haskell/snippet03.hs}{blue}{haskell}\n\\unskip\n\\srcsnippet{content/3.6/code/scala/snippet03.scala}{red}{scala}\n\\NoIndentAfterThis\nIn addition, some Scala snippets make use of the\n\\urlref{https://github.com/non/kind-projector}{Kind Projector} compiler plugin, to support nicer syntax for partially-applied types."
  },
  {
    "path": "src/cover/blurb.tex",
    "content": "% !TEX root = cover-blurb.tex\n% Blurb on back cover\n\n{\n\\fontsize{14}{17}\\selectfont\n\\scshape{Category Theory}\\normalfont\\sffamily{}\nis one of the most abstract branches of mathematics. It is usually taught to\ngraduate students after they have mastered several other branches of mathematics,\nlike algebra, topology, and group theory. It might, therefore, come as a shock that\nthe basic concepts of category theory can be explained in relatively simple terms\nto anybody with some experience in programming. \\\\\n\nThat's because, just like programming,\ncategory theory is about structure. Mathematicians discover structure in mathematical\ntheories, programmers discover structure in computer programs. Well-structured programs\nare easier to understand and maintain and are less likely to contain bugs. Category theory\nprovides the language to talk about structure and learning it will make you\na better programmer.\n\\vfil\n\n}\n"
  },
  {
    "path": "src/cover/cover-hardcover-ocaml.tex",
    "content": "\\documentclass[\n    coverheight=9.249in,\n    coverwidth=6.319in, % (pagesize - spinewidth) / 2\n    spinewidth=1.125in,\n    bleedwidth=0.306in,\n    11pt,\n    marklength=0pt,\n  ]{bookcover}\n\n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{fontspec}\n  \\usepackage{Alegreya}\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n\n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n\n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\input{ribbon-ocaml}\n    \\vspace{1.1cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.8\\coverwidth}\n          \\input{blurb}\n          \\vspace{.5cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\bartosz\n             &\n            \\vspace{5pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/cover-hardcover-reason.tex",
    "content": "\\documentclass[\n    coverheight=9.249in,\n    coverwidth=6.319in, % (pagesize - spinewidth) / 2\n    spinewidth=1.125in,\n    bleedwidth=0.306in,\n    11pt,\n    marklength=0pt,\n  ]{bookcover}\n\n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{fontspec}\n  \\usepackage{Alegreya}\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n\n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n\n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\input{ribbon-reason}\n    \\vspace{1.1cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.8\\coverwidth}\n          \\input{blurb}\n          \\vspace{.5cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\bartosz\n             &\n            \\vspace{5pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/cover-hardcover-scala.tex",
    "content": "\\documentclass[\n    coverheight=9.249in,\n    coverwidth=6.319in, % (pagesize - spinewidth) / 2\n    spinewidth=1.125in,\n    bleedwidth=0.306in,\n    11pt,\n    marklength=0pt,\n  ]{bookcover}\n\n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{fontspec}\n  \\usepackage{Alegreya}\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n\n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n\n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\input{ribbon-scala}\n    \\vspace{1.1cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.8\\coverwidth}\n          \\input{blurb}\n          \\vspace{.5cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\bartosz\n             &\n            \\vspace{5pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/cover-hardcover.tex",
    "content": "\\documentclass[\n    coverheight=9.249in,\n    coverwidth=6.319in, % (pagesize - spinewidth) / 2\n    spinewidth=1.069in,\n    bleedwidth=0in,\n    11pt,\n    marklength=0pt,\n  ]{bookcover}\n  \n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{Alegreya} %% Option 'black' gives heavier bold face \n  \n  \\setmainfont{Alegreya Sans}[\n    UprightFeatures={SmallCapsFont=* SC},\n    ItalicFeatures={SmallCapsFont=* SC Italic},\n    BoldFeatures={SmallCapsFont=* SC Bold},\n    BoldItalicFeatures={SmallCapsFont=* SC Bold Italic},\n  ]\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n  \n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n  \n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\vspace{2cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.8\\coverwidth}\n          \\input{blurb}\n          \\vspace{.5cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\bartosz\n             &\n            \\vspace{5pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/cover-paperback-ocaml.tex",
    "content": "\\documentclass[\n    % bleed is added to the final result\n    coverheight=9.25in,\n    coverwidth=6.125in, % (pagesize - spinewidth) / 2 == (13.042 - 1.042) / 2\n    spinewidth=1.042in,\n    bleedwidth=0in,\n    11pt,\n    marklength=0in,\n  ]{bookcover}\n\n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{fontspec}\n  \\usepackage{Alegreya}\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n\n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n\n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\input{ribbon-ocaml}\n    \\vspace{1.1cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.75\\coverwidth}\n          \\input{blurb}\n          \\vspace{0.6cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\vspace{5pt}\n            \\bartosz\n             &\n            \\vspace{10pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/cover-paperback-reason.tex",
    "content": "\\documentclass[\n    % bleed is added to the final result\n    coverheight=9.25in,\n    coverwidth=6.125in, % (pagesize - spinewidth) / 2 == (13.042 - 1.042) / 2\n    spinewidth=1.042in,\n    bleedwidth=0in,\n    11pt,\n    marklength=0in,\n  ]{bookcover}\n\n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{fontspec}\n  \\usepackage{Alegreya}\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n\n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n\n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\input{ribbon-reason}\n    \\vspace{1.1cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.75\\coverwidth}\n          \\input{blurb}\n          \\vspace{0.6cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\vspace{5pt}\n            \\bartosz\n             &\n            \\vspace{10pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/cover-paperback-scala.tex",
    "content": "\\documentclass[\n    % bleed is added to the final result\n    coverheight=9.25in,\n    coverwidth=6.125in, % (pagesize - spinewidth) / 2 == (13.042 - 1.042) / 2\n    spinewidth=1.042in,\n    bleedwidth=0in,\n    11pt,\n    marklength=0in,\n  ]{bookcover}\n\n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{fontspec}\n  \\usepackage{Alegreya}\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n\n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n\n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\input{ribbon-scala}\n    \\vspace{1.1cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.75\\coverwidth}\n          \\input{blurb}\n          \\vspace{0.6cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\vspace{5pt}\n            \\bartosz\n             &\n            \\vspace{10pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/cover-paperback.tex",
    "content": "\\documentclass[\n    coverheight=9.25in,\n    coverwidth=6.125in, % (pagesize - spinewidth) / 2\n    spinewidth=1.125in,\n    bleedwidth=0in,\n    11pt,\n    marklength=0pt,\n  ]{bookcover}\n\n  \\usepackage{fancybox}\n  \\usepackage{wrapfig}\n  \\usepackage[many]{tcolorbox}\n  \\usetikzlibrary{calc,positioning, shadings}\n  \\usepackage[T1]{fontenc}\n  \\usepackage{Alegreya} %% Option 'black' gives heavier bold face\n\n  \\setmainfont{Alegreya Sans}[\n    UprightFeatures={SmallCapsFont=* SC},\n    ItalicFeatures={SmallCapsFont=* SC Italic},\n    BoldFeatures={SmallCapsFont=* SC Bold},\n    BoldItalicFeatures={SmallCapsFont=* SC Bold Italic},\n  ]\n\n  \\newcommand{\\olpath}{../}\n  \\newcommand{\\whitebg}[1]{%\n  \\tikz\\node[circle,draw,minimum size=1.1cm,\n  fill=white,\n  path picture={\n      \\node at (path picture bounding box){\n          \\includegraphics[width=1.1cm]{\\olpath#1}\n      };\n  }]{};\n  }\n  \\newcommand{\\bartosz}{\n    \\vspace{0pt}\n    \\begin{tcolorbox}[beamer,\n      width=3.6cm,\n      arc=0pt,\n      boxsep=0pt,\n      left=0pt,right=0pt,top=0pt,bottom=0pt,\n      ] \\includegraphics[width=3.6cm]{bartosz}\n    \\end{tcolorbox}\n  }\n  \\input{\\olpath/version}\n\n  \\definecolor{BackgroundColor}{HTML}{f3f6ed}\n  \\definecolor{SpineBackColor}{HTML}{262626}\n\n\\begin{document}\n\n\\begin{bookcover}\n  \\bookcovercomponent{color}{bg whole}{color=BackgroundColor}\n  \\bookcovercomponent{color}{spine}{color=SpineBackColor}\n  \\bookcovercomponent{normal}{front}{\n    \\vspace{2cm}\n    \\begin{center}\n      \\fontsize{40pt}{5em}\\selectfont\\bfseries\n      CATEGORY THEORY \\\\FOR PROGRAMMERS\n      \\vfil\n      \\hspace*{-.8cm}\\includegraphics[width=.5\\coverwidth]{piggie}\n      \\linebreak\n      \\rule[1.5cm]{\\textwidth/2}{.5pt}\\\\\n      \\vspace{-1.5cm}\n      \\normalfont\\Huge\\textbf{Bartosz Milewski}\n      \\vfil\n      \\vspace*{1cm}\n    \\end{center}}\n\n  \\bookcovercomponent{center}{spine}{\n    \\rotatebox[origin=c]{-90}{\\color{orange}\n      \\Huge\\bfseries Category Theory for Programmers \\hspace{2em} Bartosz Milewski}}\n\n  \\bookcovercomponent{normal}{back}{%\n    \\begin{minipage}[b][\\coverheight][t]{\\coverwidth}\n      \\begin{center}\n        \\vspace{1cm}\n        \\includegraphics[width=.8\\coverwidth]{bunnies}\n        \\begin{minipage}[t]{.8\\coverwidth}\n          \\input{blurb}\n          \\vspace{.5cm}\n        \\end{minipage}\n\n        \\begin{minipage}{.85\\textwidth}\n          \\rule{\\textwidth}{.5pt}\n\n          \\begin{tabular}[h]{p{3.4cm} p{\\textwidth}}\n            \\bartosz\n             &\n            \\vspace{5pt}\n            \\begin{minipage}[b]{.58\\coverwidth}\n              \\fontsize{11pt}{1.4em}\\selectfont\\textit{Category Theory for Programmers}\n              is a series of blog posts by Bartosz Milewski, originally posted on bartoszmilewski.com.\\\\\n              Edited by Igal Tabachnik. Licenced under CC BY-SA 4.0.\\\\\n            \\end{minipage}\n          \\end{tabular}\n          \\begin{flushright}\n            \\vspace{-2.6cm}\n            \\begin{minipage}[b]{4cm}\n              \\raggedleft\n              \\whitebg{fig/icons/by}\n              \\whitebg{fig/icons/cc}\n              \\whitebg{fig/icons/sa}\n              \\centering\\footnotesize{\\texttt{\\OPTversion}}\n            \\end{minipage}\n          \\end{flushright}\n        \\end{minipage}\n      \\end{center}\n    \\end{minipage}\n  }\n\\end{bookcover}\n\\end{document}"
  },
  {
    "path": "src/cover/ribbon-ocaml.tex",
    "content": "% !TeX root = ./cover-paperback-ocaml.tex\n\n\\newcommand{\\stripskip}{4}\n\\newcommand{\\stripwidth}{3}\n\n\\definecolor{BurntOrange}{rgb}{0.8, 0.33, 0.0}\n\n\\begin{tikzpicture}[\n    overlay,\n    remember picture,\n    ribbon/.style={anchor=center, rotate = 45,\n        font={\\fontsize{22}{1}\\selectfont\\bfseries}}\n  ]\n  \\coordinate (A) at ($ (current page.south east) + (-\\stripskip,0) $);% <-- changed coordinate from 'north' to south'\n  \\coordinate (A') at ($(A) + (-\\stripwidth,0) $);\n\n  \\coordinate (B) at ($ (current page.south east) + (0,\\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \\stripskip\n  \\coordinate (B') at ($(B) + (0,\\stripwidth) $);% <-- changed sign for \\stripskip \n\n  \\fill [BurntOrange!20] (A) -- (A') -- (B') -- (B) -- cycle;\n\n  \\coordinate (tempA) at ($(A)!.5!(A')$);\n  \\coordinate (tempB) at ($(B)!.5!(B')$);\n\n  \\node [ribbon](text) at ($(tempA)!.5!(tempB)$) {\n    \\raisebox{-.15\\height}{\\includegraphics[width=.8cm]{\\olpath/fig/icons/ocaml}}\n    \\hspace{.5mm} OCaml Edition\n  };\n\n\\end{tikzpicture}"
  },
  {
    "path": "src/cover/ribbon-reason.tex",
    "content": "% !TeX root = ./cover-paperback-reason.tex\n\n\\newcommand{\\stripskip}{4}\n\\newcommand{\\stripwidth}{3}\n\n\\definecolor{RedOrange}{rgb}{0.86, 0.30, 0.25}\n\n\\begin{tikzpicture}[\n    overlay,\n    remember picture,\n    ribbon/.style={anchor=center, rotate = 45,\n        font={\\fontsize{22}{1}\\selectfont\\bfseries}}\n  ]\n  \\coordinate (A) at ($ (current page.south east) + (-\\stripskip,0) $);% <-- changed coordinate from 'north' to south'\n  \\coordinate (A') at ($(A) + (-\\stripwidth,0) $);\n\n  \\coordinate (B) at ($ (current page.south east) + (0,\\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \\stripskip\n  \\coordinate (B') at ($(B) + (0,\\stripwidth) $);% <-- changed sign for \\stripskip \n\n  \\fill [RedOrange!20] (A) -- (A') -- (B') -- (B) -- cycle;\n\n  \\coordinate (tempA) at ($(A)!.5!(A')$);\n  \\coordinate (tempB) at ($(B)!.5!(B')$);\n\n  \\node [ribbon](text) at ($(tempA)!.5!(tempB)$) {\n    \\raisebox{-.15\\height}{\\includegraphics[width=.8cm]{\\olpath/fig/icons/reason}}\n    \\hspace{.5mm} ReasonML Edition\n  };\n\n\\end{tikzpicture}"
  },
  {
    "path": "src/cover/ribbon-scala.tex",
    "content": "\\newcommand{\\stripskip}{4}\n\\newcommand{\\stripwidth}{3}\n\n\\begin{tikzpicture}[\n    overlay,\n    remember picture,\n    ribbon/.style={anchor=center, rotate = 45,\n        font={\\fontsize{22}{1}\\selectfont\\bfseries}}\n  ]\n  \\coordinate (A) at ($ (current page.south east) + (-\\stripskip,0) $);% <-- changed coordinate from 'north' to south'\n  \\coordinate (A') at ($(A) + (-\\stripwidth,0) $);\n\n  \\coordinate (B) at ($ (current page.south east) + (0,\\stripskip) $);% <-- changed coordinate from 'north' to south' and sign for \\stripskip\n  \\coordinate (B') at ($(B) + (0,\\stripwidth) $);% <-- changed sign for \\stripskip \n\n  \\fill [red!20] (A) -- (A') -- (B') -- (B) -- cycle;\n\n  \\coordinate (tempA) at ($(A)!.5!(A')$);\n  \\coordinate (tempB) at ($(B)!.5!(B')$);\n\n  \\node [ribbon](text) at ($(tempA)!.5!(tempB)$) {\n    \\raisebox{-.30\\height}{\\includegraphics[width=.8cm]{\\olpath/fig/icons/scala}}\n    \\hspace{.5mm} Scala Edition\n  };\n\n\\end{tikzpicture}"
  },
  {
    "path": "src/ctfp-print-ocaml.tex",
    "content": "\\input{opt-ocaml}\n\\input{ctfp-print}\n\\input{postamble}"
  },
  {
    "path": "src/ctfp-print-reason.tex",
    "content": "\\input{opt-reason}\n\\input{ctfp-print}\n\\input{postamble}"
  },
  {
    "path": "src/ctfp-print-scala.tex",
    "content": "\\input{opt-scala}\n\\input{ctfp-print}\n\\input{postamble}"
  },
  {
    "path": "src/ctfp-print.tex",
    "content": "% This is a main LaTeX file for generating the CTFP book\n% for printing in US-trade format, suitable for binding.\n% The links are black in this version.\n\n\\input{opt-print-ustrade}\n\n\\input{preamble}\n\n\\hypersetup{hidelinks}\n\n\\input{ctfp}\n\n\\input{postamble}"
  },
  {
    "path": "src/ctfp-reader-ocaml.tex",
    "content": "\\input{opt-ocaml}\n\\input{ctfp-reader}\n\\input{postamble}"
  },
  {
    "path": "src/ctfp-reader-reason.tex",
    "content": "\\input{opt-reason}\n\\input{ctfp-reader}\n\\input{postamble}"
  },
  {
    "path": "src/ctfp-reader-scala.tex",
    "content": "\\input{opt-scala}\n\\input{ctfp-reader}\n\\input{postamble}"
  },
  {
    "path": "src/ctfp-reader.tex",
    "content": "% This is a main LaTeX file for generating the CTFP book\n% for printing in US-trade format, suitable for binding.\n% The links are black in this version.\n\n\\input{opt-reader-10in}\n\n\\input{preamble}\n\n\\input{ctfp}\n\n\\input{postamble}"
  },
  {
    "path": "src/ctfp.tex",
    "content": "% !TEX root = ctfp-print.tex\n\n\\input{half-title}\n\n\\frontmatter\n\\tableofcontents\n\n\\input{content/editor-note}\n\\chapter*{Preface}\n\\addcontentsline{toc}{chapter}{Preface}\n\\label{Preface}\n\\subfile{content/0.0/Preface}\n\n\\mainmatter\n\n\\part*{Part One}\n\\addcontentsline{toc}{part}{Part One}\n\n\\chapter{Category: The Essence of Composition}\\label{category-the-essence-of-composition}\n\\subfile{content/1.1/category-the-essence-of-composition}\n\n\\chapter{Types and Functions}\\label{types-and-functions}\n\\subfile{content/1.2/types-and-functions}\n\n\\chapter{Categories Great and Small}\\label{categories-great-and-small}\n\\subfile{content/1.3/categories-great-and-small}\n\n\\chapter{Kleisli Categories}\\label{kleisli-categories}\n\\subfile{content/1.4/kleisli-categories}\n\n\\chapter{Products and Coproducts}\\label{products-and-coproducts}\n\\subfile{content/1.5/products-and-coproducts}\n\n\\chapter{Simple Algebraic Data Types}\\label{simple-algebraic-data-types}\n\\subfile{content/1.6/simple-algebraic-data-types}\n\n\\chapter{Functors}\\label{functors}\n\\subfile{content/1.7/functors}\n\n\\chapter{Functoriality}\\label{functoriality}\n\\subfile{content/1.8/functoriality}\n\n\\chapter{Function Types}\\label{function-types}\n\\subfile{content/1.9/function-types}\n\n\\chapter{Natural Transformations}\\label{natural-transformations}\n\\subfile{content/1.10/natural-transformations}\n\n\\part*{Part Two}\n\\addcontentsline{toc}{part}{Part Two}\n\n\\chapter{Declarative Programming}\\label{declarative-programming}\n\\subfile{content/2.1/declarative-programming}\n\n\\chapter{Limits and Colimits}\\label{limits-and-colimits}\n\\subfile{content/2.2/limits-and-colimits}\n\n\\chapter{Free Monoids}\\label{free-monoids}\n\\subfile{content/2.3/free-monoids}\n\n\\chapter{Representable Functors}\\label{representable-functors}\n\\subfile{content/2.4/representable-functors}\n\n\\chapter{The Yoneda Lemma}\\label{the-yoneda-lemma}\n\\subfile{content/2.5/the-yoneda-lemma}\n\n\\chapter{Yoneda Embedding}\\label{yoneda-embedding}\n\\subfile{content/2.6/yoneda-embedding}\n\n\\part*{Part Three}\n\\addcontentsline{toc}{part}{Part Three}\n\n\\chapter{It's All About Morphisms}\\label{all-about-morphisms}\n\\subfile{content/3.1/its-all-about-morphisms}\n\n\\chapter{Adjunctions}\\label{adjunctions}\n\\subfile{content/3.2/adjunctions}\n\n\\chapter{Free/Forgetful Adjunctions}\\label{free-forgetful-adjunctions}\n\\subfile{content/3.3/free-forgetful-adjunctions}\n\n\\chapter{Monads: Programmer's Definition}\\label{monads-programmers-definition}\n\\subfile{content/3.4/monads-programmers-definition}\n\n\\chapter{Monads and Effects}\\label{monads-and-effects}\n\\subfile{content/3.5/monads-and-effects}\n\n\\chapter{Monads Categorically}\\label{monads-categorically}\n\\subfile{content/3.6/monads-categorically}\n\n\\chapter{Comonads}\\label{comonads}\n\\subfile{content/3.7/comonads}\n\n\\chapter{$F$-Algebras}\\label{f-algebras}\n\\subfile{content/3.8/f-algebras}\n\n\\chapter{Algebras for Monads}\\label{algebras-for-monads}\n\\subfile{content/3.9/algebras-for-monads}\n\n\\chapter{Ends and Coends}\\label{ends-and-coends}\n\\subfile{content/3.10/ends-and-coends}\n\n\\chapter{Kan Extensions}\\label{kan-extensions}\n\\subfile{content/3.11/kan-extensions}\n\n\\chapter{Enriched Categories}\\label{enriched-categories}\n\\subfile{content/3.12/enriched-categories}\n\n\\chapter{Topoi}\\label{topoi}\n\\subfile{content/3.13/topoi}\n\n\\chapter{Lawvere Theories}\\label{lawvere-theories}\n\\subfile{content/3.14/lawvere-theories}\n\n\\chapter{Monads, Monoids, and Categories}\\label{monads-monoids-categories}\n\\subfile{content/3.15/monads-monoids-and-categories}\n\n\\backmatter\n\n\\appendix\n\\addcontentsline{toc}{part}{Appendices}\n\\input{index}\n\n\\makeatletter\\@openrightfalse\n\\chapter*{Acknowledgments}\\label{acknowledgments}\n\\addcontentsline{toc}{chapter}{Acknowledgments}\n\\input{acknowledgments}\n\n\\chapter*{Colophon}\\label{colophon}\n\\addcontentsline{toc}{chapter}{Colophon}\n\\input{colophon}\n\n\\chapter*{Copyleft notice}\\label{copyleft}\n\\addcontentsline{toc}{chapter}{Copyleft notice}\n\\input{free-software}\n\\@openrighttrue\\makeatother\n\\afterpage{\\blankpage}\n"
  },
  {
    "path": "src/free-software.tex",
    "content": "\\lettrine[lraise=-0.03,loversize=0.08]{T}{his book} is \\textbf{Libre} and follows the philosophy of\n\\urlref{https://www.gnu.org/philosophy/free-sw.en.html}{Free Software}:\nyou can use this book as you like, the source is available, you can redistribute\nthis book and you can distribute your own version. That means you can print it,\nphotocopy it, e-mail it, upload it to websites, change it, translate it, remix it, delete bits,\nand draw all over it.\n\nThis book is Copyleft: if you change the book and distribute your own version, you must also pass these freedoms to its recipients.\nThis book uses the Creative Commons Attribution-ShareAlike 4.0 International License\n(\\href{http://creativecommons.org/licenses/by-sa/4.0/}{\\acronym{CC BY-SA 4.0}})."
  },
  {
    "path": "src/half-title.tex",
    "content": "% !TEX root = ctfp-print.tex\n\\input{version}\n\n\\thispagestyle{empty}\n\n\\vspace*{80pt}\n\n\\begin{raggedleft}\n  \\fontsize{24pt}{24pt}\\selectfont\n  \\textbf{Category Theory \\\\ for Programmers}\\\\\n  \\ifdefined\\OPTCustomLanguage{%\n    \\vspace*{1cm}\n    \\small\\selectfont{\n      \\textbf{\\OPTDisplayLanguageName{} Edition}\\\\\n      \\textit{Contains code snippets in Haskell and \\OPTDisplayLanguageName}\\\\\n    }\n  }\n  \\fi\n  \\vspace*{1cm}\n  \\fontsize{16pt}{18pt}\\selectfont \\textit{By } \\textbf{Bartosz Milewski}\\\\\n  \\vspace{1cm}\n  \\fontsize{12pt}{14pt}\\selectfont \\textit{compiled and edited by}\\\\ \\textbf{Igal Tabachnik}\\\\\n\n\\end{raggedleft}\n\n\n\\newpage\n\n\\vspace*{0.3\\textheight}\n\\thispagestyle{empty}\n\n\\begin{small}\n  \\begin{center}\n\n    \\textsc{Category Theory for Programmers}\\\\\n\n    \\vspace{1.0em}\n    \\noindent\n    Bartosz Milewski\\\\\n\n    \\vspace{1.26em}\n    \\noindent\n    Version \\texttt{\\OPTversion}\\\\\\today\n\n\n    \\vspace{1.6em}\n    \\noindent\n    \\includegraphics[width=3mm]{fig/icons/cc.pdf}\n    \\includegraphics[width=3mm]{fig/icons/by.pdf}\n    \\includegraphics[width=3mm]{fig/icons/sa.pdf}\n\n    \\vspace{0.4em}\n    \\noindent\n    This work is licensed under a Creative Commons\\\\\n    Attribution-ShareAlike 4.0 International License\n    (\\href{http://creativecommons.org/licenses/by-sa/4.0/}{\\acronym{CC BY-SA 4.0}}).\n\n    \\vspace{1.26em}\n    \\noindent\n    Converted from a series of blog posts by \\href{https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/}{Bartosz Milewski}.\\\\\n    PDF and book compiled by \\href{https://hmemcpy.com}{Igal Tabachnik}.\\\\\n    \\vspace{1.26em}\n    \\noindent\n    \\LaTeX{} source code is available on GitHub: \\href{https://github.com/hmemcpy/milewski-ctfp-pdf}{https://github.com/hmemcpy/milewski-ctfp-pdf}\n  \\end{center}\n\\end{small}"
  },
  {
    "path": "src/index.tex",
    "content": "\\setindexprenote{\\normalsize\n  \\begin{quote} Any inaccuracies in this index may be explained by the fact\n    that it has been prepared with the help of a computer.\n\n    ---Donald E. Knuth, \\textit{Fundamental Algorithms}\\\\\n    (Volume 1 of \\textit{The Art of Computer Programming})\n  \\end{quote}}\n\n\\printindex"
  },
  {
    "path": "src/opt-ocaml.tex",
    "content": "\\def\\OPTCustomLanguage{ocaml}\n\\def\\OPTCustomLanguageExt{ml}\n\\def\\OPTCustomLanguageColor{BurntOrange}\n\\def\\OPTDisplayLanguageName{OCaml}"
  },
  {
    "path": "src/opt-print-ustrade.tex",
    "content": "% !TeX program = xelatex\n% !TEX root = ctfp-print-scala.tex\n\n\\def\\OPTmodes{twoside,final,openright,10pt}\n\n% After struggling a while to get it right, here's how to calculate:\n% 1. Use the calculator to get your specifications\n%    https://www.blurb.com/make/pdf_to_book/booksize_calculator\n% 2. Get the specifications. For a 6x9 hardcover (ImageWrap) book, I got:\n%\n%    Page Specifications                        Inches\n%    Final, exported PDF should measure (w x h) 6.125 x 9.25\n%    Page size / trim line (w x h)              6.0 x 9.0\n%    Bleed (top, bottom, and outside edges)     0.125\n%    Safe boundary (Top, Bottom, Outside Edge)  0.25\n%    Safe boundary (Binding Edge)               0.5\n%\n% 3. Trim line is at 0.625in, so to get safe text boundary (magenta line):\n%    Top margin:      0.625in (start at trim line, header space fills to safe line)\n%    Bottom margin:   0.625in + 0.25in = 0.875in\n%    Inner margin:    0.625in (start on the trim line)\n%    Binding offset:  0.5in\n%    Outer margin:    0.625in + 0.25in = 0.875in\n\n% Specifications for blurb.com\n\\def\\OPTpaperesize{6.125in,9.25in}     % Page size\n\\def\\OPTtopmargin{.625in}              % Margin at the top of the page\n\\def\\OPTbottommargin{0.875in}          % Margin at the bottom of the page\n\\def\\OPTinnermargin{0.625in}           % Margin on the inner side of the page\n\\def\\OPTbindingoffset{0.4in}           % Extra offset on the inner side\n\\def\\OPToutermargin{0.625in}           % Margin on the outer side of the page\n"
  },
  {
    "path": "src/opt-reader-10in.tex",
    "content": "% !TEX root = ctfp.tex\n\n% Options for reading on 10\" tables (e.g. Kindle DX)\n\n\\def\\OPTmodes{oneside,openany,11pt}\n\n% PAGE FORMAT\n%\n% Page geometry for 10-inch tablets\n\\def\\OPTpaperesize{148mm,197mm}  % Page size\n\\def\\OPTtopmargin{21mm}        % Margin at the top of the page\n\\def\\OPTbottommargin{28mm}     % Margin at the bottom of the page\n\\def\\OPTinnermargin{18.5mm}    % Margin on the inner side of the page\n\\def\\OPToutermargin{18.5mm}    % Margin on the outer side of the page\n\\def\\OPTbindingoffset{0mm}     % Extra offset on the inner side\n\n\\def\\OPThidelinks{false}"
  },
  {
    "path": "src/opt-reason.tex",
    "content": "\\def\\OPTCustomLanguage{reason}\n\\def\\OPTCustomLanguageExt{re}\n\\def\\OPTCustomLanguageColor{RedOrange}\n\\def\\OPTDisplayLanguageName{ReasonML}"
  },
  {
    "path": "src/opt-scala.tex",
    "content": "\\def\\OPTCustomLanguage{scala}\n\\def\\OPTCustomLanguageExt{scala}\n\\def\\OPTCustomLanguageColor{red}\n\\def\\OPTDisplayLanguageName{Scala}"
  },
  {
    "path": "src/postamble.tex",
    "content": "\n\\end{document}\n"
  },
  {
    "path": "src/preamble.tex",
    "content": "\\documentclass[\\OPTmodes]{book}\n\n\\usepackage[papersize={\\OPTpaperesize},\n            top=\\OPTtopmargin,\n            bottom=\\OPTbottommargin,\n            inner=\\OPTinnermargin,\n            outer=\\OPToutermargin,\n            bindingoffset=\\OPTbindingoffset,\n            centering,\n            % showframe,\n            ]{geometry}\n\n% New line height: 1.05 * 1.2 = 1.26\n\\renewcommand{\\baselinestretch}{1.05}\n\n% Uncomment for diagnostics!\n% \\usepackage[cam,width=6in,height=9in]{crop}\n\n% Font settings\n%--------------------------------------------------------------%  Note:\n\\usepackage[no-math]{fontspec}                                 %  This exact order\n\\usepackage{libertine}                                         %  of declarations\n\\defaultfontfeatures{%                                         %  is important for\n  Scale=MatchLowercase, % needed here ...                      %  single quotes not\n}                                                              %  to turn out curly\n\\setmonofont[BoldFont=Inconsolata-LGC-Bold.ttf]{Inconsolata-LGC-Bold.ttf} %  (\"typographic\")\n                                                               %  in verbatim blocks\n\\defaultfontfeatures{%                                         %  of Haskell code.\n  Scale=MatchLowercase, % ... and here again                   %  Now the quote is\n  Mapping=tex-text,                                            %  upright and safely\n  SmallCapsFeatures={LetterSpace=2.5,WordSpace=1.05},          %  copy-pasteable to\n}                                                              %  the REPL without\n%--------------------------------------------------------------%  giving errors.\n\n% To use Libertine letters and numbers,\n% but tx-style operators in math environment:\n\\usepackage[libertine]{newtxmath}\n\\usepackage{amsmath}\n% Needed to display additional math unicode symbols (like double-colon)\n\n% https://github.com/wspr/unicode-math/issues/469\n\\expandafter\\let\\csname not=\\endcsname\\relax\n\\expandafter\\let\\csname not<\\endcsname\\relax\n\\expandafter\\let\\csname not>\\endcsname\\relax\n\\usepackage{unicode-math}\n\\setmathfont{LibertinusMath-Regular.otf}\n\n\\usepackage[all]{nowidow}\n\\usepackage{emptypage}\n\\usepackage{noindentafter}\n\n\\usepackage{graphicx}\n\\usepackage{caption, wrapfig, framed, subfigure}\n\\usepackage[export]{adjustbox}\n\\captionsetup{labelformat=empty,font=scriptsize}\n\\usepackage{titlecaps}\n\n\\usepackage[usenames,dvipsnames,x11names]{xcolor}\n\\usepackage{longtable}\n\\usepackage{booktabs}\n% Workaround to fix mismatched left and right math delimiters. Taken from:\n% http://tex.stackexchange.com/questions/63410/parentheses-differ-xelatex-fontspec-newtxmath-libertine\n\\DeclareSymbolFont{parenthesis}{T1}{fxl}{m}{n}\n\\DeclareMathDelimiter{(}{\\mathopen}{parenthesis}{\"28}{largesymbols}{\"00}\n\\DeclareMathDelimiter{)}{\\mathclose}{parenthesis}{\"29}{largesymbols}{\"01}\n\\DeclareMathDelimiter{[}{\\mathopen}{parenthesis}{\"5B}{largesymbols}{\"02}\n\\DeclareMathDelimiter{]}{\\mathclose}{parenthesis}{\"5D}{largesymbols}{\"03}\n\\DeclareMathDelimiter{\\lbrace}{\\mathopen}{parenthesis}{\"7B}{largesymbols}{\"08}\n\\DeclareMathDelimiter{\\rbrace}{\\mathclose}{parenthesis}{\"7D}{largesymbols}{\"09}\n\n% Use tikz-cd for commutative diagrams\n\\usepackage{tikz-cd}\n\\usepackage[framemethod=TikZ]{mdframed}\n\n\\usepackage{ifthen}\n\\usepackage{fancyvrb}\n\\fvset{fontsize=\\small}\n\n\\usepackage[cachedir=_minted-ctfp]{minted}\n\\setminted[text]{fontsize=\\small,breaklines}\n\\usemintedstyle{github}\n\\makeatletter\n% prevents cleaning up the cache at the end of the run (needed to keep the \"unused\" caches, generated by other editions)\n\\renewcommand*{\\minted@cleancache}{}\n\\makeatother\n\n\\usepackage{imakeidx}\n\\usepackage[totoc,font=footnotesize]{idxlayout}\n\\usepackage{fancyhdr}\n\\pagestyle{plain}\n\\usepackage[final]{pdfpages} % inserts pages from a pdf file\n\n\\usepackage{titlesec}  % to change the appearance of section titles\n\\usepackage{listings}  % for syntax highlighted code listings\n\\usepackage{enumerate} % allows customized labels in enumerations\n\\usepackage{enumitem}  % allows nested enumeration with numbers\n\\PassOptionsToPackage{hyphens}{url}\\usepackage{hyperref}  % makes cross references and URLs clickable\n\\definecolor{LinkRed}{HTML}{80171F}\n\\hypersetup{\n  pdfauthor={Bartosz Milewski},\n  pdftitle={Category Theory for Programmers},\n  pdfsubject={category theory, computer science, programming, abstraction, composition},\n  colorlinks=true,\n  linkcolor=LinkRed,\n  urlcolor=LinkRed,\n}\n\\usepackage{afterpage}\n\\newcommand\\blankpage{%\n    \\null\n    \\thispagestyle{empty}%\n    \\addtocounter{page}{-1}%\n    \\newpage}\n\n\\usepackage{subfiles}\n\\makeatletter\n\\let\\org@subfile\\subfile\n\\renewcommand*{\\subfile}[1]{%\n  \\filename@parse{#1}\n  \\expandafter\n  \\graphicspath\\expandafter{\\expandafter{\\filename@area}}\n  \\org@subfile{#1}%\n}\n\\makeatother\n\n% Document colors\n\\definecolor{Dark}          {HTML} {262626}\n\\definecolor{DropCapGray}   {HTML} {B8B8B8}\n\\definecolor{ChapterGray}   {HTML} {C8C8C8}\n\\definecolor{ChapterViolet} {HTML} {AEAECE}\n\\definecolor{DropCapViolet} {HTML} {9090C0}\n\n\\usepackage{lettrine}  % adds commands that make drop capitals\n\\renewcommand{\\LettrineFontHook}{\\rmfamily\\mdseries\\color{DropCapViolet}}\n\\renewcommand{\\DefaultLraise}{0.00}\n\\renewcommand{\\DefaultLoversize}{0.02}\n\\renewcommand{\\DefaultLhang}{0.12}\n\\setlength{\\DefaultFindent}{1pt}\n\\setlength{\\DefaultNindent}{0em}\n\n% removes the \"Part X\" text from \\part\n\\renewcommand{\\partname}{}\n\\renewcommand{\\thepart}{}\n\n\\usepackage{xparse}\n\\usepackage[abspath]{currfile}\n\n\\newenvironment{snip}[2][]\n  {\\VerbatimEnvironment\n  \\mdfsetup{\n    linecolor=gray!20,\n    linewidth=2pt,\n    topline=false,\n    bottomline=false,\n    rightline=false\n  }\n  \\begin{mdframed}\\begin{minted}[#1]{#2}}\n {\\end{minted}\\end{mdframed}\n \\vspace{-1ex}}\n\n \\newenvironment{snipv}\n {\\VerbatimEnvironment\n \\mdfsetup{\n   linecolor=gray!20,\n   linewidth=2pt,\n   topline=false,\n   bottomline=false,\n   rightline=false\n }\n \\begin{mdframed}\\begin{Verbatim}[commandchars=\\\\\\{\\}]}\n{\\end{Verbatim}\\end{mdframed}\n\\vspace{-1ex}}\n\n% See the context about this workaround at\n% https://github.com/gpoore/minted/issues/354\n\\makeatletter\n\\ifwindows\n  \\def\\minted@opt@quote#1{\\detokenize\\expandafter{\\expandafter\"\\expanded{#1}\"}}\n\\else\n  \\def\\minted@opt@quote#1{\\detokenize\\expandafter{\\expandafter'\\expanded{#1}'}}\n\\fi\n\\makeatother\n\n\\NewDocumentCommand\\src{mO{}}{\n  \\srcsnippet{\\currfileabsdir/code/haskell/#1.hs}{blue}{haskell}{#2}\n  \\ifdefined\\OPTCustomLanguage{%\n    \\unskip\n    \\srcsnippet{\\currfileabsdir/code/\\OPTCustomLanguage/#1.\\OPTCustomLanguageExt}{\\OPTCustomLanguageColor}{\\OPTCustomLanguage}{#2}\n  }\n  \\fi\n  \\NoIndentAfterThis\n}\n\\NewDocumentCommand\\srcsnippet{mmmm}{\n  \\newif\\ifbreak\n  \\def\\snippet{#1}\n  \\mdfsetup{%\n    linecolor=#2!20,%\n    linewidth=2pt,\n    topline=false,\n    bottomline=false,\n    rightline=false,\n  }\n  \\def\\x{#4}\n  \\ifthenelse{\\equal{\\x}{b}}{\\breaktrue}{\\breakfalse}\n  \\begin{mdframed}\n    \\ifbreak \\inputminted[autogobble,breaklines]{#3}{\\snippet}\n    \\else \\inputminted[autogobble]{#3}{\\snippet}\n    \\fi\n  \\end{mdframed}\n}\n\n\\newcommand{\\acronym}[1]{\\textsc{\\MakeLowercase{#1}}}\n\\newcommand{\\newterm}[1]{\\index{#1}\\emph{#1}}\n\\newcommand{\\code}[1]{\\Verb+{#1}+}\n\\newcommand{\\heading}[1]{{\\sffamily\\bfseries #1}}\n\\newcommand{\\mono}[1]{\\hbox{\\ttfamily\\scriptsize #1}}\n\\newcommand{\\monoit}[1]{\\hbox{\\ttfamily\\itshape\\scriptsize #1}}\n\\newcommand{\\mathtext}[1]{\\ensuremath{\\pmb{#1}}}\n\\newcommand{\\urlref}[2]{\\href{#1}{#2}\\urlfootnote{#1}}\n\n% https://tex.stackexchange.com/questions/219445/line-break-in-texttt/219497\n\\renewcommand{\\code}[1]{%\n  \\begingroup\n  \\ttfamily\n  \\begingroup\\lccode`~=`/\\lowercase{\\endgroup\\def~}{/\\discretionary{}{}{}}%\n  \\begingroup\\lccode`~=`[\\lowercase{\\endgroup\\def~}{[\\discretionary{}{}{}}%\n  \\begingroup\\lccode`~=`.\\lowercase{\\endgroup\\def~}{.\\discretionary{}{}{}}%\n  \\catcode`/=\\active\\catcode`[=\\active\\catcode`.=\\active\n  \\scantokens{#1\\noexpand}%\n  \\endgroup\n}\n\n\\makeatletter\n\\newcommand\\urlfootnote@[1]{\\footnote{\\url@{#1}}}\n\\DeclareRobustCommand{\\urlfootnote}{\\hyper@normalise\\urlfootnote@}\n\\makeatother\n\n\\titleformat{\\chapter}[display]\n  {\\color{Dark}\\normalfont\\sffamily\\bfseries\\LARGE}\n  {\\filright \\color{ChapterViolet}\\sffamily\\mdseries\n    \\fontsize{6em}{0em}\\selectfont\n    {\\addfontfeature{Numbers=OldStyle}\\thechapter}}\n  {1em}\n  {\\filright}\n\n\\titleformat{\\section}\n{\\color{Dark}\\normalfont\\Large\\sffamily\\bfseries}\n{\\color{DropCapViolet}\\thesection}{0.8em}{}\n\n\\titleformat{\\subsection}\n{\\color{Dark}\\normalfont\\large\\sffamily\\bfseries}\n{\\color{DropCapViolet}\\thesubsection}{0.8em}{}\n\n\\titleformat{\\subsubsection}\n{\\color{black}\\normalfont\\normalsize\\sffamily\\bfseries}\n{\\color{DropCapViolet}\\thesubsubsection}{0.8em}{}\n\n\\setcounter{secnumdepth}{3}\n\\setcounter{tocdepth}{3}\n\n\\sloppy\n\\frenchspacing\n\\makeindex\n\n% reduce space between items in a list\n\\providecommand{\\tightlist}{%\n\\setlength{\\itemsep}{0pt}\\setlength{\\parskip}{0pt}}\n\n%====================%\n%  End of preamble.  %\n%====================%\n\n\\input{category}\n\\begin{document}\n"
  },
  {
    "path": "src/scraper.py",
    "content": "import os\nimport pypandoc\nimport pathlib\nfrom requests import get\nfrom bs4 import BeautifulSoup\nfrom mercury_parser import ParserAPI\n\n# get the API key at https://mercury.postlight.com/web-parser/\nmercury = ParserAPI(api_key='<your API key>')\n\nindex_page = 'https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/'\n\n\ndef get_toc():\n    result = []\n    part = 0\n    chapter = 0\n    lists = get_content(get(index_page).content).find_all('ol')\n    for part_list in lists:\n        part += 1\n        for li in part_list.find_all('li'):\n            chapter += 1\n            result.append({'chapter': '{}.{}'.format(part, chapter),\n                           'title': li.a.text,\n                           'url': li.a['href']})\n        chapter = 0\n    return result\n\n\ndef get_content(html):\n    soup = BeautifulSoup(html, 'html.parser')\n    return soup.find(class_='post-content')\n\n\ndef write_content(file, content):\n    with file.open('w') as f: f.write(content)\n\n\ndef save_images(markup, path):\n    import urllib.request\n    html = get_content(markup)\n    images = html.find_all('img')\n    for img in images:\n        image_url = img.parent['href']\n        image_file = image_url.split('/')[-1]\n        target_file = path.joinpath(image_file)\n        urllib.request.urlretrieve(image_url, target_file)\n        img['src'] = 'images/' + target_file.name\n        img.parent.replaceWithChildren()  # removes the parent <a href...> and replaces it with the image\n    return html\n\n\ndef save_url(chapter, title, url):\n    file_name = '{}.tex'.format(title.replace('/', '\\\\').replace(':', ' -'))\n    path = pathlib.Path(os.path.join('content', chapter, 'images'))\n    path.mkdir(parents=True, exist_ok=True)\n\n    p = mercury.parse(url)\n    html = save_images(p.content, path)\n\n    content = pypandoc.convert_text(html, 'tex', format='html')\n    write_content(path.parent.joinpath(file_name), content)\n\n\nfor toc in get_toc():\n    print(toc)\n    title = toc['title']\n    chapter = toc['chapter']\n    url = toc['url']\n    save_url(chapter, title, url)\nsave_url('0.0', 'Preface', index_page)\n"
  },
  {
    "path": "src/version.tex",
    "content": "\\newcommand\\OPTversion{dev}"
  }
]