{"id":13678567,"url":"https://github.com/alhassy/AgdaCheatSheet","last_synced_at":"2025-04-29T15:32:05.032Z","repository":{"id":45135617,"uuid":"212402799","full_name":"alhassy/AgdaCheatSheet","owner":"alhassy","description":"Basics of the dependently-typed functional language Agda ^_^","archived":false,"fork":false,"pushed_at":"2022-01-06T01:46:40.000Z","size":471,"stargazers_count":37,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-06-17T15:52:33.591Z","etag":null,"topics":["agda","cheatsheet","emacs","html","pdf"],"latest_commit_sha":null,"homepage":null,"language":"Agda","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alhassy.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-02T17:37:24.000Z","updated_at":"2023-11-29T20:34:08.000Z","dependencies_parsed_at":"2022-08-26T09:52:42.359Z","dependency_job_id":null,"html_url":"https://github.com/alhassy/AgdaCheatSheet","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FAgdaCheatSheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FAgdaCheatSheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FAgdaCheatSheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alhassy%2FAgdaCheatSheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alhassy","download_url":"https://codeload.github.com/alhassy/AgdaCheatSheet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":213678354,"owners_count":15622499,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agda","cheatsheet","emacs","html","pdf"],"created_at":"2024-08-02T13:00:55.295Z","updated_at":"2024-08-02T13:07:43.841Z","avatar_url":"https://github.com/alhassy.png","language":"Agda","funding_links":[],"categories":["Agda"],"sub_categories":[],"readme":"# Created 2019-10-04 Fri 16:08\n#+OPTIONS: toc:nil d:nil\n#+OPTIONS: toc:nil d:nil\n#+TITLE: Agda CheatSheet\n#+AUTHOR: [[http://www.cas.mcmaster.ca/~alhassm/][Musa Al-hassy]]\n#+export_file_name: README.org\n\nBasics of Agda, a total and dependently-typed functional language (•̀ᴗ•́)و\n\n*The listing sheet, as PDF, can be found\n [[file:CheatSheet.pdf][here]]*,\n or as a [[file:CheatSheet_Portrait.pdf][single column portrait]],\n while below is an unruly html rendition.\n\nThis reference sheet is built from a\n[[https://github.com/alhassy/CheatSheet][CheatSheets with Org-mode]]\nsystem. This is a /literate/ Agda file written in Org-mode using\n[[https://github.com/alhassy/org-agda-mode][org-agda-mode]].\n\n#+toc: headlines 2\n\n#+macro: blurb Basics of Agda, a total and dependently-typed functional language (•̀ᴗ•́)و\n\n#+latex_header: \\usepackage{titling,parskip}\n#+latex_header: \\usepackage{eufrak} % for mathfrak fonts\n#+latex_header: \\usepackage{multicol,xparse,newunicodechar}\n\n#+latex_header: \\usepackage{etoolbox}\n\n#+latex_header: \\newif\\iflandscape\n#+latex_header: \\landscapetrue\n\n#+latex_header_extra: \\iflandscape \\usepackage[landscape, margin=0.5in]{geometry} \\else \\usepackage[margin=0.5in]{geometry} \\fi\n\n#+latex_header: \\def\\cheatsheetcols{2}\n#+latex_header: \\AfterEndPreamble{\\begin{multicols}{\\cheatsheetcols}}\n#+latex_header: \\AtEndDocument{ \\end{multicols} }\n\n#+latex_header: \\let\\multicolmulticols\\multicols\n#+latex_header: \\let\\endmulticolmulticols\\endmulticols\n#+latex_header: \\RenewDocumentEnvironment{multicols}{mO{}}{\\ifnum#1=1 #2 \\def\\columnbreak{} \\else \\multicolmulticols{#1}[#2] \\fi}{\\ifnum#1=1 \\else \\endmulticolmulticols\\fi}\n\n#+latex_header: \\def\\maketitle{}\n#+latex: \\fontsize{9}{10}\\selectfont\n\n#+latex_header: \\def\\cheatsheeturl{}\n\n#+latex_header: \\usepackage[dvipsnames]{xcolor} % named colours\n#+latex: \\definecolor{grey}{rgb}{0.5,0.5,0.5}\n\n#+latex_header: \\usepackage{color}\n#+latex_header: \\definecolor{darkgreen}{rgb}{0.0, 0.3, 0.1}\n#+latex_header: \\definecolor{darkblue}{rgb}{0.0, 0.1, 0.3}\n#+latex_header: \\hypersetup{colorlinks,linkcolor=darkblue,citecolor=darkblue,urlcolor=darkgreen}\n\n#+latex_header: \\setlength{\\parindent}{0pt}\n\n\n#+latex_header: \\def\\cheatsheetitemsep{-0.5em}\n#+latex_header: \\let\\olditem\\item\n#+latex_header_extra: \\def\\item{\\vspace{\\cheatsheetitemsep}\\olditem}\n\n#+latex_header: \\usepackage{CheatSheet/UnicodeSymbols}\n\n#+latex_header: \\makeatletter\n#+latex_header: \\AtBeginEnvironment{minted}{\\dontdofcolorbox}\n#+latex_header: \\def\\dontdofcolorbox{\\renewcommand\\fcolorbox[4][]{##4}}\n#+latex_header: \\makeatother\n\n\n\n#+latex_header: \\RequirePackage{fancyvrb}\n#+latex_header: \\DefineVerbatimEnvironment{verbatim}{Verbatim}{fontsize=\\scriptsize}\n\n\n#+latex_header: \\def\\cheatsheeturl{https://github.com/alhassy/AgdaCheatSheet}\n\n#+latex_header: \\def\\cheatsheetcols{2}\n#+latex_header: \\landscapetrue\n#+latex_header: \\def\\cheatsheetitemsep{-0.5em}\n\n#+latex_header: \\newunicodechar{‼}{\\ensuremath{!\\!!}}\n#+latex_header: \\newunicodechar{𝕨}{\\ensuremath{\\mathbb{w}}}\n#+latex_header: \\newunicodechar{≈}{\\ensuremath{\\approx}}\n#+latex_header: \\newunicodechar{ℓ}{\\ensuremath{\\ell}}\n#+latex_header: \\newunicodechar{ω}{\\ensuremath{\\omega}}\n#+latex_header: \\newunicodechar{⁰}{\\ensuremath{^0}}\n#+latex_header: \\newunicodechar{⁴}{\\ensuremath{^4}}\n#+latex_header: \\newunicodechar{♯}{\\ensuremath{\\sharp}}\n#+latex_header: \\newunicodechar{α}{\\ensuremath{\\alpha}}\n#+latex_header: \\newunicodechar{β}{\\ensuremath{\\beta}}\n\n\n#+latex_header: \\newunicodechar{⇨}{\\ensuremath{\\circlearrowright}}\n\n#+begin_quote\n- [[#administrivia][Administrivia]]\n- [[#dependent-functions][Dependent Functions]]\n- [[#reads][Reads]]\n- [[#dependent-datatypes][Dependent Datatypes]]\n- [[#the-curry-howard-correspondence----propositions-as-types][The Curry-Howard Correspondence ---“Propositions as Types”]]\n  - [[#adding-to-the-table][Adding to the table]]\n- [[#equality][Equality]]\n- [[#break][break]]\n- [[#modules----namespace-management][Modules ---Namespace Management]]\n  - [[#anonymous-modules-and-variables][Anonymous Modules and Variables]]\n  - [[#break][break]]\n  - [[#module-keywords][Module Keywords]]\n- [[#records][Records]]\n- [[#interacting-with-the-real-world----compilation-haskell-and-io][Interacting with the real world ---Compilation, Haskell, and IO]]\n- [[#absurd-patterns][Absurd Patterns]]\n  - [[#preconditions-as-proof-object-arguments][Preconditions as proof-object arguments]]\n- [[#mechanically-moving-from-bool-to-set----avoiding-boolean-blindness][Mechanically Moving from ~Bool~ to ~Set~ ---Avoiding “Boolean Blindness”]]\n#+end_quote\n\n* Administrivia\n\n#+latex: \\hspace{-1.3em}\nAgda is based on  intuitionistic type theory.\n\n| Agda | ≈ | Haskell + Harmonious Support for Dependent Types |\n\nIn particular, /types ≈ terms/ and so, for example,\n~ℕ ∶ Set = Set₀~ and ~Setᵢ ∶ Setᵢ₊₁~.\nOne says /universe/ ~Setₙ~ has /level/ $n$.\n\n⇨ It is a programming language and a proof assistant.\n#+latex: \\newline {\\color{white}.}\\hspace{0.3em}\nA proposition is proved by writing a program of the corresponding type.\n\n⇨ Its Emacs interface allows programming by gradual refinement\n  of incomplete type-correct terms. One uses the “hole” marker ~?~\n  as a placeholder that is used to stepwise write a program.\n\n⇨ Agda allows arbitrary mixfix Unicode lexemes, identifiers.\n- Underscores are used to indicate where positional arguments.\n- Almost anything can be a valid name; e.g., ~[]~ and ~_∷_~ below.\n  Hence it's important to be liberal with whitespace: ~e:T~ is a valid identifier\n  whereas ~e ∶ T~ declares ~e~ to be of type ~T~.\n\n#+latex: \\begin{parallel}\n\n#+latex: \\begin{tiny}\n#+begin_src agda\nmodule CheatSheet where\n\nopen import Level using (Level)\nopen import Data.Nat\nopen import Data.Bool hiding (_\u003c?_)\nopen import Data.List using (List; []; _∷_; length)\n#+end_src\n#+latex: \\end{tiny} \\columnbreak\n\nEvery Agda file contains at most one top-level module whose name\ncorresponds to the name of the file.\nThis document is generated from a ~.lagda~ file.\n\n#+latex: \\end{parallel} \\vspace{-1em}\n\n* Dependent Functions\n\n#+latex: \\hspace{-1.3em}\nA /dependent function type/ has those functions whose result /type/ depends\non the /value/ of the argument. If ~B~ is a type depending on a type ~A~, then\n~(a ∶ A) → B a~ is the type of functions ~f~ mapping arguments ~a ∶ A~ to values ~f a ∶ B a~.\nVectors, matrices, sorted lists, and trees of a particular height are all examples of dependent types.\n\n#+latex: \\begin{parallel}\nFor example, /the/ generic identity function takes as /input/ a type ~X~ and returns as /output/\na function ~X → X~. Here are a number of ways to write it in Agda.\n\n#+latex: \\vspace{0.5em}\\hrule\\vspace{0.5em}\n\nAll these functions explicitly require the type ~X~ when we use them, which is silly since\nit can be inferred from the element ~x~.\n\n#+latex: \\columnbreak\n\n#+begin_src agda\nid₀ : (X : Set) → X → X\nid₀ X x = x\n\nid₁ id₂ id₃ : (X : Set) → X → X\n\nid₁ X = λ x → x\nid₂   = λ X x → x\nid₃   = λ (X : Set) (x : X) → x\n#+end_src\n\n#+latex: \\end{parallel} \\vspace{-1em}\n\nCurly braces make an argument /implicitly inferred/ and so it may be omitted.\nE.g., the ~{X ∶ Set} → ⋯~ below lets us make a polymorphic function\nsince ~X~ can be inferred by inspecting the given arguments. This is akin to\ninformally writing $\\mathsf{id}_X$ versus $\\mathsf{id}$.\n\n#+latex: \\begin{parallel}\n#+begin_src agda\nid : {X : Set} → X → X\nid x = x\n\nsad : ℕ\nsad = id₀ ℕ 3\n\nnice : ℕ\nnice = id 3\n#+end_src\n#+latex: \\columnbreak\n#+begin_src agda\nexplicit : ℕ\nexplicit = id {ℕ} 3\n\nexplicit′ : ℕ\nexplicit′ = id₀ _ 3\n#+end_src\n#+latex: \\end{parallel}\n\n#+latex: \\vspace{-1em}\nNotice that we may provide an implicit argument /explicitly/ by enclosing the value in braces\nin its expected position. Values can also be inferred when the ~_~ pattern is supplied in a value position.\n\nEssentially wherever the typechecker can figure out a value ---or a type---, we may use ~_~.\nIn type declarations, we have a contracted form via ~∀~---which is *not* recommended since it slows down typechecking\nand, more importantly, types /document/ our understanding and it's useful to have them explicitly.\n\nIn a type, ~(a : A)~ is called a /telescope/ and they can be combined for convenience.\n\n#+latex: \\begin{parallel}\n#+begin_example agda\n   {x : _} {y : _} (z : _) → ⋯\n≈  ∀ {x y} z → ⋯\n#+end_example\n#+latex: \\columnbreak\n#+begin_example agda\n   (a₁ : A) → (a₂ : A) → (b : B) → ⋯\n≈  (a₁ a₂ : A) (b : B) → ⋯\n#+end_example\n#+latex: \\end{parallel} \\vspace{-1.5em}\n\n* Reads\n\n#+latex: {\\color{white}.} \\vspace{-1.5em}\n\n- [[http://www.cse.chalmers.se/~ulfn/papers/afp08/tutorial.pdf][Dependently Typed Programming in Agda]]\n  - Aimed at functional programmers\n- [[https://agda.readthedocs.io/en/v2.6.0.1/getting-started/tutorial-list.html][Agda Meta-Tutorial]] and [[https://wiki.portal.chalmers.se/agda/pmwiki.php][The Agda Wiki]]\n- [[https://mazzo.li/posts/AgdaSort.html][Agda by Example: Sorting]]\n  - One of the best introductions to Agda\n- [[https://plfa.github.io/][Programming Language Foundations in Agda]]\n  - Online, well-organised, and accessible book\n- [[https://alhassy.github.io/PathCat/][Graphs are to categories as lists are to monoids]]\n  - A brutal second tutorial\n- [[https://oxij.org/note/BrutalDepTypes/][Brutal {Meta}Introduction to Dependent Types in Agda]]\n  - A terse but accessible tutorial\n- [[http://learnyouanagda.liamoc.net/][Learn You An Agda (and achieve enlightenment)]]\n  - Enjoyable graphics\n- [[https://github.com/agda][The Agda Github Umbrella]]\n  - Some Agda libraries\n- [[https://cs.ru.nl/~wouters/Publications/ThePowerOfPi.pdf][The Power of Pi]]\n  - Design patterns for dependently-typed languages, namely Agda\n- [[https://alhassy.github.io/next-700-module-systems/prototype/package-former.html][Making Modules with Meta-Programmed Meta-Primitives]]\n  - An Emacs editor extension for Agda\n- [[https://github.com/alhassy/gentle-intro-to-reflection][A gentle introduction to reflection in Agda]] ---Tactics!\n- [[http://dx.doi.org/10.1007/11546382_3][Epigram: Practical Programming with Dependent Type]]\n\n  - “If it typechecks, ship it!” ...\n  - Maybe not; e.g., ~if null xs then tail xs else xs~\n  - /We need a static language capable of expressing the significance of\n    particular values in legitimizing some computations rather than others./\n\n* Dependent Datatypes\n\n#+latex: \\hspace{-1.3em}\nAlgebraic datatypes are introduced with a ~data~ declaration, giving the name,\narguments, and type of the datatype as well as the constructors and their types.\nBelow we define the datatype of lists of a particular length.\nThe Unicode below is entered with ~\\McN, \\::~, and ~\\to~.\n\n#+begin_src agda\ndata Vec {ℓ : Level} (A : Set ℓ) : ℕ → Set ℓ where\n  []  : Vec A 0\n  _∷_ : {n : ℕ} → A → Vec A n → Vec A (1 + n)\n#+end_src\n\nNotice that, for a given type ~A~, the type of ~Vec A~\nis ~ℕ → Set~. This means that ~Vec A~ is a family of types\nindexed by natural numbers: For each number ~n~, we have a type ~Vec A n~.\n\nOne says ~Vec~ is /parametrised/ by ~A~ (and ℓ), and /indexed/ by ~n~.\n\nThey have different roles:\n~A~ is the type of elements in the vectors,\nwhereas ~n~ determines the ‘shape’ ---length--- of the vectors\nand so needs to be more ‘flexible’ than a parameter.\n\nNotice that the indices say that the only way to make an element of ~Vec A 0~ is to\nuse ~[]~ and the only way to make an element of ~Vec A (1 + n)~ is to use ~_∷_~.\nWhence, we can write the following safe function since ~Vec A (1 + n)~ denotes\nnon-empty lists and so the pattern ~[]~ is impossible.\n#+begin_src agda\n\nhead : {A : Set} {n : ℕ} → Vec A (1 + n) → A\nhead (x ∷ xs) = x\n#+end_src\n\nThe ℓ argument means the ~Vec~ type operator is /universe polymorphic/: We can make\nvectors of, say, numbers but also vectors of types. Levels are essentially natural numbers:\nWe have ~lzero~ and ~lsuc~ for making them, and ~_⊔_~ for taking the maximum of two levels.\n/There is no universe of all universes:/\n~Setₙ~ has type ~Setₙ₊₁~ /for any n/, however the /type/ ~(n : Level) → Set n~ is /not/ itself typeable\n---i.e., is not in ~Setₗ~ for any ~l~--- and Agda errors saying it is a value of ~Setω~.\n\nFunctions are defined by pattern matching, and must cover all possible cases.\nMoreover, they must be terminating and so recursive calls must be made on structurally smaller\narguments; e.g., ~xs~ is a sub-term of ~x ∷ xs~ below and catenation is defined recursively on the first argument.\nFirstly, we declare a /precedence rule/ so we may omit parenthesis in seemingly ambiguous expressions.\n#+begin_src agda\n infixr 40 _++_\n\n _++_ : {A : Set} {n m : ℕ} → Vec A n → Vec A m → Vec A (n + m)\n []       ++ ys  =  ys\n (x ∷ xs) ++ ys  =  x ∷ (xs ++ ys)\n#+end_src\nNotice that the *type encodes a useful property*: The length of the catenation\nis the sum of the lengths of the arguments.\n\n- Different types can have the same constructor names.\n\n- Mixifx operators can be written prefix by having all underscores mentioned; e.g.,\n  ~x ∷ xs~ is the same as ~_∷_ x xs~.\n\n- In a function definition, if you don't care about an argument\n  and don't want to bother naming it, use ~_~ with whitespace around it.\n  This is the “wildcard pattern”.\n\n- Exercise: Define the Booleans then define the /control flow construct/ ~if_then_else_~.\n\n* The Curry-Howard Correspondence ---“Propositions as Types”\n\n#+latex: \\hspace{-1.3em}\nProgramming and proving are two sides of the same coin.\n\n#+macro: twolines @@latex:\\begin{tabular}[l]{@{}l@{}}$1\\\\$2\\end{tabular}@@\n#+macro: hfill @@latex:\\hfill@@\n\n| *Logic*             | *Programming*              | Example Use in Programming                         |\n|---------------------+----------------------------+----------------------------------------------------|\n| proof / proposition | element / type             | “$p$ is a proof of $P$” ≈ “$p$ is of type $P$”     |\n|---------------------+----------------------------+----------------------------------------------------|\n| $true$              | singleton type             | return type of side-effect only methods            |\n| $false$             | empty type                 | return type for non-terminating methods            |\n|---------------------+----------------------------+----------------------------------------------------|\n| ⇒                   | function type     →        | methods with an input and output type              |\n| ∧                   | product type     ×         | simple records of data and methods                 |\n| ∨                   | sum type        +          | enumerations or tagged unions                      |\n|---------------------+----------------------------+----------------------------------------------------|\n| ∀                   | dependent function type  Π | return type varies according to input \\emph{value} |\n| ∃                   | dependent product type   Σ | record fields depend on each other's \\emph{values} |\n|---------------------+----------------------------+----------------------------------------------------|\n| natural deduction   | type system                | ensuring only ``meaningful'' programs              |\n| hypothesis          | free variable              | global variables, closures                         |\n|---------------------+----------------------------+----------------------------------------------------|\n| modus ponens        | function application       | executing methods on arguments                     |\n| ⇒-introduction      | λ-abstraction              |                                                    |\n|---------------------+----------------------------+----------------------------------------------------|\n|                     | Structural recursion       | ~for~-loops are precisely ℕ-induction              |\n\n** Adding to the table\nLet's augment the table a bit:\n| *Logic*                 | *Programming*                               |\n| Signature, term         | Syntax; interface, record type, ~class~     |\n| Algebra, Interpretation | Semantics; implementation, instance, object |\n| Free Theory             | Data structure                              |\n| Inference rule          | Algebraic datatype constructor              |\n| Monoid                  | Untyped programming / composition           |\n| Category                | Typed programming / composition             |\n\n#+latex: \\vspace{-1em}\n\n* Equality\n\n#+latex: \\hspace{-1.3em}\nAn example of propositions-as-types is a definition of the identity relation\n---the least reflexive relation.\n\n#+latex: \\begin{parallel}[2]\n#+begin_src agda\ndata _≡_ {A : Set} : A → A → Set\n  where\n    refl : {x : A} → x ≡ x\n#+end_src\n#+latex: \\columnbreak\n\nThis states that ~refl {x}~ is a proof of ~l ≡ r~\nwhenever ~l~ and ~r~ simplify, by definition chasing only, to ~x~.\n\n#+latex: \\end{parallel} \\vspace{-1em}\n\nThis definition makes it easy to prove [[https://en.wikipedia.org/wiki/Identity_of_indiscernibles][Leibniz's substitutivity rule]],\n“equals for equals”:\n#+begin_src agda\nsubst : {A : Set} {P : A → Set} {l r : A}\n      → l ≡ r → P l → P r\nsubst refl it = it\n#+end_src\nWhy does this work?\nAn element of ~l ≡ r~ must be of the form ~refl {x}~ for some\ncanonical form ~x~; but if ~l~ and ~r~ are both ~x~, then ~P l~ and ~P r~\nare the /same type/. Pattern matching on a proof of ~l ≡ r~\ngave us information about the rest of the program's type!\n\n#+latex: \\columnbreak\n* Modules ---Namespace Management\n\n#+latex: \\hspace{-1.3em}\nModules are not a first-class construct, yet.\n\n- Within a module, we may have nested module declarations.\n- All names in a module are public, unless declared ~private~.\n\n#+latex: \\begin{parallel}[4]\n_A Simple Module_\n#+latex: \\vspace{0.5em}\n#+begin_src agda\nmodule M where\n\n  𝒩 : Set\n  𝒩 = ℕ\n\n  private\n    x : ℕ\n    x = 3\n\n  y : 𝒩\n  y = x + 1\n#+end_src\n#+latex: \\columnbreak\n_Using It_\n#+latex: \\vspace{0.5em}\n#+begin_src agda\nuse₀ : M.𝒩\nuse₀ = M.y\n\nuse₁ : ℕ\nuse₁ = y\n  where open M\n#+end_src\n\n#+begin_example agda\n\nopen M\n\nuse₂ : ℕ\nuse₂ = y\n#+end_example\n#+latex: \\columnbreak\n_Parameterised Modules_\n#+latex: \\vspace{0.5em}\n#+begin_src agda\nmodule M′ (x : ℕ)\n  where\n    y : ℕ\n    y = x + 1\n#+end_src\n#+latex: \\vfill\n_Names are Functions_\n#+latex: \\vspace{0.2em}\n#+begin_src agda\nexposed : (x : ℕ)\n        → ℕ\nexposed = M′.y\n#+end_src\n#+latex: \\columnbreak\n\n_Using Them_\n#+latex: \\vspace{0.5em}\n#+begin_src agda\nuse′₀ : ℕ\nuse′₀ = M′.y 3\n\nmodule M″ = M′ 3\n\nuse″ : ℕ\nuse″ = M″.y\n\nuse′₁ : ℕ\nuse′₁ = y\n  where\n    open M′ 3\n#+end_src\n\n#+latex: \\end{parallel}\n\n- Public names may be accessed by qualification or by opening them locally or globally.\n- Modules may be parameterised by arbitrarily many values and types ---but not by other modules.\n\nModules are essentially implemented as syntactic sugar: Their declarations are treated\nas top-level functions that takes the parameters of the module as extra arguments.\nIn particular, it may appear that module arguments are ‘shared’ among their declarations,\nbut this is not so.\n\n“Using Them”:\n- This explains how names in parameterised modules are used: They are treated as functions.\n- We may prefer to instantiate some parameters and name the resulting module.\n- However, we can still ~open~ them as usual.\n\n** Anonymous Modules and Variables\n\nAnonymous modules correspond to named-then-immediately-opened modules,\nand serve to approximate the informal phrase “for any ~A ∶ Set~ and ~a ∶ A~, we have ⋯”.\nThis is so [[https://people.inf.elte.hu/divip/AIMXXVIII.pdf][common]] that the ~variable~ keyword was introduced and it's [[https://agda.readthedocs.io/en/v2.6.0.1/language/generalization-of-declared-variables.html][clever]]:\nNames in ~⋯~ are functions of /only/ those ~variable~-s they actually mention.\n\n#+latex: \\begin{parallel}\n#+begin_example agda\n   module _ {A : Set} {a : A} ⋯\n≈\n   module T {A : Set} {a : A} ⋯\n   open T\n#+end_example\n#+latex: \\columnbreak\n#+begin_example agda\nvariable\n  A : Set\n  a : A\n⋯\n#+end_example\n#+latex: \\end{parallel} \\vspace{-1em}\n\n#+latex: \\columnbreak\nWhen opening a module, we can control which names are brought into scope with\nthe ~using, hiding,~ and ~renaming~ keywords.\n| ~open M hiding (𝓃₀; …; 𝓃ₖ)~               | Essentially treat ~𝓃ᵢ~ as private       |\n| ~open M using  (𝓃₀; …; 𝓃ₖ)~               | Essentially treat /only/ ~𝓃ᵢ~ as public |\n| ~open M renaming (𝓃₀ to 𝓂₀; …; 𝓃ₖ to 𝓂ₖ)~ | Use names ~𝓂ᵢ~ instead of ~𝓃ᵢ~          |\n\nSplitting a program over several files will improve type checking performance,\nsince when you are making changes the type checker only has to check the files\nthat are influenced by the change.\n- ~import X.Y.Z~: Use the definitions of module ~Z~ which lives in file ~./X/Y/Z.agda~.\n- ~open M public~: Treat the contents of ~M~ as if they were public contents of the current module.\n\n* Records\n\n#+latex: \\hspace{-1.3em}\nA record type is declared much like a datatype where the\nfields are indicated by the ~field~ keyword.\n\n| ~record~ | ≈ | ~module~ +  ~data~ with one constructor |\n\n#+latex: \\begin{parallel}\n#+begin_src agda\nrecord PointedSet : Set₁ where\n  constructor MkIt  {- Optional -}\n  field\n    Carrier : Set\n    point   : Carrier\n\n  {- It's like a module,\n  we can add derived definitions -}\n  blind : {A : Set} → A → Carrier\n  blind = λ a → point\n#+end_src\n#+latex: \\columnbreak\n#+begin_src agda\nex₀ : PointedSet\nex₀ = record {Carrier = ℕ; point = 3}\n\nex₁ : PointedSet\nex₁ = MkIt ℕ 3\n\nopen PointedSet\n\nex₂ : PointedSet\nCarrier ex₂ = ℕ\npoint   ex₂ = 3\n#+end_src\n#+latex: \\end{parallel} \\vspace{-1em}\n\nStart with ~ex₂ = ?~, then in the hole enter ~C-c C-c RET~\nto obtain the /co-pattern/ setup.\nTwo tuples are the same when they have the same components,\nlikewise a record is defined by its projections, whence /co-patterns/.\nIf you're using many local definitions, you likely want to use co-patterns!\n\nTo allow projection of the fields from a record, each record type comes\nwith a module of the same name. This module is parameterised by an element\nof the record type and contains projection functions for the fields.\n\n#+latex: \\begin{parallel}\n#+begin_src agda\nuse⁰ : ℕ\nuse⁰ = PointedSet.point ex₀\n#+end_src\n#+begin_example agda\n\nuse¹ : ℕ\nuse¹ = point where open PointedSet ex₀\n#+end_example\n\n#+begin_src agda\nopen PointedSet\n\nuse² : ℕ\nuse² = blind ex₀ true\n#+end_src\n#+latex: \\columnbreak\n\nYou can even pattern match on records\n\\\\\n---they're just ~data~ after all!\n#+latex: \\vspace{1em}\n#+begin_src agda\nuse³ : (P : PointedSet) → Carrier P\nuse³ record {Carrier = C; point = x}\n  = x\n\nuse⁴ : (P : PointedSet) → Carrier P\nuse⁴ (MkIt C x)\n  = x\n#+end_src\n#+latex: \\end{parallel} \\vspace{-1em}\n\n* Interacting with the real world ---Compilation, Haskell, and IO\n#+latex: {\\color{white}.} \\vspace{-1em}\n#+begin_quote\n/Let's demonstrate how we can reach into Haskell, thereby subverting Agda!/\n#+end_quote\n\nAn Agda program module containing a ~main~ function is compiled into a standalone executable\nwith ~agda --compile myfile.agda~. If the module has no main file, use the flag ~--no-main~.\nIf you only want the resulting Haskell, not necessarily an executable program, then use the flag\n~--ghc-dont-call-ghc~.\n\nThe type of ~main~ should be ~Agda.Builtin.IO.IO A~, for some ~A~;\nthis is just a proxy to Haskell's ~IO~.\nWe may ~open import IO.Primitive~ to get /this/ ~IO~, but\nthis one works with costrings, which are a bit awkward.\nInstead, we use the standard library's wrapper type, also named ~IO~.\nThen we use ~run~ to move from ~IO~ to ~Primitive.IO~; conversely one uses ~lift~.\n\n#+latex: \\begin{minipage}[c]{0.55\\linewidth}\n#+latex: \\begin{tiny}\n#+begin_src agda\nopen import Data.Nat                 using (ℕ; suc)\nopen import Data.Nat.Show            using (show)\nopen import Data.Char                using (Char)\nopen import Data.List as L           using (map; sum; upTo)\nopen import Function                 using (_$_; const; _∘_)\nopen import Data.String as S         using (String; _++_; fromList)\nopen import Agda.Builtin.Unit        using (⊤)\nopen import Codata.Musical.Colist    using (take)\nopen import Codata.Musical.Costring  using (Costring)\nopen import Data.BoundedVec.Inefficient as B using (toList)\nopen import Agda.Builtin.Coinduction using (♯_)\nopen import IO as IO                 using (run ; putStrLn ; IO)\nimport IO.Primitive as Primitive\n#+end_src\n#+latex: \\end{tiny}\n#+latex: \\end{minipage} % no space if you would like to put them side by side\n#+latex: \\begin{minipage}[c]{0.5\\linewidth}\n#+begin_quote\n/Agda has *no* primitives for side-effects, instead it allows arbitrary/\n/Haskell functions to be imported as axioms, whose definitions are only/\n/used at run-time./\n#+end_quote\n#+latex: \\end{minipage}\n\nAgda lets us use “do”-notation as in Haskell.\nTo do so, methods named ~_\u003e\u003e_~ and ~_\u003e\u003e=_~ need to be in scope ---that is all.\nThe type of ~IO._\u003e\u003e_~ takes two “lazy” IO actions and yield a non-lazy IO action.\nThe one below is a homogeneously typed version.\n\n#+begin_src agda\ninfixr 1 _\u003e\u003e=_ _\u003e\u003e_\n\n_\u003e\u003e=_ : ∀ {ℓ} {α β : Set ℓ} → IO α → (α → IO β) → IO β\nthis \u003e\u003e= f = ♯ this IO.\u003e\u003e= λ x → ♯ f x\n\n_\u003e\u003e_ : ∀{ℓ} {α β : Set ℓ} → IO α → IO β → IO β\nx \u003e\u003e y = x \u003e\u003e= const y\n#+end_src\n\nOddly, Agda's standard library comes with ~readFile~ and\n~writeFile~, but the symmetry ends there since it provides ~putStrLn~\nbut not [[https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html#v:getLine][~getLine~]]. Mimicking the ~IO.Primitive~ module, we define /two/\nversions ourselves as proxies for Haskell's ~getLine~ ---the second one\nbelow is bounded by 100 characters, whereas the first is not.\n\n#+begin_src agda\npostulate\n  getLine∞ : Primitive.IO Costring\n\n{-# FOREIGN GHC\n  toColist :: [a] -\u003e MAlonzo.Code.Codata.Musical.Colist.AgdaColist a\n  toColist []       = MAlonzo.Code.Codata.Musical.Colist.Nil\n  toColist (x : xs) =\n    MAlonzo.Code.Codata.Musical.Colist.Cons x (MAlonzo.RTE.Sharp (toColist xs))\n#-}\n\n{- Haskell's prelude is implicitly available; this is for demonstration. -}\n{-# FOREIGN GHC import Prelude as Haskell #-}\n{-# COMPILE GHC getLine∞  = fmap toColist Haskell.getLine #-}\n\n-- (1)\n-- getLine : IO Costring\n-- getLine = IO.lift getLine∞\n\ngetLine : IO String\ngetLine = IO.lift\n  $ getLine∞ Primitive.\u003e\u003e= (Primitive.return ∘ S.fromList ∘ B.toList ∘ take 100)\n#+end_src\nWe obtain ~MAlonzo~ strings, then convert those to colists, then\neventually lift those to the wrapper ~IO~ type.\n\nLet's also give ourselves Haskell's ~read~ method.\n#+begin_src agda\npostulate readInt  : L.List Char → ℕ\n{-# COMPILE GHC readInt = \\x -\u003e read x :: Integer  #-}\n#+end_src\n\nNow we write our ~main~ method.\n#+begin_src agda\nmain : Primitive.IO ⊤\nmain = run do putStrLn \"Hello, world! I'm a compiled Agda program!\"\n\n              putStrLn \"What is your name?\"\n              name ← getLine\n\n              putStrLn \"Please enter a number.\"\n              num ← getLine\n              let tri = show $ sum $ upTo $ suc $ readInt $ S.toList num\n              putStrLn $ \"The triangle number of \" ++ num ++ \" is \" ++ tri\n\n              putStrLn \"Bye, \"\n              -- IO.putStrLn∞ name  {- If we use approach (1) above. -}\n              putStrLn $ \"\\t\" ++ name\n#+end_src\nFor example, the $12^{th}$ [[https://en.wikipedia.org/wiki/Triangular_number][triangle number]] is $\\sum_{i=0}^{12} i = 78$.\nInterestingly, when an integer parse fails, the program just crashes!\nSuper cool dangerous stuff!\n\nCalling this file ~CompilingAgda.agda~, we may compile then run it with:\n#+begin_src shell :tangle no\nNAME=CompilingAgda; time agda --compile $NAME.agda; ./$NAME\n#+end_src\n\nThe very first time you compile may take ∼80 seconds since some prerequisites need to be compiled,\nbut future compilations are within ∼10 seconds.\n\nThe generated Haskell source lives under the newly created MAlonzo directory; namely\n~./MAlonzo/Code/CompilingAgda.hs~. Here's some fun: Write a parameterised module with multiple declarations,\nthen use those in your ~main~; inspect the generated Haskell to see that the module is thrown away in-preference\nto top-level functions ---as mentioned earlier.\n\n- When compiling you may see an error ~Could not find module ‘Numeric.IEEE’~.\n- Simply open a terminal and install the necessary Haskell library:\n  #+begin_src shell :tangle no\n  cabal install ieee754\n  #+end_src\n\n* Absurd Patterns\n\n#+latex: \\hspace{-1.3em}\nWhen there are no possible constructor patterns, we may match on the pattern ~()~\nand provide no right hand side ---since there is no way anyone could provide an argument\nto the function.\n\nFor example, here we define the datatype family of numbers smaller than a given natural number:\n~fzero~ is smaller than ~suc n~ for any ~n~, and if ~i~ is smaller than ~n~ then ~fsuc i~ is smaller\nthan ~suc n~.\n\n#+latex: \\begin{parallel}\n#+begin_src agda\n{- Fin n  ≅  numbers i with i \u003c n -}\ndata Fin : ℕ → Set where\n  fzero : {n : ℕ} → Fin (suc n)\n  fsuc  : {n : ℕ}\n        → Fin n → Fin (suc n)\n#+end_src\n#+latex: \\columnbreak\n\nFor each $n$, the type ~Fin n~ contains $n$ elements;\ne.g., ~Fin 2~ has elements ~fsuc fzero~ and ~fzero~,\nwhereas ~Fin 0~ has no elements at all.\n\n#+latex: \\end{parallel} \\vspace{-1em}\n\nUsing this type, we can write a safe indexing function that never “goes out of bounds”.\n#+begin_src agda\n\n_‼_ : {A : Set} {n : ℕ} → Vec A n → Fin n → A\n[] ‼ ()\n(x ∷ xs) ‼ fzero  = x\n(x ∷ xs) ‼ fsuc i = xs ‼ i\n#+end_src\n\nWhen we are given the empty list, ~[]~, then ~n~ is necessarily ~0~,\nbut there is no way to make an element of type ~Fin 0~ and so we have the absurd pattern.\nThat is, since the empty type ~Fin 0~ has no elements there is nothing to define\n---we have a definition by /no cases/.\n\nLogically [[https://en.wikipedia.org/wiki/Principle_of_explosion][“anything follows from false”]] becomes the following program:\n#+begin_src agda\ndata False : Set where\n\nmagic : {Anything-you-want : Set} → False → Anything-you-want\nmagic ()\n#+end_src\n\nStarting with ~magic x = ?~ then casing on ~x~ yields the program above\nsince there is no way to make an element of ~False~\n---we needn't bother with a result(ing right side), since there's no way to make\nan element of an empty type.\n\n** Preconditions as proof-object arguments\n\nSometimes it is not easy to capture a desired precondition in the types, and\nan alternative is to use the following ~isTrue~-approach of passing around\nexplicit proof objects.\n\n#+latex: \\begin{parallel}\n#+begin_src agda\n{- An empty record has only\n   one value: record {} -}\nrecord True : Set where\n\nisTrue : Bool → Set\nisTrue true  = True\nisTrue false = False\n#+end_src\n#+latex: \\columnbreak\n#+begin_src agda\n_\u003c₀_ : ℕ → ℕ → Bool\n_ \u003c₀ zero      = false\nzero \u003c₀ suc y  = true\nsuc x \u003c₀ suc y = x \u003c₀ y\n#+end_src\n#+latex: \\end{parallel} \\vspace{-1em}\n\n#+begin_src agda\nfind : {A : Set} (xs : List A) (i : ℕ) → isTrue (i \u003c₀ length xs) → A\nfind [] i ()\nfind (x ∷ xs) zero pf    = x\nfind (x ∷ xs) (suc i) pf = find xs i pf\n\nhead′ : {A : Set} (xs : List A) → isTrue (0 \u003c₀ length xs) → A\nhead′ [] ()\nhead′ (x ∷ xs) _ = x\n#+end_src\n\nUnlike the ~_‼_~ definition, rather than there being no index into the empty list,\nthere is no proof that a natural number ~i~ is smaller than 0.\n\n* Mechanically Moving from ~Bool~ to ~Set~ ---Avoiding “Boolean Blindness”\n\n#+latex: \\hspace{-1.3em}\nIn Agda we can represent a proposition as a type whose elements denote proofs\nof that proposition. Why would you want this? Recall how awkward it was to request\nan index be “in bounds” in the ~find~ method, but it's much easier to encode this\nusing ~Fin~ ---likewise, ~head′~ obtains a more elegant type when the non-empty precondition\nis part of the datatype definition, as in ~head~.\n\nHere is a simple recipe to go from Boolean functions to inductive datatype families.\n1. Write the Boolean function.\n2. Throw away all the cases with right side ~false~.\n3. Every case that has right side ~true~ corresponds to a new nullary constructor.\n4. Every case that has $n$ recursive calls corresponds to an ~n~-ary constructor.\n\nFollowing these steps for ~_\u003c₀_~, from the left side of the page, gives us:\n\n#+begin_src agda\ndata _\u003c₁_ : ℕ → ℕ → Set where\n  z\u003c : {y : ℕ} → zero \u003c₁ y\n  s\u003c : {x y : ℕ} → x \u003c₁ y → suc x \u003c₁ suc y\n#+end_src\n\nTo convince yourself you did this correctly, you can prove “soundness”\n---constructed values correspond to Boolean-true statements---\nand “completeness” ---true things correspond to terms formed from constructors.\nThe former is ensured by the second step in our recipe!\n\n#+begin_src agda\ncompleteness : {x y : ℕ} → isTrue (x \u003c₀ y) → x \u003c₁ y\ncompleteness {x}     {zero}  ()\ncompleteness {zero}  {suc y} p = z\u003c\ncompleteness {suc x} {suc y} p = s\u003c (completeness p)\n#+end_src\n\nWe began with ~completeness {x} {y} p = ?~, then we wanted to case on ~p~\nbut that requires evaluating ~x \u003c₀ y~ which requires we know the shapes of ~x~ and ~y~.\n/The shape of proofs usually mimics the shape of definitions they use/; e.g., ~_\u003c₀_~ here.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falhassy%2FAgdaCheatSheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falhassy%2FAgdaCheatSheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falhassy%2FAgdaCheatSheet/lists"}