on master help sign in
Merge pull request #2008 from jfdm/sphinx-doc

Sphinx Based Documentation for Idris.

commit6be29b3ecd0735e25ab0c74e2901e33568f6c27d authorDavid Christiansen <david@davidchristiansen.dk> dateFri 20 Mar 2015, 07:52 (12 years ago) parentb06f843ef50150
54 files changed+9363−4
Makefile+12−1 docs/.gitignore+3 docs/LICENSE+10 docs/Makefile+183 docs/README.md+39 docs/conf.py+357 docs/effects/conclusions.rst+76 docs/effects/depeff.rst+331 docs/effects/hangman.rst+334 docs/effects/impleff.rst+329 docs/effects/index.rst+28 docs/effects/introduction.rst+111 docs/effects/simpleeff.rst+602 docs/effects/state.rst+518 docs/effects/summary.rst+153 docs/guides/index.rst+21 docs/guides/type-providers-ffi.rst+290 docs/image/effects-tree.png docs/index.rst+84 docs/listing/idris-prompt-helloworld.txt+15 docs/listing/idris-prompt-interp.txt+12 docs/listing/idris-prompt-start.txt+8 docs/make.bat+263 docs/reference/documenting.rst+135 docs/reference/erasure.rst+501 docs/reference/ffi.rst+277 docs/reference/index.rst+26 docs/reference/uniqueness-types.rst+251 docs/tutorial/classes.rst+517 docs/tutorial/conclusions.rst+54 docs/tutorial/index.rst+33 docs/tutorial/interactive.rst+258 docs/tutorial/interp.rst+289 docs/tutorial/introduction.rst+69 docs/tutorial/miscellany.rst+546 docs/tutorial/modules.rst+222 docs/tutorial/provisional.rst+268 docs/tutorial/starting.rst+84 docs/tutorial/syntax.rst+208 docs/tutorial/theorems.rst+444 docs/tutorial/typesfuns.rst+1048 docs/tutorial/views.rst+98 samples/ConsoleIO.idr+15 samples/Exception.idr+21 samples/Makefile+2−2 samples/Random.idr+37 samples/ReadInt.idr+22 samples/Select.idr+17 samples/TreeTag-noeff.idr+21 samples/TreeTag.idr+40 samples/TreeTagCount.idr+29 samples/binary.idr+1−1 samples/hworld.idr+10 samples/vadd.idr+41
Makefile+12−1
@@ -1,4 +1,4 @@
1−.PHONY: build configure doc install linecount nodefault pinstall lib_clean relib test_c test lib_doc lib_doc_clean
1+.PHONY: build configure doc install linecount nodefault pinstall lib_clean relib test_c test lib_doc lib_doc_clean user_doc_html user_doc_pdf user_docs
22
33include config.mk
44-include custom.mk
@@ -55,5 +55,16 @@ lib_doc:
5555lib_doc_clean:
5656 $(MAKE) -C libs IDRIS=../../dist/build/idris/idris doc_clean
5757
58+user_docs: user_doc_html user_doc_pdf
59+
60+user_doc_clean:
61+ $(MAKE) -C docs clean
62+
63+user_doc_html:
64+ $(MAKE) -C docs html
65+
66+user_doc_pdf:
67+ $(MAKE) -C docs latexpdf
68+
5869dist/setup-config:
5970 $(CABAL) configure $(CABALFLAGS)
docs/.gitignorenew file+3
@@ -0,0 +1,3 @@
1+*~
2+UnicodeData.txt
3+_build/
docs/LICENSEnew file+10
@@ -0,0 +1,10 @@
1+#+TITLE: Licensing Information
2+
3+The documentation for Idris has been published under the Creative
4+Commons CC0 License. As such to the extent possible under law, /The
5+Idris Community/ has waived all copyright and related or neighboring
6+rights to Documentation for Idris.
7+
8+More information concerning the CC0 can be found online at:
9+
10+ http://creativecommons.org/publicdomain/zero/1.0/
docs/Makefilenew file+183
@@ -0,0 +1,183 @@
1+# Makefile for Sphinx documentation
2+#
3+
4+# You can set these variables from the command line.
5+SPHINXOPTS =
6+SPHINXBUILD = sphinx-build
7+PAPER =
8+BUILDDIR = _build
9+
10+# User-friendly check for sphinx-build
11+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13+endif
14+
15+# Internal variables.
16+PAPEROPT_a4 = -D latex_paper_size=a4
17+PAPEROPT_letter = -D latex_paper_size=letter
18+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19+# the i18n builder cannot share the environment and doctrees with the others
20+I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
21+
22+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
23+
24+help:
25+ @echo "Please use \`make <target>' where <target> is one of"
26+ @echo " html to make standalone HTML files"
27+ @echo " dirhtml to make HTML files named index.html in directories"
28+ @echo " singlehtml to make a single large HTML file"
29+ @echo " pickle to make pickle files"
30+ @echo " json to make JSON files"
31+ @echo " htmlhelp to make HTML files and a HTML help project"
32+ @echo " qthelp to make HTML files and a qthelp project"
33+ @echo " devhelp to make HTML files and a Devhelp project"
34+ @echo " epub to make an epub"
35+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
36+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
37+ @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
38+ @echo " text to make text files"
39+ @echo " man to make manual pages"
40+ @echo " texinfo to make Texinfo files"
41+ @echo " info to make Texinfo files and run them through makeinfo"
42+ @echo " gettext to make PO message catalogs"
43+ @echo " changes to make an overview of all changed/added/deprecated items"
44+ @echo " xml to make Docutils-native XML files"
45+ @echo " pseudoxml to make pseudoxml-XML files for display purposes"
46+ @echo " linkcheck to check all external links for integrity"
47+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
48+ @echo " coverage to run coverage check of the documentation (if enabled)"
49+
50+clean:
51+ rm -rf $(BUILDDIR)/*
52+
53+html:
54+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
55+ @echo
56+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
57+
58+dirhtml:
59+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
60+ @echo
61+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
62+
63+singlehtml:
64+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
65+ @echo
66+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
67+
68+pickle:
69+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
70+ @echo
71+ @echo "Build finished; now you can process the pickle files."
72+
73+json:
74+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
75+ @echo
76+ @echo "Build finished; now you can process the JSON files."
77+
78+htmlhelp:
79+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
80+ @echo
81+ @echo "Build finished; now you can run HTML Help Workshop with the" \
82+ ".hhp project file in $(BUILDDIR)/htmlhelp."
83+
84+qthelp:
85+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
86+ @echo
87+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
88+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
89+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/IdrisManual.qhcp"
90+ @echo "To view the help file:"
91+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/IdrisManual.qhc"
92+
93+devhelp:
94+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
95+ @echo
96+ @echo "Build finished."
97+ @echo "To view the help file:"
98+ @echo "# mkdir -p $$HOME/.local/share/devhelp/IdrisManual"
99+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/IdrisManual"
100+ @echo "# devhelp"
101+
102+epub:
103+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
104+ @echo
105+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
106+
107+latex:
108+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
109+ @echo
110+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
111+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
112+ "(use \`make latexpdf' here to do that automatically)."
113+
114+latexpdf:
115+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
116+ @echo "Running LaTeX files through pdflatex..."
117+ $(MAKE) -C $(BUILDDIR)/latex all-pdf
118+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
119+
120+latexpdfja:
121+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
122+ @echo "Running LaTeX files through platex and dvipdfmx..."
123+ $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
124+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
125+
126+text:
127+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
128+ @echo
129+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
130+
131+man:
132+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
133+ @echo
134+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
135+
136+texinfo:
137+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
138+ @echo
139+ @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
140+ @echo "Run \`make' in that directory to run these through makeinfo" \
141+ "(use \`make info' here to do that automatically)."
142+
143+info:
144+ $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
145+ @echo "Running Texinfo files through makeinfo..."
146+ make -C $(BUILDDIR)/texinfo info
147+ @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
148+
149+gettext:
150+ $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
151+ @echo
152+ @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
153+
154+changes:
155+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
156+ @echo
157+ @echo "The overview file is in $(BUILDDIR)/changes."
158+
159+linkcheck:
160+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
161+ @echo
162+ @echo "Link check complete; look for any errors in the above output " \
163+ "or in $(BUILDDIR)/linkcheck/output.txt."
164+
165+doctest:
166+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
167+ @echo "Testing of doctests in the sources finished, look at the " \
168+ "results in $(BUILDDIR)/doctest/output.txt."
169+
170+coverage:
171+ $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
172+ @echo "Testing of coverage in the sources finished, look at the " \
173+ "results in $(BUILDDIR)/coverage/python.txt."
174+
175+xml:
176+ $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
177+ @echo
178+ @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
179+
180+pseudoxml:
181+ $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
182+ @echo
183+ @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
docs/README.mdnew file+39
@@ -0,0 +1,39 @@
1+# Documentation for the Idris Language.
2+
3+
4+This manual has been prepared using ReStructured Text and the [Sphinx Documentation Generator](http://sphinx-doc.org) for future inclusion on [Read The Docs](http://www.readthedocs.org).
5+
6+## Dependencies
7+
8+To build the manual the following dependencies must be met. We assume that you have standard build automation tools already install i.e. `make`.
9+
10+### Sphinx-Doc
11+
12+Python should be installed by default on most systems.
13+Sphinx can be installed wither through your hosts package manager or using pip/easy_install.
14+
15+### LaTeX
16+
17+LaTeX can be install either using your systems package manager or direct from TeXLive.
18+
19+
20+## Build Instructions
21+
22+```sh
23+make html
24+make latexpdf
25+```
26+
27+## Contributing
28+
29+The documentation for Idris has been published under the Creative
30+Commons CC0 License. As such to the extent possible under law, /The
31+Idris Community/ has waived all copyright and related or neighboring
32+rights to Documentation for Idris.
33+
34+More information concerning the CC0 can be found online at:
35+
36+ http://creativecommons.org/publicdomain/zero/1.0/
37+
38+
39+When contributing material to the manual please bear in mind that the work will be licensed as above.
docs/conf.pynew file+357
@@ -0,0 +1,357 @@
1+# -*- coding: utf-8 -*-
2+#
3+# Idris Manual documentation build configuration file, created by
4+# sphinx-quickstart on Sat Feb 28 20:41:47 2015.
5+#
6+# This file is execfile()d with the current directory set to its
7+# containing dir.
8+#
9+# Note that not all possible configuration values are present in this
10+# autogenerated file.
11+#
12+# All configuration values have a default; values that are commented out
13+# serve to show the default.
14+
15+import sys
16+import os
17+
18+# If extensions (or modules to document with autodoc) are in another directory,
19+# add these directories to sys.path here. If the directory is relative to the
20+# documentation root, use os.path.abspath to make it absolute, like shown here.
21+#sys.path.insert(0, os.path.abspath('.'))
22+
23+# -- General configuration ------------------------------------------------
24+
25+# If your documentation needs a minimal Sphinx version, state it here.
26+#needs_sphinx = '1.0'
27+
28+# Add any Sphinx extension module names here, as strings. They can be
29+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
30+# ones.
31+extensions = [
32+ 'sphinx.ext.todo',
33+ 'sphinx.ext.pngmath',
34+ 'sphinx.ext.ifconfig',
35+]
36+
37+# Add any paths that contain templates here, relative to this directory.
38+templates_path = ['_templates']
39+
40+# The suffix of source filenames.
41+source_suffix = '.rst'
42+
43+# The encoding of source files.
44+#source_encoding = 'utf-8-sig'
45+
46+# The master toctree document.
47+master_doc = 'index'
48+
49+# General information about the project.
50+project = u'Idris'
51+copyright = u'2015, The Idris Community'
52+author = u'The Idris Community'
53+
54+# The version info for the project you're documenting, acts as replacement for
55+# |version| and |release|, also used in various other places throughout the
56+# built documents.
57+#
58+# The short X.Y version.
59+version = '0.9.17'
60+# The full version, including alpha/beta/rc tags.
61+release = '0.9.17'
62+
63+# The language for content autogenerated by Sphinx. Refer to documentation
64+# for a list of supported languages.
65+#
66+# This is also used if you do content translation via gettext catalogs.
67+# Usually you set "language" from the command line for these cases.
68+language = None
69+
70+# There are two options for replacing |today|: either, you set today to some
71+# non-false value, then it is used:
72+#today = ''
73+# Else, today_fmt is used as the format for a strftime call.
74+#today_fmt = '%B %d, %Y'
75+
76+# List of patterns, relative to source directory, that match files and
77+# directories to ignore when looking for source files.
78+exclude_patterns = ['_build']
79+
80+# The reST default role (used for this markup: `text`) to use for all
81+# documents.
82+#default_role = None
83+
84+# If true, '()' will be appended to :func: etc. cross-reference text.
85+#add_function_parentheses = True
86+
87+# If true, the current module name will be prepended to all description
88+# unit titles (such as .. function::).
89+#add_module_names = True
90+
91+# If true, sectionauthor and moduleauthor directives will be shown in the
92+# output. They are ignored by default.
93+#show_authors = False
94+
95+# The name of the Pygments (syntax highlighting) style to use.
96+pygments_style = 'sphinx'
97+
98+# A list of ignored prefixes for module index sorting.
99+#modindex_common_prefix = []
100+
101+# If true, keep warnings as "system message" paragraphs in the built documents.
102+#keep_warnings = False
103+
104+# If true, `todo` and `todoList` produce output, else they produce nothing.
105+todo_include_todos = True
106+
107+
108+# -- Options for HTML output ----------------------------------------------
109+
110+# The theme to use for HTML and HTML Help pages. See the documentation for
111+# a list of builtin themes.
112+html_theme = "alabaster"
113+
114+# Theme options are theme-specific and customize the look and feel of a theme
115+# further. For a list of options available for each theme, see the
116+# documentation.
117+#html_theme_options = {}
118+
119+# Add any paths that contain custom themes here, relative to this directory.
120+#html_theme_path = []
121+
122+# The name for this set of Sphinx documents. If None, it defaults to
123+# "<project> v<release> documentation".
124+#html_title = None
125+
126+# A shorter title for the navigation bar. Default is the same as html_title.
127+#html_short_title = None
128+
129+# The name of an image file (relative to this directory) to place at the top
130+# of the sidebar.
131+#html_logo = None
132+
133+# The name of an image file (within the static path) to use as favicon of the
134+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
135+# pixels large.
136+#html_favicon = None
137+
138+# Add any paths that contain custom static files (such as style sheets) here,
139+# relative to this directory. They are copied after the builtin static files,
140+# so a file named "default.css" will overwrite the builtin "default.css".
141+html_static_path = ['_static']
142+
143+# Add any extra paths that contain custom files (such as robots.txt or
144+# .htaccess) here, relative to this directory. These files are copied
145+# directly to the root of the documentation.
146+#html_extra_path = []
147+
148+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
149+# using the given strftime format.
150+#html_last_updated_fmt = '%b %d, %Y'
151+
152+# If true, SmartyPants will be used to convert quotes and dashes to
153+# typographically correct entities.
154+#html_use_smartypants = True
155+
156+# Custom sidebar templates, maps document names to template names.
157+#html_sidebars = {}
158+
159+# Additional templates that should be rendered to pages, maps page names to
160+# template names.
161+#html_additional_pages = {}
162+
163+# If false, no module index is generated.
164+#html_domain_indices = True
165+
166+# If false, no index is generated.
167+#html_use_index = True
168+
169+# If true, the index is split into individual pages for each letter.
170+#html_split_index = False
171+
172+# If true, links to the reST sources are added to the pages.
173+#html_show_sourcelink = True
174+
175+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
176+#html_show_sphinx = True
177+
178+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
179+#html_show_copyright = True
180+
181+# If true, an OpenSearch description file will be output, and all pages will
182+# contain a <link> tag referring to it. The value of this option must be the
183+# base URL from which the finished HTML is served.
184+#html_use_opensearch = ''
185+
186+# This is the file name suffix for HTML files (e.g. ".xhtml").
187+#html_file_suffix = None
188+
189+# Language to be used for generating the HTML full-text search index.
190+# Sphinx supports the following languages:
191+# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
192+# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
193+#html_search_language = 'en'
194+
195+# A dictionary with options for the search language support, empty by default.
196+# Now only 'ja' uses this config value
197+#html_search_options = {'type': 'default'}
198+
199+# The name of a javascript file (relative to the configuration directory) that
200+# implements a search results scorer. If empty, the default will be used.
201+#html_search_scorer = 'scorer.js'
202+
203+# Output file base name for HTML help builder.
204+htmlhelp_basename = 'IdrisManualdoc'
205+
206+# -- Options for LaTeX output ---------------------------------------------
207+
208+latex_elements = {
209+# The paper size ('letterpaper' or 'a4paper').
210+'papersize': 'a4paper',
211+
212+# The font size ('10pt', '11pt' or '12pt').
213+'pointsize': '10pt',
214+
215+# Additional stuff for the LaTeX preamble.
216+#'preamble': '',
217+
218+# Latex figure (float) alignment
219+#'figure_align': 'htbp',
220+}
221+
222+# Grouping the document tree into LaTeX files. List of tuples
223+# (source start file, target name, title,
224+# author, documentclass [howto, manual, or own class]).
225+latex_documents = [
226+ ('guides/index', 'idris-guides.tex', u'Idris Tutorial Series', u'The Idris Community', 'manual'),
227+ ('reference/index', 'idris-reference.tex', u'The Idris Reference', u'The Idris Community', 'manual'),
228+ ('tutorial/index', 'idris-tutorial.tex', u'The Idris Tutorial', u'The Idris Community', 'manual'),
229+ ('effects/index', 'eff-tutorial.tex', u'The Effects Tutorial', u'The Idris Community', 'manual')
230+ ]
231+
232+# The name of an image file (relative to this directory) to place at the top of
233+# the title page.
234+#latex_logo = None
235+
236+# For "manual" documents, if this is true, then toplevel headings are parts,
237+# not chapters.
238+#latex_use_parts = True
239+
240+# If true, show page references after internal links.
241+#latex_show_pagerefs = False
242+
243+# If true, show URL addresses after external links.
244+#latex_show_urls = False
245+
246+# Documents to append as an appendix to all manuals.
247+#latex_appendices = []
248+
249+# If false, no module index is generated.
250+#latex_domain_indices = True
251+
252+
253+# -- Options for manual page output ---------------------------------------
254+
255+# One entry per manual page. List of tuples
256+# (source start file, name, description, authors, manual section).
257+man_pages = [
258+ (master_doc, 'idrismanual', u'Idris Manual Documentation',
259+ [author], 1)
260+]
261+
262+# If true, show URL addresses after external links.
263+#man_show_urls = False
264+
265+
266+# -- Options for Texinfo output -------------------------------------------
267+
268+# Grouping the document tree into Texinfo files. List of tuples
269+# (source start file, target name, title, author,
270+# dir menu entry, description, category)
271+texinfo_documents = [
272+ (master_doc, 'IdrisManual', u'Idris Manual Documentation',
273+ author, 'IdrisManual', 'One line description of project.',
274+ 'Miscellaneous'),
275+]
276+
277+# Documents to append as an appendix to all manuals.
278+#texinfo_appendices = []
279+
280+# If false, no module index is generated.
281+#texinfo_domain_indices = True
282+
283+# How to display URL addresses: 'footnote', 'no', or 'inline'.
284+#texinfo_show_urls = 'footnote'
285+
286+# If true, do not generate a @detailmenu in the "Top" node's menu.
287+#texinfo_no_detailmenu = False
288+
289+
290+# -- Options for Epub output ----------------------------------------------
291+
292+# Bibliographic Dublin Core info.
293+epub_title = project
294+epub_author = author
295+epub_publisher = author
296+epub_copyright = copyright
297+
298+# The basename for the epub file. It defaults to the project name.
299+#epub_basename = project
300+
301+# The HTML theme for the epub output. Since the default themes are not optimized
302+# for small screen space, using the same theme for HTML and epub output is
303+# usually not wise. This defaults to 'epub', a theme designed to save visual
304+# space.
305+#epub_theme = 'epub'
306+
307+# The language of the text. It defaults to the language option
308+# or 'en' if the language is not set.
309+#epub_language = ''
310+
311+# The scheme of the identifier. Typical schemes are ISBN or URL.
312+#epub_scheme = ''
313+
314+# The unique identifier of the text. This can be a ISBN number
315+# or the project homepage.
316+#epub_identifier = ''
317+
318+# A unique identification for the text.
319+#epub_uid = ''
320+
321+# A tuple containing the cover image and cover page html template filenames.
322+#epub_cover = ()
323+
324+# A sequence of (type, uri, title) tuples for the guide element of content.opf.
325+#epub_guide = ()
326+
327+# HTML files that should be inserted before the pages created by sphinx.
328+# The format is a list of tuples containing the path and title.
329+#epub_pre_files = []
330+
331+# HTML files shat should be inserted after the pages created by sphinx.
332+# The format is a list of tuples containing the path and title.
333+#epub_post_files = []
334+
335+# A list of files that should not be packed into the epub file.
336+epub_exclude_files = ['search.html']
337+
338+# The depth of the table of contents in toc.ncx.
339+#epub_tocdepth = 3
340+
341+# Allow duplicate toc entries.
342+#epub_tocdup = True
343+
344+# Choose between 'default' and 'includehidden'.
345+#epub_tocscope = 'default'
346+
347+# Fix unsupported image types using the Pillow.
348+#epub_fix_images = False
349+
350+# Scale large images.
351+#epub_max_image_width = 0
352+
353+# How to display URL addresses: 'footnote', 'no', or 'inline'.
354+#epub_show_urls = 'inline'
355+
356+# If false, no index is generated.
357+#epub_use_index = True
docs/effects/conclusions.rstnew file+76
@@ -0,0 +1,76 @@
1+.. _sect-further:
2+
3+===============
4+Further Reading
5+===============
6+
7+This tutorial has given an introduction to writing and reasoning about
8+side-effecting programs in ``Idris``, using the ``Effects`` library.
9+More details about the *implementation* of the library, such as how
10+``run`` works, how handlers are invoked, etc, are given in a separate
11+paper [1]_.
12+
13+Some libraries and programs which use ``Effects`` can be found in the
14+following places:
15+
16+- http://github.com/edwinb/SDL-idris — some bindings for the SDL media
17+ library, supporting graphics in particular.
18+
19+- http://github.com/edwinb/idris-demos — various demonstration
20+ programs, including several examples from this tutorial, and a “Space
21+ Invaders” game.
22+
23+- https://github.com/SimonJF/IdrisNet2 — networking and socket
24+ libraries.
25+
26+- http://github.com/edwinb/Protocols — a high level communication
27+ protocol description language.
28+
29+The inspiration for the ``Effects`` library was Bauer and Pretnar’s
30+Eff language [2]_, which describes a langauge based on algebraic
31+effects and handlers. Other recent languages and libraries have also
32+been built on this ideas, for example [3]_ and [4]_. The theoretical
33+foundations are also well-studied see [5]_, [6]_, [7]_, [8]_.
34+
35+
36+
37+.. [1] Edwin Brady. 2013. Programming and reasoning with algebraic
38+ effects and dependent types. SIGPLAN Not. 48, 9 (September
39+ 2013), 133-144. DOI=10.1145/2544174.2500581
40+ http://doi.acm.org/10.1145/2544174.2500581
41+
42+.. [2] Andrej Bauer, Matija Pretnar, Programming with algebraic
43+ effects and handlers, Journal of Logical and Algebraic Methods
44+ in Programming, Volume 84, Issue 1, January 2015, Pages
45+ 108-123, ISSN 2352-2208,
46+ http://dx.doi.org/10.1016/j.jlamp.2014.02.001.
47+ (http://www.sciencedirect.com/science/article/pii/S2352220814000194)
48+
49+.. [3] Ben Lippmeier. 2009. Witnessing Purity, Constancy and
50+ Mutability. In Proceedings of the 7th Asian Symposium on
51+ Programming Languages and Systems (APLAS '09), Zhenjiang Hu
52+ (Ed.). Springer-Verlag, Berlin, Heidelberg,
53+ 95-110. DOI=10.1007/978-3-642-10672-9_9
54+ http://dx.doi.org/10.1007/978-3-642-10672-9_9
55+
56+.. [4] Ohad Kammar, Sam Lindley, and Nicolas Oury. 2013. Handlers in
57+ action. SIGPLAN Not. 48, 9 (September 2013),
58+ 145-158. DOI=10.1145/2544174.2500590
59+ http://doi.acm.org/10.1145/2544174.2500590
60+
61+.. [5] Martin Hyland, Gordon Plotkin, John Power, Combining effects:
62+ Sum and tensor, Theoretical Computer Science, Volume 357,
63+ Issues 1–3, 25 July 2006, Pages 70-99, ISSN 0304-3975,
64+ http://dx.doi.org/10.1016/j.tcs.2006.03.013.
65+ (http://www.sciencedirect.com/science/article/pii/S0304397506002659)
66+
67+.. [6] Paul Blain Levy. 2004. Call-By-Push-Value: A
68+ Functional/Imperative Synthesis (Semantics Structures in
69+ Computation, V. 2). Kluwer Academic Publishers, Norwell, MA,
70+ USA.
71+
72+.. [7] Plotkin, Gordon, and Matija Pretnar. "Handlers of algebraic
73+ effects." Programming Languages and Systems. Springer Berlin
74+ Heidelberg, 2009. 80-94.
75+
76+.. [8] Pretnar, Matija. "Logic and handling of algebraic effects." (2010).
docs/effects/depeff.rstnew file+331
@@ -0,0 +1,331 @@
1+.. _sect-depeff:
2+
3+=================
4+Dependent Effects
5+=================
6+
7+In the programs we have seen so far, the available effects have remained
8+constant. Sometimes, however, an operation can *change* the available
9+effects. The simplest example occurs when we have a state with a
10+dependent type—adding an element to a vector also changes its type, for
11+example, since its length is explicit in the type. In this section, we
12+will see how the library supports this. Firstly, we will see how states
13+with dependent types can be implemented. Secondly, we will see how the
14+effects can depend on the *result* of an effectful operation. Finally,
15+we will see how this can be used to implement a type-safe and
16+resource-safe protocol for file management.
17+
18+Dependent States
19+----------------
20+
21+Suppose we have a function which reads input from the console, converts
22+it to an integer, and adds it to a list which is stored in a ``STATE``.
23+It might look something like the following:
24+
25+.. code-block:: idris
26+
27+ readInt : { [STATE (List Int), STDIO] } Eff ()
28+ readInt = do let x = trim !getStr
29+ put (cast x :: !get)
30+
31+But what if, instead of a list of integers, we would like to store a
32+``Vect``, maintaining the length in the type?
33+
34+.. code-block:: idris
35+
36+ readInt : { [STATE (Vect n Int), STDIO] } Eff ()
37+ readInt = do let x = trim !getStr
38+ put (cast x :: !get)
39+
40+This will not type check! Although the vector has length ``n`` on entry
41+to ``readInt``, it has length ``S n`` on exit. The library allows us to
42+express this as follows:
43+
44+.. code-block:: idris
45+
46+ readInt : { [STATE (Vect n Int), STDIO] ==>
47+ [STATE (Vect (S n) Int), STDIO] } Eff ()
48+ readInt = do let x = trim !getStr
49+ putM (cast x :: !get)
50+
51+The notation ``{ xs ==> xs’ } Eff a`` in a type means that the operation
52+begins with effects ``xs`` available, and ends with effects ``xs’``
53+available. We have used ``putM`` to update the state, where the ``M``
54+suffix indicates that the *type* is being updated as well as the value.
55+It has the following type:
56+
57+.. code-block:: idris
58+
59+ putM : y -> { [STATE x] ==> [STATE y] } Eff ()
60+
61+Result-dependent Effects
62+------------------------
63+
64+Often, whether a state is updated could depend on the success or
65+otherwise of an operation. In our ``readInt`` example, we might wish to
66+update the vector only if the input is a valid integer (i.e. all
67+digits). As a first attempt, we could try the following, returning a
68+``Bool`` which indicates success:
69+
70+.. code-block:: idris
71+
72+ readInt : { [STATE (Vect n Int), STDIO] ==>
73+ [STATE (Vect (S n) Int), STDIO] } Eff Bool
74+ readInt = do let x = trim !getStr
75+ case all isDigit (unpack x) of
76+ False => pure False
77+ True => do putM (cast x :: !get)
78+ pure True
79+
80+Unfortunately, this will not type check because the vector does not get
81+extended in both branches of the ``case``!
82+
83+::
84+
85+ MutState.idr:18:19:When elaborating right hand side of Main.case
86+ block in readInt:
87+ Unifying n and S n would lead to infinite value
88+
89+Clearly, the size of the resulting vector depends on whether or not the
90+value read from the user was valid. We can express this in the type:
91+
92+.. code-block:: idris
93+
94+ readInt : { [STATE (Vect n Int), STDIO] ==>
95+ {ok} if ok then [STATE (Vect (S n) Int), STDIO]
96+ else [STATE (Vect n Int), STDIO] } Eff Bool
97+ readInt = do let x = trim !getStr
98+ case all isDigit (unpack x) of
99+ False => pure False
100+ True => do putM (cast x :: !get)
101+ pure True
102+
103+The notation ``{ xs ==> res xs’ } Eff a`` in a type means that the
104+effects available are updated from ``xs`` to ``xs’``, *and* the
105+resulting effects ``xs’`` may depend on the result of the operation
106+``res``, of type ``a``. Here, the resulting effects are computed from
107+the result ``ok``—if ``True``, the vector is extended, otherwise it
108+remains the same.
109+
110+When using the function, we will naturally have to check its return
111+value in order to know what the new set of effects is. For example, to
112+read a set number of values into a vector, we could write the following:
113+
114+.. code-block:: idris
115+
116+ readN : (n : Nat) ->
117+ { [STATE (Vect m Int), STDIO] ==>
118+ [STATE (Vect (n + m) Int), STDIO] } Eff ()
119+ readN Z = pure ()
120+ readN {m} (S k) = case !readInt of
121+ True => rewrite plusSuccRightSucc k m in readN k
122+ False => readN (S k)
123+
124+The ``case`` analysis on the result of ``readInt`` means that we know in
125+each branch whether reading the integer succeeded, and therefore how
126+many values still need to be read into the vector. What this means in
127+practice is that the type system has verified that a necessary dynamic
128+check (i.e. whether reading a value succeeded) has indeed been done.
129+
130+.. note::
131+ Only ``case`` will work here. We cannot use ``if/then/else``
132+ because the ``then`` and ``else`` branches must have the same
133+ type. The ``case`` construct, however, abstracts over the value
134+ being inspected in the type of each branch.
135+
136+File Management
137+---------------
138+
139+A practical use for dependent effects is in specifying resource usage
140+protocols and verifying that they are executed correctly. For example,
141+file management follows a resource usage protocol with the following
142+(informally specified) requirements:
143+
144+- It is necessary to open a file for reading before reading it
145+
146+- Opening may fail, so the programmer should check whether opening was
147+ successful
148+
149+- A file which is open for reading must not be written to, and vice
150+ versa
151+
152+- When finished, an open file handle should be closed
153+
154+- When a file is closed, its handle should no longer be used
155+
156+These requirements can be expressed formally in , by creating a
157+``FILE_IO`` effect parameterised over a file handle state, which is
158+either empty, open for reading, or open for writing. The ``FILE_IO``
159+effect’s definition is given in Listing :ref:`eff-fileio`. Note that this
160+effect is mainly for illustrative purposes—typically we would also like
161+to support random access files and better reporting of error conditions.
162+
163+.. _eff-fileio:
164+.. code-block:: idris
165+ :caption: File I/O Effect
166+
167+ module Effect.File
168+
169+ import Effects
170+ import Control.IOExcept
171+
172+ FILE_IO : Type -> EFFECT
173+
174+ data OpenFile : Mode -> Type
175+
176+ open : String -> (m : Mode) ->
177+ { [FILE_IO ()] ==>
178+ {ok} [FILE_IO (if ok then OpenFile m else ())] } Eff Bool
179+ close : { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff ()
180+
181+ readLine : { [FILE_IO (OpenFile Read)] } Eff String
182+ writeLine : { [FILE_IO (OpenFile Write)] } Eff ()
183+ eof : { [FILE_IO (OpenFile Read)] } Eff Bool
184+
185+ instance Handler FileIO IO
186+
187+In particular, consider the type of ``open``:
188+
189+.. code-block:: idris
190+
191+ open : String -> (m : Mode) ->
192+ { [FILE_IO ()] ==>
193+ {ok} [FILE_IO (if ok then OpenFile m else ())] } Eff Bool
194+
195+This returns a ``Bool`` which indicates whether opening the file was
196+successful. The resulting state depends on whether the operation was
197+successful; if so, we have a file handle open for the stated purpose,
198+and if not, we have no file handle. By ``case`` analysis on the result,
199+we continue the protocol accordingly.
200+
201+.. _eff-readfile:
202+.. code-block:: idris
203+ :caption: Reading a File
204+
205+ readFile : { [FILE_IO (OpenFile Read)] } Eff (List String)
206+ readFile = readAcc [] where
207+ readAcc : List String -> { [FILE_IO (OpenFile Read)] }
208+ Eff (List String)
209+ readAcc acc = if (not !eof)
210+ then readAcc (!readLine :: acc)
211+ else pure (reverse acc)
212+
213+Given a function ``readFile`` (Listing :ref:`eff-readfile`) which reads from
214+an open file until reaching the end, we can write a program which opens
215+a file, reads it, then displays the contents and closes it, as follows,
216+correctly following the protocol:
217+
218+.. code-block:: idris
219+
220+ dumpFile : String -> { [FILE_IO (), STDIO] } Eff ()
221+ dumpFile name = case !(open name Read) of
222+ True => do putStrLn (show !readFile)
223+ close
224+ False => putStrLn ("Error!")
225+
226+The type of ``dumpFile``, with ``FILE_IO ()`` in its effect list,
227+indicates that any use of the file resource will follow the protocol
228+correctly (i.e. it both begins and ends with an empty resource). If we
229+fail to follow the protocol correctly (perhaps by forgetting to close
230+the file, failing to check that ``open`` succeeded, or opening the file
231+for writing) then we will get a compile-time error. For example,
232+changing ``open name Read`` to ``open name Write`` yields a compile-time
233+error of the following form:
234+
235+::
236+
237+ FileTest.idr:16:18:When elaborating right hand side of Main.case
238+ block in testFile:
239+ Can't solve goal
240+ SubList [(FILE_IO (OpenFile Read))]
241+ [(FILE_IO (OpenFile Write)), STDIO]
242+
243+In other words: when reading a file, we need a file which is open for
244+reading, but the effect list contains a ``FILE_IO`` effect carrying a
245+file open for writing.
246+
247+Pattern-matching bind
248+---------------------
249+
250+It might seem that having to test each potentially failing operation
251+with a ``case`` clause could lead to ugly code, with lots of
252+nested case blocks. Many languages support exceptions to improve this,
253+but unfortunately exceptions may not allow completely clean resource
254+management—for example, guaranteeing that any ``open`` which did succeed
255+has a corresponding close.
256+
257+Idris supports *pattern-matching* bindings, such as the following:
258+
259+.. code-block:: idris
260+
261+ dumpFile : String -> { [FILE_IO (), STDIO] } Eff ()
262+ dumpFile name = do True <- open name Read
263+ putStrLn (show !readFile)
264+ close
265+
266+This also has a problem: we are no longer dealing with the case where
267+opening a file failed! The solution is to extend the pattern-matching
268+binding syntax to give brief clauses for failing matches. Here, for
269+example, we could write:
270+
271+.. code-block:: idris
272+
273+ dumpFile : String -> { [FILE_IO (), STDIO] } Eff ()
274+ dumpFile name = do True <- open name Read | False => putStrLn "Error"
275+ putStrLn (show !readFile)
276+ close
277+
278+This is exactly equivalent to the definition with the explicit ``case``.
279+In general, in a ``do``-block, the syntax:
280+
281+.. code-block:: idris
282+
283+ do pat <- val | <alternatives>
284+ p
285+
286+is desugared to
287+
288+.. code-block:: idris
289+
290+ do x <- val
291+ case x of
292+ pat => p
293+ <alternatives>
294+
295+There can be several ``alternatives``, separated by a vertical bar
296+``|``. For example, there is a ``SYSTEM`` effect which supports
297+reading command line arguments, among other things (see Appendix
298+:ref:`sect-appendix`). To read command line arguments, we can use
299+``getArgs``:
300+
301+.. code-block:: idris
302+
303+ getArgs : { [SYSTEM] } Eff (List String)
304+
305+A main program can read command line arguments as follows, where in the
306+list which is returned, the first element ``prog`` is the executable
307+name and the second is an expected argument:
308+
309+.. code-block:: idris
310+
311+ emain : { [SYSTEM, STDIO] } Eff ()
312+ emain = do [prog, arg] <- getArgs
313+ putStrLn $ "Argument is " ++ arg
314+ {- ... rest of function ... -}
315+
316+Unfortunately, this will not fail gracefully if no argument is given, or
317+if too many arguments are given. We can use pattern matching bind
318+alternatives to give a better (more informative) error:
319+
320+.. code-block:: idris
321+
322+ emain : { [SYSTEM, STDIO] } Eff ()
323+ emain = do [prog, arg] <- getArgs | [] => putStrLn "Can't happen!"
324+ | [prog] => putStrLn "No arguments!"
325+ | _ => putStrLn "Too many arguments!"
326+ putStrLn $ "Argument is " ++ arg
327+ {- ... rest of function ... -}
328+
329+If ``getArgs`` does not return something of the form ``[prog, arg]`` the
330+alternative which does match is executed instead, and that value
331+returned.
docs/effects/hangman.rstnew file+334
@@ -0,0 +1,334 @@
1+.. _sect-hangman:
2+
3+=======================================
4+Example: A “Mystery Word” Guessing Game
5+=======================================
6+
7+In this section, we will use the techniques and specific effects
8+discussed in the tutorial so far to implement a larger example, a simple
9+text-based word-guessing game. In the game, the computer chooses a word,
10+which the player must guess letter by letter. After a limited number of
11+wrong guesses, the player loses [1]_.
12+
13+We will implement the game by following these steps:
14+
15+#. Define the game state, in enough detail to express the rules
16+
17+#. Define the rules of the game (i.e. what actions the player may take,
18+ and how these actions affect the game state)
19+
20+#. Implement the rules of the game (i.e. implement state updates for
21+ each action)
22+
23+#. Implement a user interface which allows a player to direct actions
24+
25+Step 2 may be achieved by defining an effect which depends on the state
26+defined in step 1. Then step 3 involves implementing a ``Handler`` for
27+this effect. Finally, step 4 involves implementing a program in ``Eff``
28+using the newly defined effect (and any others required to implement the
29+interface).
30+
31+Step 1: Game State
32+------------------
33+
34+First, we categorise the game states as running games (where there are a
35+number of guesses available, and a number of letters still to guess), or
36+non-running games (i.e. games which have not been started, or games
37+which have been won or lost).
38+
39+.. code-block:: idris
40+
41+ data GState = Running Nat Nat | NotRunning
42+
43+Notice that at this stage, we say nothing about what it means to make a
44+guess, what the word to be guessed is, how to guess letters, or any
45+other implementation detail. We are only interested in what is necessary
46+to describe the game rules.
47+
48+We will, however, parameterise a concrete game state ``Mystery`` over
49+this data:
50+
51+.. code-block:: idris
52+
53+ data Mystery : GState -> Type
54+
55+Step 2: Game Rules
56+------------------
57+
58+We describe the game rules as a dependent effect, where each action has
59+a *precondition* (i.e. what the game state must be before carrying out
60+the action) and a *postcondition* (i.e. how the action affects the game
61+state). Informally, these actions with the pre- and postconditions are:
62+
63+Guess
64+ Guess a letter in the word.
65+
66+ - Precondition: The game must be running, and there must be both
67+ guesses still available, and letters still to be guessed.
68+
69+ - Postcondition: If the guessed letter is in the word and not yet
70+ guessed, reduce the number of letters, otherwise reduce the
71+ number of guesses.
72+
73+Won
74+ Declare victory
75+
76+ - Precondition: The game must be running, and there must be no
77+ letters still to be guessed.
78+
79+ - Postcondition: The game is no longer running.
80+
81+Lost
82+ Accept defeat
83+
84+ - Precondition: The game must be running, and there must be no
85+ guesses left.
86+
87+ - Postcondition: The game is no longer running.
88+
89+NewWord
90+ Set a new word to be guessed
91+
92+ - Precondition: The game must not be running.
93+
94+ - Postcondition: The game is running, with 6 guesses available (the
95+ choice of 6 is somewhat arbitrary here) and the number of unique
96+ letters in the word still to be guessed.
97+
98+StrState
99+ Get a string representation of the game state. This is for display
100+ purposes; there are no pre- or postconditions.
101+
102+We can make these rules precise by declaring them more formally in an
103+effect signature:
104+
105+.. code-block:: idris
106+
107+ data MysteryRules : Effect where
108+ Guess : (x : Char) ->
109+ { Mystery (Running (S g) (S w)) ==>
110+ {inword} if inword then Mystery (Running (S g) w)
111+ else Mystery (Running g (S w)) }
112+ MysteryRules Bool
113+ Won : { Mystery (Running g 0) ==> Mystery NotRunning } MysteryRules ()
114+ Lost : { Mystery (Running 0 g) ==> Mystery NotRunning } MysteryRules ()
115+ NewWord : (w : String) ->
116+ { Mystery NotRunning ==>
117+ Mystery (Running 6 (length (letters w))) } MysteryRules ()
118+ StrState : { Mystery h } MysteryRules String
119+
120+This description says nothing about how the rules are implemented. In
121+particular, it does not specify *how* to tell whether a guessed letter
122+was in a word, just that the result of ``Guess`` depends on it.
123+
124+Nevertheless, we can still create an ``EFFECT`` from this, and use it in
125+an ``Eff`` program. Implementing a ``Handler`` for ``MysteryRules`` will
126+then allow us to play the game.
127+
128+.. code-block:: idris
129+
130+ MYSTERY : GState -> EFFECT
131+ MYSTERY h = MkEff (Mystery h) MysteryRules
132+
133+Step 3: Implement Rules
134+-----------------------
135+
136+To *implement* the rules, we begin by giving a concrete definition of
137+game state:
138+
139+.. code-block:: idris
140+
141+ data Mystery : GState -> Type where
142+ Init : Mystery NotRunning
143+ GameWon : (word : String) -> Mystery NotRunning
144+ GameLost : (word : String) -> Mystery NotRunning
145+ MkG : (word : String) ->
146+ (guesses : Nat) ->
147+ (got : List Char) ->
148+ (missing : Vect m Char) ->
149+ Mystery (Running guesses m)
150+
151+If a game is ``NotRunning``, that is either because it has not yet
152+started (``Init``) or because it is won or lost (``GameWon`` and
153+``GameLost``, each of which carry the word so that showing the game
154+state will reveal the word to the player). Finally, ``MkG`` captures a
155+running game’s state, including the target word, the letters
156+successfully guessed, and the missing letters. Using a ``Vect`` for the
157+missing letters is convenient since its length is used in the type.
158+
159+To initialise the state, we implement the following functions:
160+``letters``, which returns a list of unique letters in a ``String``
161+(ignoring spaces) and ``initState`` which sets up an initial state
162+considered valid as a postcondition for ``NewWord``.
163+
164+.. code-block:: idris
165+
166+ letters : String -> List Char
167+ initState : (x : String) -> Mystery (Running 6 (length (letters x)))
168+
169+When checking if a guess is in the vector of missing letters, it is
170+convenient to return a *proof* that the guess is in the vector, using
171+``isElem`` below, rather than merely a ``Bool``:
172+
173+.. code-block:: idris
174+
175+ data IsElem : a -> Vect n a -> Type where
176+ First : IsElem x (x :: xs)
177+ Later : IsElem x xs -> IsElem x (y :: xs)
178+
179+ isElem : DecEq a => (x : a) -> (xs : Vect n a) -> Maybe (IsElem x xs)
180+
181+The reason for returning a proof is that we can use it to remove an
182+element from the correct position in a vector:
183+
184+.. code-block:: idris
185+
186+ shrink : (xs : Vect (S n) a) -> IsElem x xs -> Vect n a
187+
188+We leave the definitions of ``letters``, ``init``, ``isElem`` and
189+``shrink`` as exercises. Having implemented these, the ``Handler``
190+implementation for ``MysteryRules`` is surprisingly straightforward:
191+
192+.. code-block:: idris
193+
194+ instance Handler MysteryRules m where
195+ handle (MkG w g got []) Won k = k () (GameWon w)
196+ handle (MkG w Z got m) Lost k = k () (GameLost w)
197+
198+ handle st StrState k = k (show st) st
199+ handle st (NewWord w) k = k () (initState w)
200+
201+ handle (MkG w (S g) got m) (Guess x) k =
202+ case isElem x m of
203+ Nothing => k False (MkG w _ got m)
204+ (Just p) => k True (MkG w _ (x :: got) (shrink m p))
205+
206+Each case simply involves directly updating the game state in a way
207+which is consistent with the declared rules. In particular, in
208+``Guess``, if the handler claims that the guessed letter is in the word
209+(by passing ``True`` to ``k``), there is no way to update the state in
210+such a way that the number of missing letters or number of guesses does
211+not follow the rules.
212+
213+Step 4: Implement Interface
214+---------------------------
215+
216+Having described the rules, and implemented state transitions which
217+follow those rules as an effect handler, we can now write an interface
218+for the game which uses the ``MYSTERY`` effect:
219+
220+.. code-block:: idris
221+
222+ game : { [MYSTERY (Running (S g) w), STDIO] ==>
223+ [MYSTERY NotRunning, STDIO] } Eff ()
224+
225+The type indicates that the game must start in a running state, with
226+some guesses available, and eventually reach a not-running state (i.e.
227+won or lost). The only way to achieve this is by correctly following the
228+stated rules. A possible complete implementation of ``game`` is
229+presented in Listing :ref:`mword`.
230+
231+Note that the type of ``game`` makes no assumption that there are
232+letters to be guessed in the given word (i.e. it is ``w`` rather than
233+``S w``). This is because we will be choosing a word at random from a
234+vector of ``String``, and at no point have we made it explicit that
235+those ``String`` are non-empty.
236+
237+Finally, we need to initialise the game by picking a word at random from
238+a list of candidates, setting it as the target using ``NewWord``, then
239+running ``game``:
240+
241+.. code-block:: idris
242+
243+ runGame : { [MYSTERY NotRunning, RND, SYSTEM, STDIO] } Eff ()
244+ runGame = do srand (cast !time)
245+ let w = index !(rndFin WEWEWE) words
246+ NewWord w
247+ game
248+ putStrLn !StrState
249+
250+We use the system time (``time`` from the ``SYSTEM`` effect; see
251+Appendix :ref:`sect-appendix`) to initialise the random number
252+generator, then pick a random ``Fin`` to index into a list of
253+``words``. For example, we could initialise a word list as follows:
254+
255+.. code-block:: idris
256+
257+ words : ?wtype
258+ words = with Vect ["idris","agda","haskell","miranda",
259+ "java","javascript","fortran","basic",
260+ "coffeescript","rust"]
261+
262+ wtype = proof search
263+
264+.. note::
265+ Rather than have to explicitly declare a type with the vector’s
266+ length, it is convenient to give a metavariable ``?wtype`` and let
267+ ``Idris``’s proof search mechanism find the type. This is a
268+ limited form of type inference, but very useful in practice.
269+
270+
271+.. _mword:
272+.. code-block:: idris
273+ :caption: Mystery Word Game Implementation
274+
275+ game : { [MYSTERY (Running (S g) w), STDIO] ==>
276+ [MYSTERY NotRunning, STDIO] } Eff ()
277+ game {w=Z} = Won
278+ game {w=S _}
279+ = do putStrLn !StrState
280+ putStr "Enter guess: "
281+ let guess = trim !getStr
282+ case choose (not (guess == "")) of
283+ (Left p) => processGuess (strHead' guess p)
284+ (Right p) => do putStrLn "Invalid input!"
285+ game
286+ where
287+ processGuess : Char -> { [MYSTERY (Running (S g) (S w)), STDIO] ==>
288+ [MYSTERY NotRunning, STDIO] }
289+ Eff ()
290+ processGuess {g} {w} c
291+ = case !(Main.Guess c) of
292+ True => do putStrLn "Good guess!"
293+ case w of
294+ Z => Won
295+ (S k) => game
296+ False => do putStrLn "No, sorry"
297+ case g of
298+ Z => Lost
299+ (S k) => game
300+
301+Discussion
302+----------
303+
304+Writing the rules separately as an effect, then an implementation
305+which uses that effect, ensures that the implementation must follow
306+the rules. This has practical applications in more serious contexts;
307+``MysteryRules`` for example can be though of as describing a
308+*protocol* that a game player most follow, or alternative a
309+*precisely-typed API*.
310+
311+In practice, we wouldn’t really expect to write rules first then
312+implement the game once the rules were complete. Indeed, I didn’t do
313+so when constructing this example! Rather, I wrote down a set of
314+likely rules making any assumptions *explicit* in the state
315+transitions for ``MysteryRules``. Then, when implementing ``game`` at
316+first, any incorrect assumption was caught as a type error. The
317+following errors were caught during development:
318+
319+- Not realising that allowing ``NewWord`` to be an arbitrary string
320+ would mean that ``game`` would have to deal with a zero-length word
321+ as a starting state.
322+
323+- Forgetting to check whether a game was won before recursively
324+ calling ``processGuess``, thus accidentally continuing a finished
325+ game.
326+
327+- Accidentally checking the number of missing letters, rather than the
328+ number of remaining guesses, when checking if a game was lost.
329+
330+These are, of course, simple errors, but were caught by the type
331+checker before any testing of the game.
332+
333+.. [1]
334+ Readers may recognise this game by the name “Hangman.”
docs/effects/impleff.rstnew file+329
@@ -0,0 +1,329 @@
1+.. _sect-impleff:
2+
3+====================
4+Creating New Effects
5+====================
6+
7+We have now seen several side-effecting operations provided by the
8+``Effects`` library, and examples of their use in Section
9+:ref:`sect-simpleff`. We have also seen how operations may *modify*
10+the available effects by changing state in Section
11+:ref:`sect-depeff`. We have not, however, yet seen how these
12+operations are implemented. In this section, we describe how a
13+selection of the available effects are implemented, and show how new
14+effectful operations may be provided.
15+
16+State
17+-----
18+
19+Effects are described by *algebraic data types*, where the
20+constructors describe the operations provided when the effect is
21+available. Stateful operations are described as follows:
22+
23+.. code-block:: idris
24+
25+ data State : Effect where
26+ Get : { a } State a
27+ Put : b -> { a ==> b } State ()
28+
29+Each effect is associated with a *resource*, the type of which is
30+given with the notation ``{ x ==> x’ }``. This notation gives the
31+resource type expected by each operation, and how it updates when the
32+operation is run. Here, it means:
33+
34+- ``Get`` takes no arguments. It has a resource of type ``a``, which
35+ is not updated, and running the ``Get`` operation returns something
36+ of type ``a``.
37+
38+- ``Put`` takes a ``b`` as an argument. It has a resource of type
39+ ``a`` on input, which is updated to a resource of type
40+ ``b``. Running the ``Put`` operation returns the element of the
41+ unit type.
42+
43+``Effect`` itself is a type synonym, declared as follows:
44+
45+.. code-block:: idris
46+
47+ Effect : Type
48+ Effect = (result : Type) ->
49+ (input_resource : Type) ->
50+ (output_resource : result -> Type) -> Type
51+
52+That is, an effectful operation returns something of type ``result``,
53+has an input resource of type ``input_resource``, and a function
54+``output_resource`` which computes the output resource type from the
55+result. We use the same syntactic sugar as with ``Eff`` to make effect
56+declarations more readable. It is defined as follows in the library:
57+
58+.. code-block:: idris
59+
60+ syntax "{" [inst] "}" [eff] = eff inst (\result => inst)
61+ syntax "{" [inst] "==>" "{" {b} "}" [outst] "}" [eff]
62+ = eff inst (\b => outst)
63+ syntax "{" [inst] "==>" [outst] "}" [eff] = eff inst (\result => outst)
64+
65+In order to convert ``State`` (of type ``Effect``) into something
66+usable in an effects list, of type ``EFFECT``, we write the following:
67+
68+.. code-block:: idris
69+
70+ STATE : Type -> EFFECT
71+ STATE t = MkEff t State
72+
73+``MkEff`` constructs an ``EFFECT`` by taking the resource type (here,
74+the ``t`` which parameterises ``STATE``) and the effect signature
75+(here, ``State``). For reference, ``EFFECT`` is declared as follows:
76+
77+.. code-block:: idris
78+
79+ data EFFECT : Type where
80+ MkEff : Type -> Effect -> EFFECT
81+
82+Recall that to run an effectful program in ``Eff``, we use one of the
83+``run`` family of functions to run the program in a particular
84+computation context ``m``. For each effect, therefore, we must explain
85+how it is executed in a particular computation context for ``run`` to
86+work in that context. This is achieved with the following type class:
87+
88+.. code-block:: idris
89+
90+ class Handler (e : Effect) (m : Type -> Type) where
91+ handle : resource -> (eff : e t resource resource') ->
92+ ((x : t) -> resource' x -> m a) -> m a
93+
94+We have already seen some instance declarations in the effect
95+summaries in Section :ref:`sect-simpleff`. An instance of ``Handler e
96+m`` means that the effect declared with signature ``e`` can be run in
97+computation context ``m``. The ``handle`` function takes:
98+
99+- The ``resource`` on input (so, the current value of the state for
100+ ``State``)
101+
102+- The effectful operation (either ``Get`` or ``Put x`` for ``State``)
103+
104+- A *continuation*, which we conventionally call ``k``, and should be
105+ passed the result value of the operation, and an updated resource.
106+
107+There are two reasons for taking a continuation here: firstly, this is
108+neater because there are multiple return values (a new resource and
109+the result of the operation); secondly, and more importantly, the
110+continuation can be called zero or more times.
111+
112+A ``Handler`` for ``State`` simply passes on the value of the state,
113+in the case of ``Get``, or passes on a new state, in the case of
114+``Put``. It is defined the same way for all computation contexts:
115+
116+.. code-block:: idris
117+
118+ instance Handler State m where
119+ handle st Get k = k st st
120+ handle st (Put n) k = k () n
121+
122+This gives enough information for ``Get`` and ``Put`` to be used
123+directly in ``Eff`` programs. It is tidy, however, to define top level
124+functions in ``Eff``, as follows:
125+
126+.. code-block:: idris
127+
128+ get : { [STATE x] } Eff x
129+ get = call Get
130+
131+ put : x -> { [STATE x] } Eff ()
132+ put val = call (Put val)
133+
134+ putM : y -> { [STATE x] ==> [STATE y] } Eff ()
135+ putM val = call (Put val)
136+
137+**An implementation detail (aside):** The ``call`` function converts
138+an ``Effect`` to a function in ``Eff``, given a proof that the effect
139+is available. This proof can be constructed automatically by , since
140+it is essentially an index into a statically known list of effects:
141+
142+.. code-block:: idris
143+
144+ call : {e : Effect} ->
145+ (eff : e t a b) -> {auto prf : EffElem e a xs} ->
146+ Eff t xs (\v => updateResTy v xs prf eff)
147+
148+This is the reason for the ``Can’t solve goal`` error when an effect
149+is not available: the implicit proof ``prf`` has not been solved
150+automatically because the required effect is not in the list of
151+effects ``xs``.
152+
153+Such details are not important for using the library, or even writing
154+new effects, however.
155+
156+Summary
157+~~~~~~~
158+
159+Listing :ref:`eff-statedef` summarises what is required to define the
160+``STATE`` effect.
161+
162+.. _eff-statedef:
163+.. code-block:: idris
164+ :caption: Complete State Effect Definition
165+
166+ data State : Effect where
167+ Get : { a } State a
168+ Put : b -> { a ==> b } State ()
169+
170+ STATE : Type -> EFFECT
171+ STATE t = MkEff t State
172+
173+ instance Handler State m where
174+ handle st Get k = k st st
175+ handle st (Put n) k = k () n
176+
177+ get : { [STATE x] } Eff x
178+ get = call Get
179+
180+ put : x -> { [STATE x] } Eff ()
181+ put val = call (Put val)
182+
183+ putM : y -> { [STATE x] ==> [STATE y] } Eff ()
184+ putM val = call (Put val)
185+
186+
187+Console I/O
188+-----------
189+
190+Listing :ref:`eff-stdiodef` gives the definition of the ``STDIO``
191+effect, including handlers for ``IO`` and ``IOExcept``. We omit the
192+definition of the top level ``Eff`` functions, as this merely invoke
193+the effects ``PutStr``, ``GetStr``, ``PutCh`` and ``GetCh`` directly.
194+
195+Note that in this case, the resource is the unit type in every case,
196+since the handlers merely apply the ``IO`` equivalents of the effects
197+directly.
198+
199+.. _eff-stdiodef:
200+.. code-block:: idris
201+ :caption: Console I/O Effect Definition
202+
203+ data StdIO : Effect where
204+ PutStr : String -> { () } StdIO ()
205+ GetStr : { () } StdIO String
206+ PutCh : Char -> { () } StdIO ()
207+ GetCh : { () } StdIO Char
208+
209+ instance Handler StdIO IO where
210+ handle () (PutStr s) k = do putStr s; k () ()
211+ handle () GetStr k = do x <- getLine; k x ()
212+ handle () (PutCh c) k = do putChar c; k () ()
213+ handle () GetCh k = do x <- getChar; k x ()
214+
215+ instance Handler StdIO (IOExcept a) where
216+ handle () (PutStr s) k = do ioe_lift $ putStr s; k () ()
217+ handle () GetStr k = do x <- ioe_lift $ getLine; k x ()
218+ handle () (PutCh c) k = do ioe_lift $ putChar c; k () ()
219+ handle () GetCh k = do x <- ioe_lift $ getChar; k x ()
220+
221+ STDIO : EFFECT
222+ STDIO = MkEff () StdIO
223+
224+Exceptions
225+----------
226+
227+.. _eff-exceptdef:
228+.. code-block:: idris
229+ :caption: Exception Effect Definition
230+
231+ data Exception : Type -> Effect where
232+ Raise : a -> { () } Exception a b
233+
234+ instance Handler (Exception a) Maybe where
235+ handle _ (Raise e) k = Nothing
236+
237+ instance Handler (Exception a) List where
238+ handle _ (Raise e) k = []
239+
240+ EXCEPTION : Type -> EFFECT
241+ EXCEPTION t = MkEff () (Exception t)
242+
243+Listing :ref:`eff-exceptdef` gives the definition of the ``Exception``
244+effect, including two of its handlers for ``Maybe`` and ``List``. The
245+only operation provided is ``Raise``. The key point to note in the
246+definitions of these handlers is that the continuation ``k`` is not
247+used. Running ``Raise`` therefore means that computation stops with an
248+error.
249+
250+Non-determinism
251+---------------
252+
253+.. _eff-selectdef:
254+.. code-block:: idris
255+ :caption: Non-determinism Effect Definition
256+
257+ data Selection : Effect where
258+ Select : List a -> { () } Selection a
259+
260+ instance Handler Selection Maybe where
261+ handle _ (Select xs) k = tryAll xs where
262+ tryAll [] = Nothing
263+ tryAll (x :: xs) = case k x () of
264+ Nothing => tryAll xs
265+ Just v => Just v
266+
267+ instance Handler Selection List where
268+ handle r (Select xs) k = concatMap (\x => k x r) xs
269+
270+ SELECT : EFFECT
271+ SELECT = MkEff () Selection
272+
273+Listing :ref:`eff-selectdef` gives the definition of the ``Select``
274+effect for writing non-deterministic programs, including a handler for
275+``List`` context which returns all possible successful values, and a
276+handler for ``Maybe`` context which returns the first successful
277+value.
278+
279+Here, the continuation is called multiple times in each handler, for
280+each value in the list of possible values. In the ``List`` handler, we
281+accumulate all successful results, and in the ``Maybe`` handler we try
282+the first value in the last, and try later values only if that fails.
283+
284+File Management
285+---------------
286+
287+Result-dependent effects are no different from non-dependent effects
288+in the way they are implemented. Listing :ref:`eff-filedef`
289+illustrates this for the ``FILE_IO`` effect. The syntax for state
290+transitions ``{ x ==> {res} x’ }``, where the result state ``x’`` is
291+computed from the result of the operation ``res``, follows that for
292+the equivalent ``Eff`` programs.
293+
294+Note that in the handler for ``Open``, the types passed to the
295+continuation ``k`` are different depending on whether the result is
296+``True`` (opening succeeded) or ``False`` (opening failed). This uses
297+``validFile``, defined in the ``Prelude``, to test whether a file
298+handler refers to an open file or not.
299+
300+.. _eff-filedef:
301+.. code-block:: idris
302+ :caption: File I/O Effect Definition
303+
304+ data FileIO : Effect where
305+ Open : String -> (m : Mode) ->
306+ {() ==> {res} if res then OpenFile m else ()} FileIO Bool
307+ Close : {OpenFile m ==> ()} FileIO ()
308+
309+ ReadLine : {OpenFile Read} FileIO String
310+ WriteLine : String -> {OpenFile Write} FileIO ()
311+ EOF : {OpenFile Read} FileIO Bool
312+
313+ instance Handler FileIO IO where
314+ handle () (Open fname m) k = do h <- openFile fname m
315+ if !(validFile h)
316+ then k True (FH h)
317+ else k False ()
318+ handle (FH h) Close k = do closeFile h
319+ k () ()
320+
321+ handle (FH h) ReadLine k = do str <- fread h
322+ k str (FH h)
323+ handle (FH h) (WriteLine str) k = do fwrite h str
324+ k () (FH h)
325+ handle (FH h) EOF k = do e <- feof h
326+ k e (FH h)
327+
328+ FILE_IO : Type -> EFFECT
329+ FILE_IO t = MkEff t FileIO
docs/effects/index.rstnew file+28
@@ -0,0 +1,28 @@
1+.. _eff-tutorial-index:
2+
3+####################
4+The Effects Tutorial
5+####################
6+
7+A tutorial on the `Effects` package in `Idris`.
8+
9+.. note::
10+
11+ The documentation for Idris has been published under the Creative
12+ Commons CC0 License. As such to the extent possible under law, /The
13+ Idris Community/ has waived all copyright and related or neighboring
14+ rights to Documentation for Idris.
15+
16+ More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/
17+
18+.. toctree::
19+ :maxdepth: 1
20+
21+ introduction
22+ state
23+ simpleeff
24+ depeff
25+ impleff
26+ hangman
27+ conclusions
28+ summary
docs/effects/introduction.rstnew file+111
@@ -0,0 +1,111 @@
1+============
2+Introduction
3+============
4+
5+Pure functional languages with dependent types such as `Idris
6+<http://idris-lang.org/>`_ support reasoning about programs directly
7+in the type system, promising that we can *know* a program will run
8+correctly (i.e. according to the specification in its type) simply
9+because it compiles. Realistically, though, things are not so simple:
10+programs have to interact with the outside world, with user input,
11+input from a network, mutable state, and so on. In this tutorial I
12+will introduce the library, which is included with the distribution
13+and supports programming and reasoning with side-effecting programs,
14+supporting mutable state, interaction with the outside world,
15+exceptions, and verified resource management.
16+
17+This tutorial assumes familiarity with pure programming in ``Idris``,
18+as described in Sections 1–6 of the main tutorial [1]_. The examples
19+are presented are tested with ``Idris`` and can be found in the
20+examples directory of the ``Idris`` repository.
21+
22+Consider, for example, the following introductory function which
23+illustrates the kind of properties which can be expressed in the type
24+system:
25+
26+.. code-block:: idris
27+
28+ vadd : Vect n Int -> Vect n Int -> Vect n Int
29+ vadd [] [] = []
30+ vadd (x :: xs) (y :: ys) = x + y :: vadd xs ys
31+
32+This function adds corresponding elements in a pair of vectors. The type
33+guarantees that the vectors will contain only elements of type ``Int``,
34+and that the input lengths and the output length all correspond. A
35+natural question to ask here, which is typically neglected by
36+introductory tutorials, is “How do I turn this into a program?” That is,
37+given some lists entered by a user, how do we get into a position to be
38+able to apply the ``vadd`` function? Before doing so, we will have to:
39+
40+- Read user input, either from the keyboard, a file, or some other
41+ input device.
42+
43+- Check that the user inputs are valid, i.e. contain only ``Int`` s
44+ and are the same length, and report an error if not.
45+
46+- Write output
47+
48+The complete program will include side-effects for I/O and error
49+handling, before we can get to the pure core functionality. In this
50+tutorial, we will see how ``Idris`` supports side-effects.
51+Furthermore, we will see how we can use the dependent type system to
52+*reason* about stateful and side-effecting programs. We will return to
53+this specific example later.
54+
55+Hello world
56+===========
57+
58+To give an idea of how programs with effects look in , here is the
59+ubiquitous “Hello world” program, written using the ``Effects``
60+library:
61+
62+.. code-block:: idris
63+
64+ module Main
65+
66+ import Effect.StdIO
67+
68+ hello : [STDIO] Eff ()
69+ hello = putStrLn “Hello world!”
70+
71+ main : IO ()
72+ main = run hello
73+
74+As usual, the entry point is ``main``. All ``main`` has to do is
75+invoke the ``hello`` function which supports the ``STDIO`` effect for
76+console I/O, and returns the unit value. The details of the ``Eff``
77+type will be presented in the remainder of this tutorial.
78+
79+To compile and run this program, ``Idris`` needs to be told to include
80+the ``Effects`` package, using the ``-p effects`` flag (this flag is
81+required for all examples in this tutorial):
82+
83+.. code-block:: sh
84+
85+ idris hello.idr -o hello -p effects
86+ ./hello Hello world!
87+
88+Outline
89+=======
90+
91+The tutorial is structured as follows: first, in Section
92+:ref:`sect-state`, we will discuss state management, describing why it
93+is important and introducing the ``effects`` library to show how it
94+can be used to manage state. This section also gives an overview of
95+the syntax of effectful programs. Section :ref:`sect-simpleff` then
96+introduces a number of other effects a program may have: I/O;
97+Exceptions; Random Numbers; and Non-determinism, giving examples for
98+each, and an extended example combining several effects in one
99+complete program. Section :ref:`sect-depeff` introduces *dependent*
100+effects, showing how states and resources can be managed in
101+types. Section :ref:`sect-impleff` shows how new effects can be
102+implemented. Section :ref:`sect-hangman` gives an extended example
103+showing how to implement a “mystery word” guessing game, using effects
104+to describe the rules of the game and ensure they are implemented
105+accurately. References to further reading are given in Section
106+:ref:`sect-further`.
107+
108+.. [1]
109+ You do not, however, need to know what a monad is. A correctness
110+ property of this tutorial is that the word “monad” should appear
111+ exactly twice, both in this footnote.
docs/effects/simpleeff.rstnew file+602
@@ -0,0 +1,602 @@
1+.. _sect-simpleff:
2+
3+==============
4+Simple Effects
5+==============
6+
7+So far we have seen how to write programs with locally mutable state
8+using the ``STATE`` effect. To recap, we have the definitions in
9+Listing :ref:`eff-state` in a module ``Effect.State``.
10+
11+.. _eff-state:
12+.. code-block:: idris
13+ :caption: State Effect
14+
15+ module Effect.State
16+
17+ STATE : Type -> EFFECT
18+
19+ get : { [STATE x] } Eff x
20+ put : x -> { [STATE x] } Eff ()
21+ putM : y -> { [STATE x] ==> [STATE y] } Eff ()
22+ update : (x -> x) -> { [STATE x] } Eff ()
23+
24+ instance Handler State m
25+
26+The last line, ``instance Handler State m``, means that the ``STATE``
27+effect is usable in any computation context ``m``. That is, a program
28+which uses this effect and returns something of type ``a`` can be
29+evaluated to something of type ``m a`` using ``run``, for any
30+``m``. The lower case ``State`` is a data type describing the
31+operations which make up the ``STATE`` effect itself—we will go into
32+more detail about this in Section :ref:`sect-impleff`.
33+
34+In this section, we will introduce some other supported effects,
35+allowing console I/O, exceptions, random number generation and
36+non-deterministic programming. For each effect we introduce, we will
37+begin with a summary of the effect, its supported operations, and the
38+contexts in which it may be used, like that above for ``STATE``, and
39+go on to present some simple examples. At the end, we will see some
40+examples of programs which combine multiple effects.
41+
42+All of the effects in the library, including those described in this
43+section, are summarised in Appendix :ref:`sect-appendix`.
44+
45+Console I/O
46+-----------
47+
48+Console I/O (Listing :ref:`eff-stdio`) is supported with the ``STDIO``
49+effect, which allows reading and writing characters and strings to and
50+from standard input and standard output. Notice that there is a
51+constraint here on the computation context ``m``, because it only
52+makes sense to support console I/O operations in a context where we
53+can perform (or at the very least simulate) console I/O.
54+
55+.. _eff-stdio:
56+.. code-block:: idris
57+ :caption: Console I/0 Effect
58+
59+ module Effect.StdIO
60+
61+ STDIO : EFFECT
62+
63+ putChar : Char -> { [STDIO] } Eff ()
64+ putStr : String -> { [STDIO] } Eff ()
65+ putStrLn : String -> { [STDIO] } Eff ()
66+
67+ getStr : { [STDIO] } Eff String
68+ getChar : { [STDIO] } Eff Char
69+
70+ instance Handler StdIO IO
71+ instance Handler StdIO (IOExcept a)
72+
73+Examples
74+~~~~~~~~
75+
76+A program which reads the user’s name, then says hello, can be written
77+as follows:
78+
79+.. code-block:: idris
80+
81+ hello : { [STDIO] } Eff ()
82+ hello = do putStr "Name? "
83+ x <- getStr
84+ putStrLn ("Hello " ++ trim x ++ "!")
85+
86+We use ``trim`` here to remove the trailing newline from the
87+input. The resource associated with ``STDIO`` is simply the empty
88+tuple, which has a default value ``()``, so we can run this as
89+follows:
90+
91+.. code-block:: idris
92+
93+ main : IO ()
94+ main = run hello
95+
96+In ``hello`` we could also use ``!``-notation instead of ``x <-
97+getStr``, since we only use the string that is read once:
98+
99+.. code-block:: idris
100+
101+ hello : { [STDIO] } Eff ()
102+ hello = do putStr "Name? "
103+ putStrLn ("Hello " ++ trim !getStr ++ "!")
104+
105+More interestingly, we can combine multiple effects in one
106+program. For example, we can loop, counting the number of people we’ve
107+said hello to:
108+
109+.. code-block:: idris
110+
111+ hello : { [STATE Int, STDIO] } Eff ()
112+ hello = do putStr "Name? "
113+ putStrLn ("Hello " ++ trim !getStr ++ "!")
114+ update (+1)
115+ putStrLn ("I've said hello to: " ++ show !get ++ " people")
116+ hello
117+
118+The list of effects given in ``hello`` means that the function can
119+call ``get`` and ``put`` on an integer state, and any functions which
120+read and write from the console. To run this, ``main`` does not need
121+to be changed.
122+
123+Aside: Resource Types
124+~~~~~~~~~~~~~~~~~~~~~
125+
126+To find out the resource type of an effect, if necessary (for example
127+if we want to initialise a resource explicitiy with ``runInit`` rather
128+than using a default value with ``run``) we can run the
129+``resourceType`` function at the REPL:
130+
131+.. code-block:: idris
132+
133+ *ConsoleIO> resourceType STDIO
134+ () : Type
135+ *ConsoleIO> resourceType (STATE Int)
136+ Int : Type
137+
138+Exceptions
139+----------
140+
141+Listing :ref:`eff-exception` gives the definition of the ``EXCEPTION``
142+effect, declared in module ``Effect.Exception``. This allows programs
143+to exit immediately with an error, or errors to be handled more
144+generally.
145+
146+.. _eff-exception:
147+.. code-block:: idris
148+ :caption: Exception Effect
149+
150+ module Effect.Exception
151+
152+ EXCEPTION : Type -> EFFECT
153+
154+ raise : a -> { [EXCEPTION a ] } Eff b
155+
156+ instance Handler (Exception a) Maybe
157+ instance Handler (Exception a) List
158+ instance Handler (Exception a) (Either a)
159+ instance Handler (Exception a) (IOExcept a)
160+ instance Show a => Handler (Exception a) IO
161+
162+Example
163+~~~~~~~
164+
165+Suppose we have a ``String`` which is expected to represent an integer
166+in the range ``0`` to ``n``. We can write a function ``parseNumber``
167+which returns an ``Int`` if parsing the string returns a number in the
168+appropriate range, or throws an exception otherwise. Exceptions are
169+paramaterised by an error type:
170+
171+.. code-block:: idris
172+
173+ data Err = NotANumber | OutOfRange
174+
175+ parseNumber : Int -> String -> { [EXCEPTION Err] } Eff Int
176+ parseNumber num str
177+ = if all isDigit (unpack str)
178+ then let x = cast str in
179+ if (x >=0 && x <= num)
180+ then pure x
181+ else raise OutOfRange
182+ else raise NotANumber
183+
184+Programs which support the ``EXCEPTION`` effect can be run in any
185+context which has some way of throwing errors, for example, we can run
186+``parseNumber`` in the ``Either Err`` context. It returns a value of
187+the form ``Right x`` if successful:
188+
189+.. code-block:: idris
190+
191+ *Exception> the (Either Err Int) $ run (parseNumber 42 "20")
192+ Right 20 : Either Err Int
193+
194+Or ``Left e`` on failure, carrying the appropriate exception:
195+
196+.. code-block:: idris
197+
198+ *Exception> the (Either Err Int) $ run (parseNumber 42 "50")
199+ Left OutOfRange : Either Err Int
200+
201+ *Exception> the (Either Err Int) $ run (parseNumber 42 "twenty")
202+ Left NotANumber : Either Err Int
203+
204+In fact, we can do a little bit better with ``parseNumber``, and have
205+it return a *proof* that the integer is in the required range along
206+with the integer itself. One way to do this is define a type of
207+bounded integers, ``Bounded``:
208+
209+.. code-block:: idris
210+
211+ Bounded : Int -> Type
212+ Bounded x = (n : Int ** So (n >= 0 && n <= x))
213+
214+Recall that ``So`` is parameterised by a ``Bool``, and only ``So
215+True`` is inhabited. We can use ``choose`` to construct such a value
216+from the result of a dynamic check:
217+
218+.. code-block:: idris
219+
220+ data So : Bool -> Type = Oh : So True
221+
222+ choose : (b : Bool) -> Either (So b) (So (not b))
223+
224+We then write ``parseNumber`` using ``choose`` rather than an
225+``if/then/else`` construct, passing the proof it returns on success as
226+the boundedness proof:
227+
228+.. code-block:: idris
229+
230+ parseNumber : (x : Int) -> String -> { [EXCEPTION Err] } Eff (Bounded x)
231+ parseNumber x str
232+ = if all isDigit (unpack str)
233+ then let num = cast str in
234+ case choose (num >=0 && num <= x) of
235+ Left p => pure (num ** p)
236+ Right p => raise OutOfRange
237+ else raise NotANumber
238+
239+Random Numbers
240+--------------
241+
242+Random number generation is also implemented by the library, in module
243+``Effect.Random``. Listing :ref:`eff-random` gives its definition.
244+
245+.. _eff-random:
246+.. code-block:: idris
247+ :caption: Random Number Effect
248+
249+ module Effect.Random
250+
251+ RND : EFFECT
252+
253+ srand : Integer -> { [RND] } Eff ()
254+ rndInt : Integer -> Integer -> { [RND] } Eff Integer
255+ rndFin : (k : Nat) -> { [RND] } Eff (Fin (S k))
256+
257+ instance Handler Random m
258+
259+Random number generation is considered side-effecting because its
260+implementation generally relies on some external source of randomness.
261+The default implementation here relies on an integer *seed*, which can
262+be set with ``srand``. A specific seed will lead to a predictable,
263+repeatable sequence of random numbers. There are two functions which
264+produce a random number:
265+
266+- ``rndInt``, which returns a random integer between the given lower
267+ and upper bounds.
268+
269+- ``rndFin``, which returns a random element of a finite set
270+ (essentially a number with an upper bound given in its type).
271+
272+Example
273+~~~~~~~
274+
275+We can use the ``RND`` effect to implement a simple guessing game. The
276+``guess`` function, given a target number, will repeatedly ask the
277+user for a guess, and state whether the guess is too high, too low, or
278+correct:
279+
280+.. code-block:: idris
281+
282+ guess : Int -> { [STDIO] } Eff ()
283+
284+For reference, the code for ``guess`` is given in Listing
285+:ref:`eff-game`. Note that we use ``parseNumber`` as defined
286+previously to read user input, but we don’t need to list the
287+``EXCEPTION`` effect because we use a nested ``run`` to invoke
288+``parseNumber``, independently of the calling effectful program.
289+
290+To invoke these, we pick a random number within the range 0–100,
291+having set up the random number generator with a seed, then run
292+``guess``:
293+
294+.. code-block:: idris
295+
296+ game : { [RND, STDIO] } Eff ()
297+ game = do srand 123456789
298+ guess (fromInteger !(rndInt 0 100))
299+
300+ main : IO ()
301+ main = run game
302+
303+If no seed is given, it is set to the ``default`` value. For a less
304+predictable game, some better source of randomness would be required,
305+for example taking an initial seed from the system time. To see how to
306+do this, see the ``SYSTEM`` effect described in :ref:`sect-appendix`.
307+
308+.. _eff-game:
309+.. code-block:: idris
310+ :caption: Guessing Game
311+
312+ guess : Int -> { [STDIO] } Eff ()
313+ guess target
314+ = do putStr "Guess: "
315+ case run {m=Maybe} (parseNumber 100 (trim !getStr)) of
316+ Nothing => do putStrLn "Invalid input"
317+ guess target
318+ Just (v ** _) =>
319+ case compare v target of
320+ LT => do putStrLn "Too low"
321+ guess target
322+ EQ => putStrLn "You win!"
323+ GT => do putStrLn "Too high"
324+ guess target
325+
326+Non-determinism
327+---------------
328+
329+Listing :ref:`eff-select` gives the definition of the non-determinism
330+effect, which allows a program to choose a value non-deterministically
331+from a list of possibilities in such a way that the entire computation
332+succeeds.
333+
334+.. _eff-select:
335+.. code-block:: idris
336+ :caption: Non-determinism Effect
337+
338+ import Effects
339+ import Effect.Select
340+
341+ SELECT : EFFECT
342+
343+ select : List a -> { [SELECT] } Eff a
344+
345+ instance Handler Selection Maybe
346+ instance Handler Selection List
347+
348+Example
349+~~~~~~~
350+
351+The ``SELECT`` effect can be used to solve constraint problems, such
352+as finding Pythagorean triples. The idea is to use ``select`` to give
353+a set of candidate values, then throw an exception for any combination
354+of values which does not satisfy the constraint:
355+
356+.. code-block:: idris
357+
358+ triple : Int -> { [SELECT, EXCEPTION String] } Eff (Int, Int, Int)
359+ triple max = do z <- select [1..max]
360+ y <- select [1..z]
361+ x <- select [1..y]
362+ if (x * x + y * y == z * z)
363+ then pure (x, y, z)
364+ else raise "No triple"
365+
366+This program chooses a value for ``z`` between ``1`` and ``max``, then
367+values for ``y`` and ``x``. In operation, after a ``select``, the
368+program executes the rest of the ``do``-block for every possible
369+assignment, effectively searching depth-first. If the list is empty
370+(or an exception is thrown) execution fails.
371+
372+There are handlers defined for ``Maybe`` and ``List`` contexts, i.e.
373+contexts which can capture failure. Depending on the context ``m``,
374+``triple`` will either return the first triple it finds (if in
375+``Maybe`` context) or all triples in the range (if in ``List``
376+context). We can try this as follows:
377+
378+.. code-block:: idris
379+
380+ main : IO ()
381+ main = do print $ the (Maybe _) $ run (triple 100)
382+ print $ the (List _) $ run (triple 100)
383+
384+``vadd`` revisited
385+------------------
386+
387+We now return to the ``vadd`` program from the introduction. Recall the
388+definition:
389+
390+.. code-block:: idris
391+
392+ vadd : Vect n Int -> Vect n Int -> Vect n Int
393+ vadd [] [] = []
394+ vadd (x :: idris xs) (y :: ys) = x + y :: vadd xs ys
395+
396+Using , we can set up a program so that it reads input from a user,
397+checks that the input is valid (i.e both vectors contain integers, and
398+are the same length) and if so, pass it on to ``vadd``. First, we
399+write a wrapper for ``vadd`` which checks the lengths and throw an
400+exception if they are not equal. We can do this for input vectors of
401+length ``n`` and ``m`` by matching on the implicit arguments ``n`` and
402+``m`` and using ``decEq`` to produce a proof of their equality, if
403+they are equal:
404+
405+.. code-block:: idris
406+
407+ vadd_check : Vect n Int -> Vect m Int ->
408+ { [EXCEPTION String] } Eff (Vect m Int)
409+ vadd_check {n} {m} xs ys with (decEq n m)
410+ vadd_check {n} {m=n} xs ys | (Yes Refl) = pure (vadd xs ys)
411+ vadd_check {n} {m} xs ys | (No contra) = raise "Length mismatch"
412+
413+To read a vector from the console, we implement a function of the
414+following type:
415+
416+.. code-block:: idris
417+
418+ read_vec : { [STDIO] } Eff (p ** Vect p Int)
419+
420+This returns a dependent pair of a length, and a vector of that
421+length, because we cannot know in advance how many integers the user
422+is going to input. One way to implement this function, using ``-1`` to
423+indicate the end of input, is shown in Listing [readvec]. This uses a
424+variation on ``parseNumber`` which does not require a number to be
425+within range.
426+
427+Finally, we write a program which reads two vectors and prints the
428+result of pairwise addition of them, throwing an exception if the
429+inputs are of differing lengths:
430+
431+.. code-block:: idris
432+
433+ do_vadd : { [STDIO, EXCEPTION String] } Eff ()
434+ do_vadd = do putStrLn "Vector 1"
435+ (_ ** xs) <- read_vec
436+ putStrLn "Vector 2"
437+ (_ ** ys) <- read_vec
438+ putStrLn (show !(vadd_check xs ys))
439+
440+By having explicit lengths in the type, we can be sure that ``vadd``
441+is only being used where the lengths of inputs are guaranteed to be
442+equal. This does not stop us reading vectors from user input, but it
443+does require that the lengths are checked and any discrepancy is dealt
444+with gracefully.
445+
446+.. code-block:: idris
447+ :caption: Reading a vector from the console.
448+
449+ read_vec : { [STDIO] } Eff (p ** Vect p Int)
450+ read_vec = do putStr "Number (-1 when done): "
451+ case run (parseNumber (trim !getStr)) of
452+ Nothing => do putStrLn "Input error"
453+ read_vec
454+ Just v => if (v /= -1)
455+ then do (_ ** xs) <- read_vec
456+ pure (_ ** v :: xs)
457+ else pure (_ ** [])
458+ where
459+ parseNumber : String -> { [EXCEPTION String] } Eff Int
460+ parseNumber str
461+ = if all (\x => isDigit x || x == '-') (unpack str)
462+ then pure (cast str)
463+ else raise "Not a number"
464+
465+Example: An Expression Calculator
466+---------------------------------
467+
468+To show how these effects can fit together, let us consider an
469+evaluator for a simple expression language, with addition and integer
470+values.
471+
472+.. code-block:: idris
473+
474+ data Expr = Val Integer
475+ | Add Expr Expr
476+
477+An evaluator for this language always returns an ``Integer``, and
478+there are no situations in which it can fail!
479+
480+.. code-block:: idris
481+
482+ eval : Expr -> Integer
483+ eval (Val x) = x
484+ eval (Add l r) = eval l + eval r
485+
486+If we add variables, however, things get more interesting. The
487+evaluator will need to be able to access the values stored in
488+variables, and variables may be undefined.
489+
490+.. code-block:: idris
491+
492+ data Expr = Val Integer
493+ | Var String
494+ | Add Expr Expr
495+
496+To start, we will change the type of ``eval`` so that it is effectful,
497+and supports an exception effect for throwing errors, and a state
498+containing a mapping from variable names (as ``String``) to their
499+values:
500+
501+.. code-block:: idris
502+
503+ Env : Type
504+ Env = List (String, Integer)
505+
506+ eval : Expr -> { [EXCEPTION String, STATE Env] } Eff Integer
507+ eval (Val x) = return x
508+ eval (Add l r) = return $ !(eval l) + !(eval r)
509+
510+Note that we are using ``!``-notation to avoid having to bind
511+subexpressions in a ``do`` block. Next, we add a case for evaluating
512+``Var``:
513+
514+.. code-block:: idris
515+
516+ eval (Var x) = case lookup x !get of
517+ Nothing => raise $ "No such variable " ++ x
518+ Just val => return val
519+
520+This retrieves the state (with ``get``, supported by the ``STATE Env``
521+effect) and raises an exception if the variable is not in the
522+environment (with ``raise``, supported by the ``EXCEPTION String``
523+effect).
524+
525+To run the evaluator on a particular expression in a particular
526+environment of names and their values, we can write a function which
527+sets the state then invokes ``eval``:
528+
529+.. code-block:: idris
530+
531+ runEval : List (String, Integer) -> Expr -> Maybe Integer
532+ runEval args expr = run (eval' expr)
533+ where eval' : Expr -> { [EXCEPTION String, STATE Env] } Eff Integer
534+ eval' e = do put args
535+ eval e
536+
537+We have picked ``Maybe`` as a computation context here; it needs to be
538+a context which is available for every effect supported by
539+``eval``. In particular, because we have exceptions, it needs to be a
540+context which supports exceptions. Alternatively, ``Either String`` or
541+``IO`` would be fine, for example.
542+
543+What if we want to extend the evaluator further, with random number
544+generation? To achieve this, we add a new constructor to ``Expr``,
545+which gives a random number up to a maximum value:
546+
547+.. code-block:: idris
548+
549+ data Expr = Val Integer
550+ | Var String
551+ | Add Expr Expr
552+ | Random Integer
553+
554+Then, we need to deal with the new case, making sure that we extend
555+the list of events to include ``RND``. It doen’t matter where ``RND``
556+appears in the list, as long as it is present:
557+
558+.. code-block:: idris
559+
560+ eval : Expr -> { [EXCEPTION String, RND, STATE Env] } Eff Integer
561+
562+ eval (Random upper) = rndInt 0 upper
563+
564+For test purposes, we might also want to print the random number which
565+has been generated:
566+
567+.. code-block:: idris
568+
569+ eval (Random upper) = do val <- rndInt 0 upper
570+ putStrLn (show val)
571+ return val
572+
573+If we try this without extending the effects list, we would see an
574+error something like the following:
575+
576+::
577+
578+ Expr.idr:28:6:When elaborating right hand side of eval:
579+ Can't solve goal
580+ SubList [STDIO]
581+ [(EXCEPTION String), RND, (STATE (List (String, Integer)))]
582+
583+In other words, the ``STDIO`` effect is not available. We can correct
584+this simply by updating the type of ``eval`` to include ``STDIO``.
585+
586+.. code-block:: idris
587+
588+ eval : Expr -> { [STDIO, EXCEPTION String, RND, STATE Env] } Eff Integer
589+
590+Note that using ``STDIO`` will restrict the number of contexts in
591+which ``eval`` can be ``run`` to those which support ``STDIO``, such
592+as ``IO``. Once effect lists get longer, it can be a good idea instead
593+to encapsulate sets of effects in a type synonym. This is achieved as
594+follows, simply by defining a function which computes a type, since
595+types are first class in ``Idris``:
596+
597+.. code-block:: idris
598+
599+ EvalEff : Type -> Type
600+ EvalEff t = { [STDIO, EXCEPTION String, RND, STATE Env] } Eff t
601+
602+ eval : Expr -> EvalEff Integer
docs/effects/state.rstnew file+518
@@ -0,0 +1,518 @@
1+.. _sect-state:
2+
3+=====
4+State
5+=====
6+
7+Many programs, even pure programs, can benefit from locally mutable
8+state. For example, consider a program which tags binary tree nodes
9+with a counter, by an inorder traversal (i.e. counting depth first,
10+left to right). This would perform something like the following:
11+
12+|image|
13+
14+We can describe binary trees with the following data type ``BTree``
15+and ``testTree`` to represent the example input above:
16+
17+.. code-block:: idris
18+
19+ data BTree a = Leaf
20+ | Node (BTree a) a (BTree a)
21+
22+ testTree : BTree String
23+ testTree = Node (Node Leaf "Jim" Leaf)
24+ "Fred"
25+ (Node (Node Leaf "Alice" Leaf)
26+ "Sheila"
27+ (Node Leaf "Bob" Leaf))
28+
29+Then our function to implement tagging, beginning to tag with a
30+specific value ``i``, has the following type:
31+
32+.. code-block:: idris
33+
34+ treeTag : (i : Int) -> BTree a -> BTree (Int, a)
35+
36+First attempt
37+-------------
38+
39+Naïvely, we can implement ``treeTag`` by implementing a helper
40+function which propagates a counter, returning the result of the count
41+for each subtree:
42+
43+.. code-block:: idris
44+
45+ treeTagAux : (i : Int) -> BTree a -> (Int, BTree (Int, a))
46+ treeTagAux i Leaf = (i, Leaf)
47+ treeTagAux i (Node l x r)
48+ = let (i', l') = treeTagAux i l in
49+ let x' = (i', x) in
50+ let (i'', r') = treeTagAux (i' + 1) r in
51+ (i'', Node l' x' r')
52+
53+ treeTag : (i : Int) -> BTree a -> BTree (Int, a)
54+ treeTag i x = snd (treeTagAux i x)
55+
56+This gives the expected result when run at the REPL prompt:
57+
58+.. code-block:: idris
59+
60+ *TreeTag> treeTag 1 testTree
61+ Node (Node Leaf (1, "Jim") Leaf)
62+ (2, "Fred")
63+ (Node (Node Leaf (3, "Alice") Leaf)
64+ (4, "Sheila")
65+ (Node Leaf (5, "Bob") Leaf)) : BTree (Int, String)
66+
67+This works as required, but there are several problems when we try to
68+scale this to larger programs. It is error prone, because we need to
69+ensure that state is propagated correctly to the recursive calls (i.e.
70+passing the appropriate ``i`` or ``i’``). It is hard to read, because
71+the functional details are obscured by the state propagation. Perhaps
72+most importantly, there is a common programming pattern here which
73+should be abstracted but instead has been implemented by hand. There
74+is local mutable state (the counter) which we have had to make
75+explicit.
76+
77+Introducing ``Effects``
78+-----------------------
79+
80+``Idris`` provides a library, ``Effects`` [3]_, which captures this
81+pattern and many others involving effectful computation [1]_. An
82+effectful program ``f`` has a type of the following form:
83+
84+.. code-block:: idris
85+
86+ f : (x1 : a1) -> (x2 : a2) -> ... -> { effs } Eff t
87+
88+That is, the return type gives the effects that ``f`` supports
89+(``effs``, of type ``List EFFECT``) and the type the computation
90+returns ``t``. So, our ``treeTagAux`` helper could be written with the
91+following type:
92+
93+.. code-block:: idris
94+
95+ treeTagAux : BTree a -> { [STATE Int] } Eff (BTree (Int, a))
96+
97+That is, ``treeTagAux`` has access to an integer state, because the
98+list of available effects includes ``STATE Int``. ``STATE`` is
99+declared as follows in the module ``Effect.State`` (that is, we must
100+``import Effect.State`` to be able to use it):
101+
102+.. code-block:: idris
103+
104+ STATE : Type -> EFFECT
105+
106+It is an effect parameterised by a type (by convention, we write
107+effects in all capitals). The ``treeTagAux`` function is an effectful
108+program which builds a new tree tagged with ``Ints``, and is
109+implemented as follows:
110+
111+.. code-block:: idris
112+
113+ treeTagAux Leaf = pure Leaf
114+ treeTagAux (Node l x r)
115+ = do l' <- treeTagAux l
116+ i <- get
117+ put (i + 1)
118+ r' <- treeTagAux r
119+ pure (Node l' (i, x) r')
120+
121+There are several remarks to be made about this implementation.
122+Essentially, it hides the state, which can be accessed using ``get``
123+and updated using ``put``, but it introduces several new features.
124+Specifically, it uses ``do``-notation, binding variables with ``<-``,
125+and a ``pure`` function. There is much to be said about these
126+features, but for our purposes, it suffices to know the following:
127+
128+- ``do`` blocks allow effectful operations to be sequenced.
129+
130+- ``x <- e`` binds the result of an effectful operation ``e`` to a
131+ variable ``x``. For example, in the above code, ``treeTagAux l`` is
132+ an effectful operation returning a pair ``(Int, BTree a)``, so
133+ ``l’`` has type ``(Int, BTree a)``.
134+
135+- ``pure e`` turns a pure value ``e`` into the result of an effectful
136+ operation.
137+
138+The ``get`` and ``put`` functions read and write a state ``t``,
139+assuming that the ``STATE t`` effect is available. They have the
140+following types, polymorphic in the state ``t`` they manage:
141+
142+.. code-block:: idris
143+
144+ get : { [STATE t] } Eff t
145+ put : t -> { [STATE t] } Eff ()
146+
147+A program in ``Eff`` can call any other function in ``Eff`` provided
148+that the calling function supports at least the effects required by
149+the called function. In this case, it is valid for ``treeTagAux`` to
150+call both ``get`` and ``put`` because all three functions support the
151+``STATE Int`` effect.
152+
153+Programs in ``Eff`` are run in some underlying *computation context*,
154+using the ``run`` or ``runPure`` function. Using ``runPure``, which
155+runs an effectful program in the identity context, we can write the
156+``treeTag`` function as follows, using ``put`` to initialise the
157+state:
158+
159+.. code-block:: idris
160+
161+ treeTag : (i : Int) -> BTree a -> BTree (Int, a)
162+ treeTag i x = runPure (do put i
163+ treeTagAux x)
164+
165+We could also run the program in an impure context such as ``IO``,
166+without changing the definition of ``treeTagAux``, by using ``run``
167+instead of ``runPure``:
168+
169+.. code-block:: idris
170+
171+ treeTagAux : BTree a -> { [STATE Int] } Eff (BTree (Int, a))
172+ ...
173+
174+ treeTag : (i : Int) -> BTree a -> IO (BTree (Int, a))
175+ treeTag i x = run (do put i
176+ treeTagAux x)
177+
178+Note that the definition of ``treeTagAux`` is exactly as before. For
179+reference, this complete program (including a ``main`` to run it) is
180+shown in Listing [introprog].
181+
182+.. code-block:: idris
183+
184+ module Main
185+
186+ import Effect.State
187+
188+ data BTree a = Leaf
189+ | Node (BTree a) a (BTree a)
190+
191+ instance Show a => Show (BTree a) where
192+ show Leaf = "[]"
193+ show (Node l x r) = "[" ++ show l ++ " "
194+ ++ show x ++ " "
195+ ++ show r ++ "]"
196+
197+ testTree : BTree String
198+ testTree = Node (Node Leaf "Jim" Leaf)
199+ "Fred"
200+ (Node (Node Leaf "Alice" Leaf)
201+ "Sheila"
202+ (Node Leaf "Bob" Leaf))
203+
204+ treeTagAux : BTree a -> { [STATE Int] } Eff (BTree (Int, a))
205+ treeTagAux Leaf = pure Leaf
206+ treeTagAux (Node l x r) = do l' <- treeTagAux l
207+ i <- get
208+ put (i + 1)
209+ r' <- treeTagAux r
210+ pure (Node l' (i, x) r')
211+
212+ treeTag : (i : Int) -> BTree a -> BTree (Int, a)
213+ treeTag i x = runPure (do put i; treeTagAux x)
214+
215+ main : IO ()
216+ main = print (treeTag 1 testTree)
217+
218+Effects and Resources
219+---------------------
220+
221+Each effect is associated with a *resource*, which is initialised
222+before an effectful program can be run. For example, in the case of
223+``STATE Int`` the corresponding resource is the integer state itself.
224+The types of ``runPure`` and ``run`` show this (slightly simplified
225+here for illustrative purposes):
226+
227+.. code-block:: idris
228+
229+ runPure : {env : Env id xs} -> { xs } Eff a -> a
230+ run : Applicative m => {env : Env m xs} -> { xs } Eff a -> m a
231+
232+The ``env`` argument is implicit, and initialised automatically where
233+possible using default values given by instances of the following type
234+class:
235+
236+.. code-block:: idris
237+
238+ class Default a where
239+ default : a
240+
241+Instances of ``Default`` are defined for all primitive types, and many
242+library types such as ``List``, ``Vect``, ``Maybe``, pairs, etc.
243+However, where no default value exists for a resource type (for
244+example, you may want a ``STATE`` type for which there is no
245+``Default`` instance) the resource environment can be given explicitly
246+using one of the following functions:
247+
248+.. code-block:: idris
249+
250+ runPureInit : Env id xs -> { xs } Eff a -> a
251+ runInit : Applicative m => Env m xs -> { xs } Eff a -> m a
252+
253+To be well-typed, the environment must contain resources corresponding
254+exactly to the effects in ``xs``. For example, we could also have
255+implemented ``treeTag`` by initialising the state as follows:
256+
257+.. code-block:: idris
258+
259+ treeTag : (i : Int) -> BTree a -> BTree (Int, a)
260+ treeTag i x = runPureInit [i] (treeTagAux x)
261+
262+Labelled Effects
263+----------------
264+
265+What if we have more than one state, especially more than one state of
266+the same type? How would ``get`` and ``put`` know which state they
267+should be referring to? For example, how could we extend the tree
268+tagging example such that it additionally counts the number of leaves
269+in the tree? One possibility would be to change the state so that it
270+captured both of these values, e.g.:
271+
272+.. code-block:: idris
273+
274+ treeTagAux : BTree a
275+ -> { [STATE (Int, Int)] } Eff (BTree (Int, a))
276+
277+Doing this, however, ties the two states together throughout (as well
278+as not indicating which integer is which). It would be nice to be able
279+to call effectful programs which guaranteed only to access one of the
280+states, for example. In a larger application, this becomes
281+particularly important.
282+
283+The library therefore allows effects in general to be *labelled* so
284+that they can be referred to explicitly by a particular name. This
285+allows multiple effects of the same type to be included. We can count
286+leaves and update the tag separately, by labelling them as follows:
287+
288+.. code-block:: idris
289+
290+ treeTagAux : BTree a
291+ -> {['Tag ::: STATE Int,
292+ 'Leaves ::: STATE Int]} Eff (BTree (Int, a))
293+
294+The ``:::`` operator allows an arbitrary label to be given to an
295+effect. This label can be any type—it is simply used to identify an
296+effect uniquely. Here, we have used a symbol type. In general
297+``’name`` introduces a new symbol, the only purpose of which is to
298+disambiguate values [2]_.
299+
300+When an effect is labelled, its operations are also labelled using the
301+``:-`` operator. In this way, we can say explicitly which state we
302+mean when using ``get`` and ``put``. The tree tagging program which
303+also counts leaves can be written as follows:
304+
305+.. code-block:: idris
306+
307+ treeTagAux Leaf = do
308+ 'Leaves :- update (+1)
309+ pure Leaf
310+ treeTagAux (Node l x r) = do
311+ l' <- treeTagAux l
312+ i <- 'Tag :- get
313+ 'Tag :- put (i + 1)
314+ r' <- treeTagAux r
315+ pure (Node l' (i, x) r')
316+
317+The ``update`` function here is a combination of ``get`` and ``put``,
318+applying a function to the current state.
319+
320+.. code-block:: idris
321+
322+ update : (x -> x) -> { [STATE x] } Eff ()
323+
324+Finally, our top level ``treeTag`` function now returns a pair of the
325+number of leaves, and the new tree. Resources for labelled effects are
326+intialised using the ``:=`` operator (reminisicent of assignment in an
327+imperative language):
328+
329+.. code-block:: idris
330+
331+ treeTag : (i : Int) -> BTree a -> (Int, BTree (Int, a))
332+ treeTag i x = runPureInit ['Tag := i, 'Leaves := 0]
333+ (do x' <- treeTagAux x
334+ leaves <- 'Leaves :- get
335+ pure (leaves, x'))
336+
337+To summarise, we have:
338+
339+- ``:::`` to convert an effect to a labelled effect.
340+
341+- ``:-`` to convert an effectful operation to a labelled effectful
342+ operation.
343+
344+- ``:=`` to initialise a resource for a labelled effect.
345+
346+Or, more formally with their types (slightly simplified to account
347+only for the situation where available effects are not updated):
348+
349+.. code-block:: idris
350+
351+ (:::) : lbl -> EFFECT -> EFFECT
352+ (:-) : (l : lbl) -> { [x] } Eff a -> { [l ::: x] } Eff a
353+ (:=) : (l : lbl) -> res -> LRes l res
354+
355+Here, ``LRes`` is simply the resource type associated with a labelled
356+effect. Note that labels are polymorphic in the label type ``lbl``.
357+Hence, a label can be anything—a string, an integer, a type, etc.
358+
359+``!``-notation
360+--------------
361+
362+In many cases, using ``do``-notation can make programs unnecessarily
363+verbose, particularly in cases where the value bound is used once,
364+immediately. The following program returns the length of the
365+``String`` stored in the state, for example:
366+
367+.. code-block:: idris
368+
369+ stateLength : { [STATE String] } Eff Nat
370+ stateLength = do x <- get
371+ pure (length x)
372+
373+This seems unnecessarily verbose, and it would be nice to program in a
374+more direct style in these cases. provides ``!``-notation to help with
375+this. The above program can be written instead as:
376+
377+.. code-block:: idris
378+
379+ stateLength : { [STATE String] } Eff Nat
380+ stateLength = pure (length !get)
381+
382+The notation ``!expr`` means that the expression ``expr`` should be
383+evaluated and then implicitly bound. Conceptually, we can think of
384+``!`` as being a prefix function with the following type:
385+
386+.. code-block:: idris
387+
388+ (!) : { xs } Eff a -> a
389+
390+Note, however, that it is not really a function, merely syntax! In
391+practice, a subexpression ``!expr`` will lift ``expr`` as high as
392+possible within its current scope, bind it to a fresh name ``x``, and
393+replace ``!expr`` with ``x``. Expressions are lifted depth first, left
394+to right. In practice, ``!``-notation allows us to program in a more
395+direct style, while still giving a notational clue as to which
396+expressions are effectful.
397+
398+For example, the expression:
399+
400+.. code-block:: idris
401+
402+ let y = 42 in f !(g !(print y) !x)
403+
404+is lifted to:
405+
406+.. code-block:: idris
407+
408+ let y = 42 in do y' <- print y
409+ x' <- x
410+ g' <- g y' x'
411+ f g'
412+
413+Syntactic Sugar and ``Eff``
414+---------------------------
415+
416+By now, you may be wondering about the syntax we are using for
417+``Eff``, because it doesn’t look like a normal type! (If not, you may
418+safely skip this section and return to it later.) In fact, the type of
419+``Eff`` is the following:
420+
421+.. code-block:: idris
422+
423+ Eff : (x : Type) ->
424+ List EFFECT -> (x -> List EFFECT) -> Type
425+
426+This is more general than the types we have been writing so far. It is
427+parameterised over a result type ``x``, as we have already seen, but
428+also a ``List EFFECT`` and a function type ``x -> List EFFECT``.
429+
430+These additional parameters are the list of *input* effects, and a
431+list of *output* effects, computed from the result of an effectful
432+operation. That is: running an effectful program can change the set
433+of effects available! This is a particularly powerful idea, and we
434+will see its consequences in more detail later. Some examples of
435+operations which can change the set of available effects are:
436+
437+- Updating a state containing a dependent type (for example adding an
438+ element to a vector).
439+
440+- Opening a file for reading is an effect, but whether the file really
441+ *is* open afterwards depends on whether the file was successfully
442+ opened.
443+
444+- Closing a file means that reading from the file should no longer be
445+ possible.
446+
447+While powerful, this can make uses of the ``Eff`` type hard to read.
448+Therefore, the library provides syntactic sugar which is translated
449+such that:
450+
451+.. code-block:: idris
452+
453+ { xs } Eff a
454+
455+is expanded to
456+
457+.. code-block:: idris
458+
459+ Eff a xs (\_ => xs)
460+
461+i.e. the set of effects remains the same on output. This suffices for
462+the ``STATE`` example we have seen so far, and for many useful
463+side-effecting programs. We could also have written ``treeTagAux``
464+with the expanded type:
465+
466+.. code-block:: idris
467+
468+ treeTagAux : BTree a ->
469+ Eff (BTree (Int, a)) [STATE Int] (\x => [STATE Int])
470+
471+Later, we will see programs which update effects:
472+
473+.. code-block:: idris
474+
475+ { xs ==> xs' } Eff a
476+
477+which is expanded to
478+
479+.. code-block:: idris
480+
481+ Eff a xs (\_ => xs')
482+
483+i.e. the set of effects is updated to ``xs’`` (think of a transition
484+in a state machine). There is, for example, a version of ``put`` which
485+updates the type of the state:
486+
487+.. code-block:: idris
488+
489+ putM : y -> { [STATE x] ==> [STATE y] } Eff ()
490+
491+Also, we have:
492+
493+.. code-block:: idris
494+
495+ { xs ==> {res} xs' } Eff a
496+
497+which is expanded to
498+
499+.. code-block:: idris
500+
501+ Eff a xs (\res => xs')
502+
503+i.e. the set of effects is updated according to the result of the
504+operation ``res``.
505+
506+.. [1] The earlier paper [3]_ describes the essential implementation
507+ details, although the library presented there is an earlier version
508+ which is less powerful than that presented in this tutorial.
509+
510+.. [2] In practice, ``’name`` simply introduces a new empty type
511+
512+.. [3] Edwin Brady. 2013. Programming and reasoning with algebraic
513+ effects and dependent types. SIGPLAN Not. 48, 9 (September
514+ 2013), 133-144. DOI=10.1145/2544174.2500581
515+ http://doi.acm.org/10.1145/2544174.2500581
516+
517+.. |image| image:: ../image/effects-tree.png
518+ :width: 500px
docs/effects/summary.rstnew file+153
@@ -0,0 +1,153 @@
1+.. _sect-appendix:
2+
3+===============
4+Effects Summary
5+===============
6+
7+This appendix gives interfaces for the core effects provided by the
8+library.
9+
10+EXCEPTION
11+---------
12+
13+.. code-block:: idris
14+
15+ module Effect.Exception
16+
17+ import Effects
18+ import System
19+ import Control.IOExcept
20+
21+ EXCEPTION : Type -> EFFECT
22+
23+ raise : a -> { [EXCEPTION a ] } Eff m b
24+
25+ instance Handler (Exception a) Maybe
26+ instance Handler (Exception a) List
27+ instance Handler (Exception a) (Either a)
28+ instance Handler (Exception a) (IOExcept a)
29+ instance Show a => Handler (Exception a) IO
30+
31+FILE\_IO
32+--------
33+
34+.. code-block:: idris
35+
36+ module Effect.File
37+
38+ import Effects
39+ import Control.IOExcept
40+
41+ FILE_IO : Type -> EFFECT
42+
43+ data OpenFile : Mode -> Type
44+
45+ open : Handler FileIO e => String -> (m : Mode) ->
46+ { [FILE_IO ()] ==>
47+ {ok} [FILE_IO (if ok then OpenFile m else ())] } Eff e Bool
48+ close : Handler FileIO e =>
49+ { [FILE_IO (OpenFile m)] ==> [FILE_IO ()] } Eff e ()
50+
51+ readLine : Handler FileIO e =>
52+ { [FILE_IO (OpenFile Read)] } Eff e String
53+ writeLine : Handler FileIO e => String ->
54+ { [FILE_IO (OpenFile Write)] } Eff e ()
55+ eof : Handler FileIO e =>
56+ { [FILE_IO (OpenFile Read)] } Eff e Bool
57+
58+ instance Handler FileIO IO
59+
60+RND
61+---
62+
63+.. code-block:: idris
64+
65+ module Effect.Random
66+
67+ import Effects
68+ import Data.Vect
69+ import Data.Fin
70+
71+ RND : EFFECT
72+
73+ srand : Integer -> { [RND] } Eff m ()
74+ rndInt : Integer -> Integer -> { [RND] } Eff m Integer
75+ rndFin : (k : Nat) -> { [RND] } Eff m (Fin (S k))
76+
77+ instance Handler Random m
78+
79+SELECT
80+------
81+
82+.. code-block:: idris
83+
84+ module Effect.Select
85+
86+ import Effects
87+
88+ SELECT : EFFECT
89+
90+ select : List a -> { [SELECT] } Eff m a
91+
92+ instance Handler Selection Maybe
93+ instance Handler Selection List
94+
95+STATE
96+-----
97+
98+.. code-block:: idris
99+
100+ module Effect.State
101+
102+ import Effects
103+
104+ STATE : Type -> EFFECT
105+
106+ get : { [STATE x] } Eff m x
107+ put : x -> { [STATE x] } Eff m ()
108+ putM : y -> { [STATE x] ==> [STATE y] } Eff m ()
109+ update : (x -> x) -> { [STATE x] } Eff m ()
110+
111+ instance Handler State m
112+
113+STDIO
114+-----
115+
116+.. code-block:: idris
117+
118+ module Effect.StdIO
119+
120+ import Effects
121+ import Control.IOExcept
122+
123+ STDIO : EFFECT
124+
125+ putChar : Handler StdIO m => Char -> { [STDIO] } Eff m ()
126+ putStr : Handler StdIO m => String -> { [STDIO] } Eff m ()
127+ putStrLn : Handler StdIO m => String -> { [STDIO] } Eff m ()
128+
129+ getStr : Handler StdIO m => { [STDIO] } Eff m String
130+ getChar : Handler StdIO m => { [STDIO] } Eff m Char
131+
132+ instance Handler StdIO IO
133+ instance Handler StdIO (IOExcept a)
134+
135+SYSTEM
136+------
137+
138+.. code-block:: idris
139+
140+ module Effect.System
141+
142+ import Effects
143+ import System
144+ import Control.IOExcept
145+
146+ SYSTEM : EFFECT
147+
148+ getArgs : Handler System e => { [SYSTEM] } Eff e (List String)
149+ time : Handler System e => { [SYSTEM] } Eff e Int
150+ getEnv : Handler System e => String -> { [SYSTEM] } Eff e (Maybe String)
151+
152+ instance Handler System IO
153+ instance Handler System (IOExcept a)
docs/guides/index.rstnew file+21
@@ -0,0 +1,21 @@
1+.. _guides-index:
2+
3+################################
4+Tutorials on the Idris Language
5+################################
6+
7+Tutorials submitted by community members.
8+
9+.. note::
10+ The documentation for Idris has been published under the Creative
11+ Commons CC0 License. As such to the extent possible under law, /The
12+ Idris Community/ has waived all copyright and related or neighboring
13+ rights to Documentation for Idris.
14+
15+ More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/
16+
17+
18+.. toctree::
19+ :maxdepth: 1
20+
21+ type-providers-ffi
docs/guides/type-providers-ffi.rstnew file+290
@@ -0,0 +1,290 @@
1+Type Providers in Idris
2+=======================
3+
4+`Type providers in Idris
5+<http://www.itu.dk/people/drc/pubs/dependent-type-providers.pdf>`__
6+are simple enough, but there are a few caveats to using them that it
7+would be worthwhile to go through the basic steps. We also go over
8+foreign functions, because these will often be used with type
9+providers.
10+
11+The use case
12+------------
13+
14+First, let's talk about *why* we might want type providers. There are
15+a number of reasons to use them and there are other examples available
16+around the net, but in this tutorial we'll be using them to port C's
17+``struct stat`` to Idris.
18+
19+Why do we need type providers? Well, Idris's FFI needs to know the
20+types of the things it passes to and from C, but the fields of a
21+``struct stat`` are implementation-dependent types that cannot be
22+relied upon. We don't just want to hard-code these types into our
23+program... so we'll use a type provider to find them at compile time!
24+
25+A simple example
26+----------------
27+
28+First, let's go over a basic usage of type providers, because foreign
29+functions can be confusing but it's important to remember that
30+providers themselves are simple.
31+
32+A type provider is simply an IO action that returns a value of this
33+type:
34+
35+.. code-block:: idris
36+
37+ data Provider a = Provide a | Error String
38+
39+Looks familiar? ``Provider`` is just ``Either a String``, given a
40+slightly more descriptive name.
41+
42+Remember though, type providers we use in our program must be IO
43+actions. Let's write a simple one now:
44+
45+.. code-block:: idris
46+
47+ module Provider
48+ -- Asks nicely for the user to supply the size of C's size_t type on this
49+ -- machine
50+ getSizeT : IO (Provider Int)
51+ getSizeT = do
52+ putStrLn "I'm sorry, I don't know how big size_t is. Can you tell me, in bytes?"
53+ resp <- getLine
54+ case readInt resp of
55+ Just sizeTSize => return (Provide sizeTSize)
56+ Nothing => return (Error "I'm sorry, I don't understand.")
57+ -- the readInt function is left as an exercise
58+
59+We assume that whoever's compiling the library knows the size of
60+``size_t``, so we'll just ask them! (Don't worry, we'll get it
61+ourselves later.) Then, if their response can be converted to an
62+integer, we present ``Provide sizeTSize`` as the result of our IO
63+action; or if it can't, we signal a failure. (This will then become a
64+compile-time error.)
65+
66+Now we can use this IO action as a type provider:
67+
68+.. code-block:: idris
69+
70+ module Main
71+ -- to gain access to the IO action we're using as a provider
72+ import Provider
73+
74+ -- TypeProviders is an extension, so we'll enable it
75+ %language TypeProviders
76+
77+ -- And finally, use the provider!
78+ -- Note that the parentheses are mandatory.
79+ %provide (sizeTSize : Int) with getSizeT
80+
81+ -- From now on it's just a normal program where `sizeTSize` is available
82+ -- as a top-level constant
83+ main : IO ()
84+ main = do
85+ putStr "Look! I figured out how big size_t is! It's "
86+ putStr (show sizeTSize)
87+ putStr " bytes!"
88+
89+Yay! We... asked the user something at compile time? That's not very
90+good, actually. Our library is going to be difficult to compile! This
91+is hardly a step up from having them edit in the size of ``size_t``
92+themselves!
93+
94+Don't worry, there's a better way.
95+
96+Foreign Functions
97+-----------------
98+
99+It's actually pretty easy to write a C function that figures out the
100+size of ``size_t``:
101+
102+.. code:: c
103+
104+ int sizeof_size_t() { return sizeof(size_t); }
105+
106+(Why an int and not a ``size_t``? The FFI needs to know how to receive
107+the return value of this function and translate it into an Idris
108+value. If we knew how to do this for values of C type ``size_t``, we
109+wouldn't need to write this function at all! If we really wanted to be
110+safe from overflow, we could use an array of multiple integers, but
111+the SIZE of ``size_t`` is never going to be a 65535 byte integer.)
112+
113+So now we can get the size of ``size_t`` as long as we're in C code.
114+We'd like to be able to use this from Idris. Can we do this? It turns
115+out we can.
116+
117+mkForeign
118+~~~~~~~~~
119+
120+With mkForeign, we can turn a C function into an IO action. It works
121+like this:
122+
123+.. code-block:: idris
124+
125+ getSizeT : IO Int
126+ getSizeT = mkForeign (FFun "sizeof_size_t" [] FInt)
127+
128+Pretty simple. ``mkForeign`` takes a specification of what function it
129+needs to call, and we construct this specification with ``FFun``. And
130+``FFun`` just takes a name, a list of argument types (we have none),
131+and a return type.
132+
133+One thing you might want to note: the return type we've specified is
134+``FInt``, not ``Int``. That's because ``Int`` is an idris type and C
135+functions don't return idris types. ``FInt`` is not an idris type, but
136+is just the representation of the type of a C int. It tells the
137+compiler "Treat the return value of this C function like it's a C int,
138+and when you pass it back into Idris, convert it to an Idris int."
139+
140+Caveats of mkForeign
141+^^^^^^^^^^^^^^^^^^^^
142+
143+First and foremost: ``mkForeign`` is not actually a function. It is
144+treated specially by the compiler, and there are certain rules you
145+need to follow when using it.
146+
147+- Rule 1: the name string must be a literal or constant
148+
149+This does not work:
150+
151+.. code-block:: idris
152+
153+ intIntToInt : String -> Int -> Int -> IO Int
154+ intIntToInt name = mkForeign (FFun name [FInt, FInt] FInt)
155+
156+You'll just have to bite the bullet and write out the whole
157+``mkForeign`` and ``FFun`` expression each time.
158+
159+- Rule 2: the "call" to ``mkForeign`` must be fully applied
160+
161+This just means that every argument appearing in the list of argument
162+types must be applied wherever you write ``mkForeign``. The arguments
163+don't have to be literals or even known at compile time; they just
164+have to be there. For example, if we have ``strlen : String -> IO
165+Int``, then this is fine:
166+
167+.. code-block:: idris
168+
169+ strlen str = mkForeign (FFun "strlen" [FString] FInt) str
170+
171+but this is not fine:
172+
173+.. code-block:: idris
174+
175+ strlen = mkForeign (FFun "strlen" [FString] FInt)
176+
177+Note that this only applies to places where you literally typed
178+``mkForeign``. Once you've defined it, ``strlen`` is just a normal
179+function returning an IO action, and it doesn't need to be fully
180+applied. This is okay:
181+
182+.. code-block:: idris
183+
184+ lengths : IO [Int]
185+ lengths = mapM strlen listOfStrings
186+
187+Running foreign functions
188+~~~~~~~~~~~~~~~~~~~~~~~~~
189+
190+This is all well and good for writing code that will typecheck. To
191+actually run the code, we'll need to do just a bit more work. Exactly
192+what we need to do depends on whether we want to interpret or compile
193+our code.
194+
195+In the interpreter
196+^^^^^^^^^^^^^^^^^^
197+
198+If we want to call our foreign functions from interpreted code (such
199+as the REPL or a type provider), we need to dynamically link a library
200+containing the symbols we need. This is pretty easy to do with the
201+``%dynamic`` directive:
202+
203+.. code-block:: idris
204+
205+ %dynamic "./filename.so"
206+
207+Note that the leading "./" is important: currently, the string you
208+provide is interpreted as by ``dlopen()``, which on Unix does not search
209+in the current directory by default. If you use the "./", the library
210+will be searched for in the directory from which you run idris (*not*
211+the location of the file you're running!). Of course, if you're using
212+functions from an installed library rather than something you wrote
213+yourself, the "./" is not necessary.
214+
215+In an executable
216+^^^^^^^^^^^^^^^^
217+
218+If we want to run our code from an executable, we can statically link
219+instead. We'll use the ``%include`` and ``%link`` directives:
220+
221+.. code-block:: idris
222+
223+ %include C "filename.h"
224+ %link C "filename.o"
225+
226+Note the extra argument to the directive! We specify that we're
227+linking a C header and library. Also, unlike ``%dynamic``, these
228+directives search in the current directory by default. (That is, the
229+directory from which we run idris.)
230+
231+Putting it all together
232+-----------------------
233+
234+So, at the beginning of this article I said we'd use type providers to
235+port ``struct stat`` to Idris. The relevant part is just translating
236+all the mysterious typedef'd C types into Idris types, and that's what
237+we'll do here.
238+
239+First, let's write a C file containing functions that we'll bind to.
240+
241+.. code-block:: c
242+
243+ /* stattypes.c */
244+ int sizeof_dev_t() { return sizeof(dev_t); }
245+ int sizeof_ino_t() { return sizeof(ino_t); }
246+ /* lots more functions like this */
247+
248+Next, an Idris file to define our providers:
249+
250+.. code-block:: idris
251+
252+ -- Providers.idr
253+ module Providers
254+
255+ %dynamic "./stattypes.so"
256+
257+ sizeOfDevT : IO Int
258+ sizeOfDevT = mkForeign (FFun "sizeof_dev_t" [] FInt)
259+ {- lots of similar functions -}
260+
261+ -- now we have an integer, but we want a Provider FTy
262+ -- since our sizeOf* functions are ordinary IO actions, we
263+ -- can just map over them.
264+ bytesToType : Int -> Provider FTy
265+ bytesToType 1 = Provide (FIntT IT8) -- "8 bit foreign integer"
266+ bytesToType 2 = Provide (FIntT IT16)
267+ bytesToType 4 = Provide (FIntT IT32)
268+ bytesToType 8 = Provide (FIntT IT64)
269+ bytesToType _ = Error "Unrecognized integral type."
270+
271+ getDevT : IO (Provider FTy)
272+ getDevT = map bytesToType sizeOfDevT
273+ {- lots of similar functions -}
274+
275+Finally, we'll write one more idris file where we use the type
276+providers:
277+
278+.. code-block:: idris
279+
280+ -- Main.idr
281+ module Main
282+ import Providers
283+ %language TypeProviders
284+ %provide (FDevT : FTy) with getDevT
285+
286+ -- interpFTy translates a foreign type to the corresponding idris type
287+ DevT : Type
288+ DevT = interpFTy FDevT -- on most systems, DevT = Bits64
289+
290+ -- We can now use DevT in our program and FDevT in our FFun expressions!
docs/image/effects-tree.pngnew file

Binary file not shown.

docs/index.rstnew file+84
@@ -0,0 +1,84 @@
1+.. Idris Manual documentation master file, created by
2+ sphinx-quickstart on Sat Feb 28 20:41:47 2015.
3+ You can adapt this file completely to your liking, but it should at least
4+ contain the root `toctree` directive.
5+
6+Documentation for the Idris Language
7+====================================
8+
9+ This work is licensed under the Creative Commons
10+ Attribution-ShareAlike 4.0 International License. To view a copy
11+ of this license, visit
12+ http://creativecommons.org/licenses/by-sa/4.0/.
13+
14+* :ref:`reference-index`
15+* :ref:`tutorial-index`
16+* :ref:`eff-tutorial-index`
17+* :ref:`guides-index`
18+
19+
20+.. _reference:
21+
22+##################
23+Language Reference
24+##################
25+
26+.. toctree::
27+ :maxdepth: 1
28+
29+ reference/documenting
30+ reference/uniqueness-types
31+ reference/ffi
32+ reference/erasure
33+
34+.. _tutorial:
35+
36+###################
37+The Idris Tutorial
38+###################
39+
40+.. toctree::
41+ :maxdepth: 1
42+
43+ tutorial/introduction
44+ tutorial/starting
45+ tutorial/typesfuns
46+ tutorial/classes
47+ tutorial/modules
48+ tutorial/interp
49+ tutorial/views
50+ tutorial/theorems
51+ tutorial/provisional
52+ tutorial/interactive
53+ tutorial/syntax
54+ tutorial/miscellany
55+ tutorial/conclusions
56+
57+.. _effects:
58+
59+################
60+Learning Effects
61+################
62+
63+.. toctree::
64+ :maxdepth: 1
65+
66+ effects/introduction
67+ effects/state
68+ effects/simpleeff
69+ effects/depeff
70+ effects/impleff
71+ effects/hangman
72+ effects/conclusions
73+ effects/summary
74+
75+.. _guides:
76+
77+############
78+Short Guides
79+############
80+
81+.. toctree::
82+ :maxdepth: 1
83+
84+ guides/type-providers-ffi
docs/listing/idris-prompt-helloworld.txtnew file+15
@@ -0,0 +1,15 @@
1+$ idris hello.idr
2+ ____ __ _
3+ / _/___/ /____(_)____
4+ / // __ / ___/ / ___/ Version 0.9.17
5+ _/ // /_/ / / / (__ ) http://www.idris-lang.org/
6+ /___/\__,_/_/ /_/____/ Type :? for help
7+
8+Type checking ./hello.idr
9+*hello> :t main
10+Main.main : IO ()
11+*hello> :c hello
12+*hello> :q
13+Bye bye
14+$ ./hello
15+Hello world
docs/listing/idris-prompt-interp.txtnew file+12
@@ -0,0 +1,12 @@
1+$ idris interp.idr
2+ ____ __ _
3+ / _/___/ /____(_)____
4+ / // __ / ___/ / ___/ Version 0.9.17
5+ _/ // /_/ / / / (__ ) http://www.idris-lang.org/
6+ /___/\__,_/_/ /_/____/ Type :? for help
7+
8+Type checking ./interp.idr
9+*interp> :exec
10+Enter a number: 6
11+720
12+*interp>
docs/listing/idris-prompt-start.txtnew file+8
@@ -0,0 +1,8 @@
1+$ idris
2+ ____ __ _
3+ / _/___/ /____(_)____
4+ / // __ / ___/ / ___/ Version 0.9.17
5+ _/ // /_/ / / / (__ ) http://www.idris-lang.org/
6+/___/\__,_/_/ /_/____/ Type :? for help
7+
8+Idris>
docs/make.batnew file+263
@@ -0,0 +1,263 @@
1+@ECHO OFF
2+
3+REM Command file for Sphinx documentation
4+
5+if "%SPHINXBUILD%" == "" (
6+ set SPHINXBUILD=sphinx-build
7+)
8+set BUILDDIR=_build
9+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10+set I18NSPHINXOPTS=%SPHINXOPTS% .
11+if NOT "%PAPER%" == "" (
12+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14+)
15+
16+if "%1" == "" goto help
17+
18+if "%1" == "help" (
19+ :help
20+ echo.Please use `make ^<target^>` where ^<target^> is one of
21+ echo. html to make standalone HTML files
22+ echo. dirhtml to make HTML files named index.html in directories
23+ echo. singlehtml to make a single large HTML file
24+ echo. pickle to make pickle files
25+ echo. json to make JSON files
26+ echo. htmlhelp to make HTML files and a HTML help project
27+ echo. qthelp to make HTML files and a qthelp project
28+ echo. devhelp to make HTML files and a Devhelp project
29+ echo. epub to make an epub
30+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31+ echo. text to make text files
32+ echo. man to make manual pages
33+ echo. texinfo to make Texinfo files
34+ echo. gettext to make PO message catalogs
35+ echo. changes to make an overview over all changed/added/deprecated items
36+ echo. xml to make Docutils-native XML files
37+ echo. pseudoxml to make pseudoxml-XML files for display purposes
38+ echo. linkcheck to check all external links for integrity
39+ echo. doctest to run all doctests embedded in the documentation if enabled
40+ echo. coverage to run coverage check of the documentation if enabled
41+ goto end
42+)
43+
44+if "%1" == "clean" (
45+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
46+ del /q /s %BUILDDIR%\*
47+ goto end
48+)
49+
50+
51+REM Check if sphinx-build is available and fallback to Python version if any
52+%SPHINXBUILD% 2> nul
53+if errorlevel 9009 goto sphinx_python
54+goto sphinx_ok
55+
56+:sphinx_python
57+
58+set SPHINXBUILD=python -m sphinx.__init__
59+%SPHINXBUILD% 2> nul
60+if errorlevel 9009 (
61+ echo.
62+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
63+ echo.installed, then set the SPHINXBUILD environment variable to point
64+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
65+ echo.may add the Sphinx directory to PATH.
66+ echo.
67+ echo.If you don't have Sphinx installed, grab it from
68+ echo.http://sphinx-doc.org/
69+ exit /b 1
70+)
71+
72+:sphinx_ok
73+
74+
75+if "%1" == "html" (
76+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
77+ if errorlevel 1 exit /b 1
78+ echo.
79+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
80+ goto end
81+)
82+
83+if "%1" == "dirhtml" (
84+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
85+ if errorlevel 1 exit /b 1
86+ echo.
87+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
88+ goto end
89+)
90+
91+if "%1" == "singlehtml" (
92+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
93+ if errorlevel 1 exit /b 1
94+ echo.
95+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
96+ goto end
97+)
98+
99+if "%1" == "pickle" (
100+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
101+ if errorlevel 1 exit /b 1
102+ echo.
103+ echo.Build finished; now you can process the pickle files.
104+ goto end
105+)
106+
107+if "%1" == "json" (
108+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
109+ if errorlevel 1 exit /b 1
110+ echo.
111+ echo.Build finished; now you can process the JSON files.
112+ goto end
113+)
114+
115+if "%1" == "htmlhelp" (
116+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
117+ if errorlevel 1 exit /b 1
118+ echo.
119+ echo.Build finished; now you can run HTML Help Workshop with the ^
120+.hhp project file in %BUILDDIR%/htmlhelp.
121+ goto end
122+)
123+
124+if "%1" == "qthelp" (
125+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
126+ if errorlevel 1 exit /b 1
127+ echo.
128+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
129+.qhcp project file in %BUILDDIR%/qthelp, like this:
130+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\IdrisManual.qhcp
131+ echo.To view the help file:
132+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\IdrisManual.ghc
133+ goto end
134+)
135+
136+if "%1" == "devhelp" (
137+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
138+ if errorlevel 1 exit /b 1
139+ echo.
140+ echo.Build finished.
141+ goto end
142+)
143+
144+if "%1" == "epub" (
145+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
146+ if errorlevel 1 exit /b 1
147+ echo.
148+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
149+ goto end
150+)
151+
152+if "%1" == "latex" (
153+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
154+ if errorlevel 1 exit /b 1
155+ echo.
156+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
157+ goto end
158+)
159+
160+if "%1" == "latexpdf" (
161+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
162+ cd %BUILDDIR%/latex
163+ make all-pdf
164+ cd %~dp0
165+ echo.
166+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
167+ goto end
168+)
169+
170+if "%1" == "latexpdfja" (
171+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
172+ cd %BUILDDIR%/latex
173+ make all-pdf-ja
174+ cd %~dp0
175+ echo.
176+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
177+ goto end
178+)
179+
180+if "%1" == "text" (
181+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
182+ if errorlevel 1 exit /b 1
183+ echo.
184+ echo.Build finished. The text files are in %BUILDDIR%/text.
185+ goto end
186+)
187+
188+if "%1" == "man" (
189+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
190+ if errorlevel 1 exit /b 1
191+ echo.
192+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
193+ goto end
194+)
195+
196+if "%1" == "texinfo" (
197+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
198+ if errorlevel 1 exit /b 1
199+ echo.
200+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
201+ goto end
202+)
203+
204+if "%1" == "gettext" (
205+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
206+ if errorlevel 1 exit /b 1
207+ echo.
208+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
209+ goto end
210+)
211+
212+if "%1" == "changes" (
213+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
214+ if errorlevel 1 exit /b 1
215+ echo.
216+ echo.The overview file is in %BUILDDIR%/changes.
217+ goto end
218+)
219+
220+if "%1" == "linkcheck" (
221+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
222+ if errorlevel 1 exit /b 1
223+ echo.
224+ echo.Link check complete; look for any errors in the above output ^
225+or in %BUILDDIR%/linkcheck/output.txt.
226+ goto end
227+)
228+
229+if "%1" == "doctest" (
230+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
231+ if errorlevel 1 exit /b 1
232+ echo.
233+ echo.Testing of doctests in the sources finished, look at the ^
234+results in %BUILDDIR%/doctest/output.txt.
235+ goto end
236+)
237+
238+if "%1" == "coverage" (
239+ %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
240+ if errorlevel 1 exit /b 1
241+ echo.
242+ echo.Testing of coverage in the sources finished, look at the ^
243+results in %BUILDDIR%/coverage/python.txt.
244+ goto end
245+)
246+
247+if "%1" == "xml" (
248+ %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
249+ if errorlevel 1 exit /b 1
250+ echo.
251+ echo.Build finished. The XML files are in %BUILDDIR%/xml.
252+ goto end
253+)
254+
255+if "%1" == "pseudoxml" (
256+ %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
257+ if errorlevel 1 exit /b 1
258+ echo.
259+ echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
260+ goto end
261+)
262+
263+:end
docs/reference/documenting.rstnew file+135
@@ -0,0 +1,135 @@
1+.. _sect-documenting:
2+
3+======================
4+Documenting Idris Code
5+======================
6+
7+Idris documentation comes in two major forms: comments, which exist
8+for a reader’s edification and are ignored by the compiler, and inline
9+API documentation, which the compiler parses and stores for future
10+reference. To consult the documentation for a declaration ``f``, write
11+``:doc f`` at the REPL or use the appropriate command in your editor
12+(``C-c C-d`` in Emacs, in Vim).
13+
14+Comments
15+--------
16+
17+Use comments to explain why code is written the way that it
18+is. Idris’s comment syntax is the same as that of Haskell: lines
19+beginning with ``--`` are comments, and regions bracketed by ``{-``
20+and ``-}`` are comments even if they extend across multiple
21+lines. These can be used to comment out lines of code or provide
22+simple documentation for the readers of Idris code.
23+
24+Inline Documentation
25+--------------------
26+
27+Idris also supports a comprehensive and rich inline syntax for Idris
28+code to be generated. This syntax also allows for named parameters and
29+variables within type signatures to be individually annotated using a
30+syntax similar to Javadoc parameter annotations.
31+
32+Documentation always comes before the declaration being documented.
33+Inline documentation applies to either top-level declarations or to
34+constructors. Documentation for specific arguments to constructors, type
35+constructors, or functions can be associated with these arguments using
36+their names.
37+
38+The inline documentation for a declaration is an unbroken string of
39+lines, each of which begins with ``|||`` (three pipe symbols). The
40+first paragraph of the documentation is taken to be an overview, and
41+in some contexts, only this overview will be shown. After the
42+documentation for the declaration as a whole, it is possible to
43+associate documetation with specific named parameters, which can
44+either be explicitly name or the results of converting free variables
45+to implicit parameters. Annotations are the same as with Javadoc
46+annotations, that is for the named parameter ``(n : T)``, the
47+corresponding annotation is ``||| @ n Some description`` that is
48+placed before the declaration.
49+
50+Documentation is written in Markdown, though not all contexts will
51+display all possible formatting (for example, images are not displayed
52+when viewing documentation in the REPL, and only some terminals render
53+italics correctly). A comprehensive set of examples is given below.
54+
55+.. code-block:: idris
56+
57+
58+ ||| Modules can also be documented.
59+ module Docs
60+
61+ ||| Add some numbers.
62+ |||
63+ ||| Addition is really great. This paragraph is not part of the overview.
64+ ||| Still the same paragraph. Lists are also nifty:
65+ ||| * Really nifty!
66+ ||| * Yep!
67+ ||| * The name `add` is a **bold** choice
68+ ||| @ n is the recursive param
69+ ||| @ m is not
70+ add : (n, m : Nat) -> Nat
71+ add Z m = m
72+ add (S n) m = S (add n m)
73+
74+
75+ ||| Append some vectors
76+ ||| @ a the contents of the vectors
77+ ||| @ xs the first vector (recursive param)
78+ ||| @ ys the second vector (not analyzed)
79+ appendV : (xs : Vect n a) -> (ys : Vect m a) -> Vect (add n m) a
80+ appendV [] ys = ys
81+ appendV (x::xs) ys = x :: appendV xs ys
82+
83+ ||| Here's a simple datatype
84+ data Ty =
85+ ||| Unit
86+ UNIT |
87+ ||| Functions
88+ ARR Ty Ty
89+
90+ ||| Points to a place in a typing context
91+ data Elem : Vect n Ty -> Ty -> Type where
92+ Here : {ts : Vect n Ty} -> Elem (t::ts) t
93+ There : {ts : Vect n Ty} -> Elem ts t -> Elem (t'::ts) t
94+
95+ ||| A more interesting datatype
96+ ||| @ n the number of free variables
97+ ||| @ ctxt a typing context for the free variables
98+ ||| @ ty the type of the term
99+ data Term : (ctxt : Vect n Ty) -> (ty : Ty) -> Type where
100+
101+ ||| The consructor of the unit type
102+ ||| More comment
103+ ||| @ ctxt the typing context
104+ UnitCon : {ctxt : Vect n Ty} -> Term ctxt UNIT
105+
106+ ||| Function application
107+ ||| @ f the function to apply
108+ ||| @ x the argument
109+ App : {ctxt : Vect n Ty} -> (f : Term ctxt (ARR t1 t2)) -> (x : Term ctxt t1) -> Term ctxt t2
110+
111+ ||| Lambda
112+ ||| @ body the function body
113+ Lam : {ctxt : Vect n Ty} -> (body : Term (t1::ctxt) t2) -> Term ctxt (ARR t1 t2)
114+
115+ ||| Variables
116+ ||| @ i de Bruijn index
117+ Var : {ctxt : Vect n Ty} -> (i : Elem ctxt t) -> Term ctxt t
118+
119+ ||| A computation that may someday finish
120+ codata Partial : Type -> Type where
121+
122+ ||| A finished computation
123+ ||| @ value the result
124+ Now : (value : a) -> Partial a
125+
126+ ||| A not-yet-finished computation
127+ ||| @ rest the remaining work
128+ Later : (rest : Partial a) -> Partial a
129+
130+ ||| We can document records just like normal data
131+ record Yummy : Type where
132+
133+ ||| Make a yummy
134+ ||| @ food what to eat
135+ MkYummy : (food : String) -> Yummy
docs/reference/erasure.rstnew file+501
@@ -0,0 +1,501 @@
1+Erasure By Usage Analysis
2+=========================
3+
4+This work stems from this `feature proposal
5+<https://github.com/idris-lang/Idris-dev/wiki/Egg-%232%3A-Erasure-annotations>`__
6+(obsoleted by this page). Beware that the information in the proposal
7+is out of date — and sometimes even in direct contradiction with the
8+eventual implementation.
9+
10+Motivation
11+----------
12+
13+Traditional dependently typed languages (Agda, Coq) are good at
14+erasing *proofs* (either via irrelevance or an extra universe).
15+
16+.. code-block:: idris
17+
18+ half : (n : Nat) -> Even n -> Nat
19+ half Z EZ = Z
20+ half (S (S n)) (ES pf) = S (half n pf)
21+
22+For example, in the above snippet, the second argument is a proof,
23+which is used only to convince the compiler that the function is
24+total. This proof is never inspected at runtime and thus can be
25+erased. In this case, the mere existence of the proof is sufficient
26+and we can use irrelevance-related methods to achieve erasure.
27+
28+However, sometimes we want to erase *indices* and this is where the
29+traditional approaches stop being useful, mainly for reasons described
30+in the `original proposal
31+<https://github.com/idris-lang/Idris-dev/wiki/Egg-%232%3A-Erasure-annotations#prop-is-cumbersome-coq>`__.
32+
33+.. code-block:: idris
34+
35+ uninterleave : {n : Nat} -> Vect (n * 2) a -> (Vect n a, Vect n a)
36+ uninterleave [] = ([] , [])
37+ uninterleave (x :: y :: rest) with (unzipPairs rest)
38+ | (xs, ys) = (x :: xs, y :: ys)
39+
40+Notice that in this case, the second argument is the important one and
41+we would like to get rid of the ``n`` instead, although the shape of
42+the program is generally the same as in the previous case.
43+
44+There are methods described by Brady, McBride and McKinna in [BMM04]_
45+to remove the indices from data structures, exploiting the fact that
46+functions operating on them either already have a copy of the
47+appropriate index or the index can be quickly reconstructed if needed.
48+However, we often want to erase the indices altogether, from the whole
49+program, even in those cases where reconstruction is not possible.
50+
51+The following two sections describe two cases where doing so improves
52+the runtime performance asymptotically.
53+
54+Binary numbers
55+~~~~~~~~~~~~~~
56+
57+- O(n) instead of O(log n)
58+
59+Consider the following ``Nat``-indexed type family representing binary
60+numbers:
61+
62+.. code-block:: idris
63+
64+ data Bin : Nat -> Type where
65+ N : Bin 0
66+ O : {n : Nat} -> Bin n -> Bin (0 + 2*n)
67+ I : {n : Nat} -> Bin n -> Bin (1 + 2*n)
68+
69+These are supposed to be (at least asymptotically) fast and
70+memory-efficient because their size is logarithmic compared to the
71+numbers they represent.
72+
73+Unfortunately this is not the case. The problem is that these binary
74+numbers still carry the *unary* indices with them, performing
75+arithmetic on the indices whenever arithmetic is done on the binary
76+numbers themselves. Hence the real representation of the number 15
77+looks like this:
78+
79+::
80+
81+ I -> I -> I -> I -> N
82+ S S S Z
83+ S S Z
84+ S S
85+ S Z
86+ S
87+ S
88+ S
89+ Z
90+
91+The used memory is actually *linear*, not logarithmic and therefore we
92+cannot get below O(n) with time complexities.
93+
94+One could argue that Idris in fact compiles ``Nat`` via GMP but
95+that's a moot point for two reasons:
96+
97+* First, whenever we try to index our datastructures with anything
98+else than ``Nat``, the compiler is not going to come to the rescue.
99+
100+* Second, even with ``Nat``, the GMP integers are *still* there and
101+they slow the runtime down.
102+
103+This ought not to be the case since the ``Nat`` are never used at
104+runtime and they are only there for typechecking purposes. Hence we
105+should get rid of them and get runtime code similar to what a idris
106+programmer would write.
107+
108+U-views of lists
109+~~~~~~~~~~~~~~~~
110+
111+- O(n^2) instead of O(n)
112+
113+Consider the type of U-views of lists:
114+
115+.. code-block:: idris
116+
117+ data U : List a -> Type where
118+ nil : U []
119+ one : (z : a) -> U [z]
120+ two : {xs : List a} -> (x : a) -> (u : U xs) -> (y : a) -> U (x :: xs ++ [y])
121+
122+For better intuition, the shape of the U-view of
123+``[x0,x1,x2,z,y2,y1,y0]`` looks like this:
124+
125+::
126+
127+ x0 y0 (two)
128+ x1 y1 (two)
129+ x2 y1 (two)
130+ z (one)
131+
132+When recursing over this structure, the values of ``xs`` range over
133+``[x0,x1,x2,z,y2,y1,y0]``, ``[x1,x2,z,y2,y1]``, ``[x2,z,y2]``,
134+``[z]``. No matter whether these lists are stored or built on demand,
135+they take up a quadratic amount of memory (because they cannot share
136+nodes), and hence it takes a quadratic amount of time just to build
137+values of this index alone.
138+
139+But the reasonable expectation is that operations with U-views take
140+linear time — so we need to erase the index ``xs`` if we want to
141+achieve this goal.
142+
143+Changes to Idris
144+----------------
145+
146+Usage analysis is run at every compilation and its outputs are used
147+for various purposes. This is actually invisible to the user but it's
148+a relatively big and important change, which enables the new features.
149+
150+Everything that is found to be unused is erased. No annotations are
151+needed, just don't use the thing and it will vanish from the generated
152+code. However, if you wish, you can use the dot annotations to get a
153+warning if the thing is accidentally used.
154+
155+"Being used" in this context means that the value of the "thing" may
156+influence run-time behaviour of the program. (More precisely, it is
157+not found to be irrelevant to the run-time behaviour by the usage
158+analysis algorithm.)
159+
160+"Things" considered for removal by erasure include:
161+
162+* function arguments
163+
164+* data constructor fields (including record fields and dictionary
165+ fields of class instances)
166+
167+For example, ``Either`` often compiles to the same runtime
168+representation as ``Bool``. Constructor field removal sometimes
169+combines with the newtype optimisation to have quite a strong effect.
170+
171+There is a new compiler option ``--warnreach``, which will enable
172+warnings coming from erasure. Since we have full usage analysis, we
173+can compile even those programs that violate erasure annotations --
174+it's just that the binaries may run slower than expected. The warnings
175+will be enabled by default in future versions of Idris (and possibly
176+turned to errors). However, in this transitional period, we chose to
177+keep them on-demand to avoid confusion until better documentation is
178+written.
179+
180+Case-tree elaboration tries to avoid using dotted "things" whenever
181+possible. (NB. This is not yet perfect and it's being worked on:
182+https://gist.github.com/ziman/10458331)
183+
184+Postulates are no longer required to be collapsible. They are now
185+required to be *unused* instead.
186+
187+Changes to the language
188+-----------------------
189+
190+You can use dots to mark fields that are not intended to be used at
191+runtime.
192+
193+.. code-block:: idris
194+
195+ data Bin : Nat -> Type where
196+ N : Bin 0
197+ O : .{n : Nat} -> Bin n -> Bin (0 + 2*n)
198+ I : .{n : Nat} -> Bin n -> Bin (1 + 2*n)
199+
200+If these fields are found to be used at runtime, the dots will trigger
201+a warning (with ``--warnreach``).
202+
203+Note that free (unbound) implicits are dotted by default so, for
204+example, the constructor ``O`` can be defined as:
205+
206+.. code-block:: idris
207+
208+ O : Bin n -> Bin (0 + 2*n)
209+
210+and this is actually the preferred form.
211+
212+If you have a free implicit which is meant to be used at runtime, you
213+have to change it into an (undotted) ``{bound : implicit}``.
214+
215+You can also put dots in types of functions to get more guarantees.
216+
217+.. code-block:: idris
218+
219+ half : (n : Nat) -> .(pf : Even n) -> Nat
220+
221+and free implicits are automatically dotted here, too.
222+
223+What it means
224+-------------
225+
226+Dot annotations serve two purposes:
227+
228+* influence case-tree elaboration to avoid dotted variables
229+
230+* trigger warnings when a dotted variable is used
231+
232+However, there's no direct connection between being dotted and being
233+erased. The compiler erases everything it can, dotted or not. The dots
234+are there mainly to help the programmer (and the compiler) refrain
235+from using the values they want to erase.
236+
237+How to use it
238+-------------
239+
240+Ideally, few or no extra annotations are needed -- in practice, it
241+turns out that having free implicits automatically dotted is enough to
242+get good erasure.
243+
244+Therefore, just compile with ``--warnreach`` to see warnings if
245+erasure cannot remove parts of the program.
246+
247+However, those programs that have been written without runtime
248+behaviour in mind, will need some help to get in the form that
249+compiles to a reasonable binary. Generally, it's sufficient to follow
250+erasure warnings (which may be sometimes unhelpful at the moment).
251+
252+Benchmarks
253+----------
254+
255+- source: https://github.com/ziman/idris-benchmarks
256+- results: http://ziman.functor.sk/erasure-bm/
257+
258+It can be clearly seen that asymptotics are improved by erasure.
259+
260+Shortcomings
261+------------
262+
263+You can't get warnings in libraries because usage analysis starts from
264+``Main.main``. This will be solved by the planned ``%default_usage``
265+pragma.
266+
267+Usage warnings are quite bad and unhelpful at the moment. We should
268+include more information and at least translate argument numbers to
269+their names.
270+
271+There is no decent documentation yet. This wiki page is the first one.
272+
273+There is no generally accepted terminology. We switch between
274+"dotted", "unused", "erased", "irrelevant", "inaccessible", while each
275+has a slightly different meaning. We need more consistent and
276+understandable naming.
277+
278+If the same type is used in both erased and non-erased context, it
279+will retain its fields to accomodate the least common denominator --
280+the non-erased context. This is particularly troublesome in the case
281+of the type of (dependent) pairs, where it actually means that no
282+erasure would be performed. We should probably locate disjoint uses of
283+data types and split them into "sub-types". There are three different
284+flavours of dependent types now: ``Sigma`` (nothing erased),
285+``Exists`` (first component erased), ``Subset`` (second component
286+erased).
287+
288+Case-tree building does not avoid dotted values coming from
289+pattern-matched constructors (https://gist.github.com/ziman/10458331).
290+This is to be fixed soon. (Fixed.)
291+
292+Higher-order function arguments and opaque functional variables are
293+considered to be using all their arguments. To work around this, you
294+can force erasure via the type system, using the ``Erased`` wrapper:
295+https://github.com/idris-lang/Idris-dev/blob/master/libs/base/Data/Erased.idr
296+
297+Typeclass methods are considered to be using the union of all their
298+implementations. In other words, an argument of a method is unused
299+only if it is unused in every implementation of the method that occurs
300+in the program.
301+
302+Planned features
303+----------------
304+
305+- Fixes to the above shortcomings in general.
306+
307+- Improvements to the case-tree elaborator so that it properly avoids
308+ dotted fields of data constructors. Done.
309+
310+- Compiler pragma ``%default_usage used/unused`` and per-function
311+ overrides ``used`` and ``unused``, which allow the programmer to
312+ mark the return value of a function as used, even if the function
313+ is not used in ``main`` (which is the case when writing library
314+ code). These annotations will help library writers discover usage
315+ violations in their code before it is actually published and used
316+ in compiled programs.
317+
318+Troubleshooting
319+---------------
320+
321+My program is slower
322+~~~~~~~~~~~~~~~~~~~~
323+
324+The patch introducing erasure by usage analysis also disabled some
325+optimisations that were in place before; these are subsumed by the new
326+erasure. However, in some erasure-unaware programs, where erasure by
327+usage analysis does not exercise its full potential (but the old
328+optimisations would have worked), certain slowdown may be observed (up
329+to ~10% according to preliminary benchmarking), due to retention and
330+computation of information that should not be necessary at runtime.
331+
332+A simple check whether this is the case is to compile with
333+``--warnreach``. If you see warnings, there is some unnecessary code
334+getting compiled into the binary.
335+
336+The solution is to change the code so that there are no warnings.
337+
338+Usage warnings are unhelpful
339+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
340+
341+This is a known issue and we are working on it. For now, see the section
342+`How to read and resolve erasure
343+warnings <#how-to-read-and-resolve-erasure-warnings>`__.
344+
345+There should be no warnings in this function
346+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
347+
348+A possible cause is non-totality of the function (more precisely,
349+non-coverage). If a function is non-covering, the program needs to
350+inspect all arguments in order to detect coverage failures at runtime.
351+Since the function inspects all its arguments, nothing can be erased
352+and this may transitively cause usage violations. The solution is to
353+make the function total or accept the fact that it will use its
354+arguments and remove some dots from the appropriate constructor fields
355+and function arguments. (Please note that this is not a shortcoming of
356+erasure and there is nothing we can do about it.)
357+
358+Another possible cause is the currently imperfect case-tree
359+elaboration, which does not avoid dotted constructor fields (see
360+https://gist.github.com/ziman/10458331). You can either rephrase the
361+function or wait until this is fixed, hopefully soon. Fixed.
362+
363+The compiler refuses to recognise this thing as erased
364+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
365+
366+You can force anything to be erased by wrapping it in the ``Erased``
367+monad. While this program triggers usage warnings,
368+
369+.. code-block:: idris
370+
371+ f : (g : Nat -> Nat) -> .(x : Nat) -> Nat
372+ f g x = g x -- WARNING: g uses x
373+
374+the following program does not:
375+
376+.. code-block:: idris
377+
378+ f : (g : Erased Nat -> Nat) -> .(x : Nat) -> Nat
379+ f g x = g (Erase x) -- OK
380+
381+How to read and resolve erasure warnings
382+----------------------------------------
383+
384+Example 1
385+~~~~~~~~~
386+
387+Consider the following program:
388+
389+.. code-block:: idris
390+
391+ vlen : Vect n a -> Nat
392+ vlen {n = n} xs = n
393+
394+ sumLengths : List (Vect n a) -> Nat
395+ sumLengths [] = 0
396+ sumLengths (v :: vs) = vlen v + sumLengths vs
397+
398+ main : IO ()
399+ main = print . sumLengths $ [[0,1],[2,3]]
400+
401+When you compile it using ``--warnreach``, there is one warning:
402+
403+.. code-block:: idris
404+
405+ Main.sumLengths: inaccessible arguments reachable:
406+ n (no more information available)
407+
408+The warning does not contain much detail at this point so we can try
409+compiling with ``--dumpcases cases.txt`` and look up the compiled
410+definition in ``cases.txt``:
411+
412+.. code-block:: idris
413+
414+ Main.sumLengths {e0} {e1} {e2} =
415+ case {e2} of
416+ | Prelude.List.::({e6}) => LPlus (ATInt ITBig)({e0}, Main.sumLengths({e0}, ____, {e6}))
417+ | Prelude.List.Nil() => 0
418+
419+The reason for the warning is that ``sumLengths`` calls ``vlen``, which
420+gets inlined. The second clause of ``sumLengths`` then accesses the
421+variable ``n``, compiled as ``{e0}``. Since ``n`` is a free implicit, it
422+is automatically considered dotted and this triggers the warning.
423+
424+A solution would be either making the argument ``n`` a bound implicit
425+parameter to indicate that we wish to keep it at runtime,
426+
427+.. code-block:: idris
428+
429+ sumLengths : {n : Nat} -> List (Vect n a) -> Nat
430+
431+or fixing ``vlen`` to not use the index:
432+
433+.. code-block:: idris
434+
435+ vlen : Vect n a -> Nat
436+ vlen [] = Z
437+ vlen (x :: xs) = S (vlen xs)
438+
439+Which solution is appropriate depends on the usecase.
440+
441+Example 2
442+~~~~~~~~~
443+
444+Consider the following program manipulating value-indexed binary
445+numbers.
446+
447+.. code-block:: idris
448+
449+ data Bin : Nat -> Type where
450+ N : Bin Z
451+ O : Bin n -> Bin (0 + n + n)
452+ I : Bin n -> Bin (1 + n + n)
453+
454+ toN : (b : Bin n) -> Nat
455+ toN N = Z
456+ toN (O {n} bs) = 0 + n + n
457+ toN (I {n} bs) = 1 + n + n
458+
459+ main : IO ()
460+ main = print . toN $ I (I (O (O (I N))))
461+
462+In the function ``toN``, we attempted to "cheat" and instead of
463+traversing the whole structure, we just projected the value index ``n``
464+out of constructors ``I`` and ``O``. However, this index is a free
465+implicit, therefore it is considered dotted.
466+
467+Inspecting it then produces the following warnings when compiling with
468+``--warnreach``:
469+
470+.. code-block:: idris
471+
472+ Main.I: inaccessible arguments reachable:
473+ n from Main.toN arg# 1
474+ Main.O: inaccessible arguments reachable:
475+ n from Main.toN arg# 1
476+
477+We can see that the argument ``n`` of both ``I`` and ``O`` is used in
478+the function ``toN``, argument 1.
479+
480+At this stage of development, warnings only contain argument numbers,
481+not names; this will hopefully be fixed. When numbering arguments, we
482+go from 0, taking free implicits first, left-to-right; then the bound
483+arguments. The function ``toN`` has therefore in fact two arguments:
484+``n`` (argument 0) and ``b`` (argument 1). And indeed, as the warning
485+says, we project the dotted field from ``b``.
486+
487+Again, one solution is to fix the function ``toN`` to calculate its
488+result honestly; the other one is to accept that we carry a ``Nat``
489+with every constructor of ``Bin`` and make it a bound implicit:
490+
491+.. code-block:: idris
492+
493+ O : {n : Nat} -> Bin n -> Bin (0 + n + n)
494+ I : {n : Nat} -> bin n -> Bin (1 + n + n)
495+
496+References
497+----------
498+
499+.. [BMM04] Edwin Brady, Conor McBride, James McKinna: `Inductive
500+ families need not store their indices
501+ <http://citeseerx.ist.psu.edu/viewdoc/summary;jsessionid=1F796FCF0F2C4C535FC70F62BE2FB821?doi=10.1.1.62.3849>`__
docs/reference/ffi.rstnew file+277
@@ -0,0 +1,277 @@
1+New Foreign Function Interface
2+==============================
3+
4+.. sectionauthor:: Edwin Brady
5+
6+Ever since Idris has had multiple backends compiling to different
7+target languages on potentially different platforms, we have had the
8+problem that the foreign function interface (FFI) was written under
9+the assumption of compiling to C. As a result, it has been hard to
10+write generic code for multiple targets, or even to be sure that if
11+code compiles that it will run on the expected target.
12+
13+As of 0.9.17, Idris will have a new foreign function interface (FFI)
14+which is aware of multiple targets. Users who are working with the
15+default code generator can happily continue writing programs as before
16+with no changes, but if you are writing bindings for an external
17+library, writing a back end, or working with a non-C back end, there
18+are some things you will need to be aware of, which this page
19+describes.
20+
21+The ``IO'`` monad, and ``main``
22+-------------------------------
23+
24+The ``IO`` monad exists as before, but is now specific to the C
25+backend (or, more precisely, any backend whose foreign function calls
26+are compatible with C.) Additionally, there is now an ``IO'`` monad,
27+which is parameterised over a FFI descriptor:
28+
29+.. code-block:: idris
30+
31+ data IO' : (lang : FFI) -> Type -> Type
32+
33+The Prelude defines two FFI descriptors which are imported
34+automatically, for C and JavaScript/Node, and defines ``IO`` to use
35+the C FFI and ``JS_IO`` to use the JavaScript FFI:
36+
37+.. code-block:: idris
38+
39+ FFI_C : FFI
40+ FFI_JS : FFI
41+
42+ IO : Type -> Type
43+ IO a = IO' FFI_C a
44+
45+ JS_IO : Type -> Type
46+ JS_IO a = IO' FFI_JS a
47+
48+As before, the entry point to an Idris program is ``main``, but the
49+type of ``main`` can now be any instance of ``IO'``, e.g. the
50+following are both valid:
51+
52+.. code-block:: idris
53+
54+ main : IO ()
55+ main : JS_IO ()
56+
57+The FFI descriptor includes details about which types can be
58+marshalled between the foreign language and Idris, and the "target" of
59+a foreign function call (typically just a String representation of the
60+function's name, but potentially something more complicated such as an
61+external library file or even a URL).
62+
63+FFI descriptors
64+---------------
65+
66+An FFI descriptor is a record containing a predicate which holds when
67+a type can be marshalled, and the type of the target of a foreign
68+call:
69+
70+.. code-block:: idris
71+
72+ record FFI : Type where
73+ MkFFI : (ffi_types : Type -> Type) ->
74+ (ffi_fn : Type) -> FFI
75+
76+For C, this is:
77+
78+.. code-block:: idris
79+
80+ -- Supported C integer types
81+ data C_IntTypes : Type -> Type where
82+ C_IntChar : C_IntTypes Char
83+ C_IntNative : C_IntTypes Int
84+ ... -- more integer types
85+
86+ -- Supported C foreign types
87+ data C_Types : Type -> Type where
88+ C_Str : C_Types String
89+ C_Float : C_Types Float
90+ C_Ptr : C_Types Ptr
91+ C_MPtr : C_Types ManagedPtr
92+ C_Unit : C_Types ()
93+ C_Any : C_Types (Raw a)
94+ C_IntT : C_IntTypes i -> C_Types i
95+
96+ FFI_C : FFI
97+ FFI_C = MkFFI C_Types
98+ String -- the name of the C function
99+
100+Foreign calls
101+-------------
102+
103+To call a foreign function, the ``foreign`` function is used. For
104+example:
105+
106+.. code-block:: idris
107+
108+ do_fopen : String -> String -> IO Ptr
109+ do_fopen f m
110+ = foreign FFI_C "fileOpen" (String -> String -> IO Ptr) f m
111+
112+The ``foreign`` function takes an FFI description, a function name (the
113+type is given by the ``ffi_fn`` field of ``FFI_C`` here), and a function
114+type, which gives the expected types of the remaining arguments. Here,
115+we're calling an external function ``fileOpen`` which takes, in the C, a
116+``char*`` file name, a ``char*`` mode, and returns a file pointer. It is
117+the job of the C back end to convert Idris ``String`` to C ``char*``
118+and vice versa.
119+
120+The argument types and return type given here must be present in the
121+``fn_types`` predicate of the ``FFI_C`` description for the foreign
122+call to be valid.
123+
124+**Note** The arguments to ``foreign`` *must* be known at compile time,
125+because the foreign calls are generated statically. The ``%inline``
126+directive on a function can be used to give hints to help this, for
127+example a shorthand for calling external JavaScript functions:
128+
129+.. code-block:: idris
130+
131+ %inline
132+ jscall : (fname : String) -> (ty : Type) ->
133+ {auto fty : FTy FFI_JS [] ty} -> ty
134+ jscall fname ty = foreign FFI_JS fname ty
135+
136+FFI implementation
137+~~~~~~~~~~~~~~~~~~
138+
139+In order to write bindings to external libraries, the details of how
140+``foreign`` works are unnecessary --- you simply need to know that
141+``foreign`` takes an FFI descriptor, the function name, and its
142+type. It is instructive to look a little deeper, however:
143+
144+The type of ``foreign`` is as follows:
145+
146+.. code-block:: idris
147+
148+ foreign : (ffi : FFI)
149+ -> (fname : ffi_fn f)
150+ -> (ty : Type)
151+ -> {auto fty : FTy ffi [] ty}
152+ -> ty
153+
154+The important argument here is the implicit ``fty``, which contains a
155+proof (``FTy``) that the given type is valid according to the FFI
156+description ``ffi``:
157+
158+.. code-block:: idris
159+
160+ data FTy : FFI -> List Type -> Type -> Type where
161+ FRet : ffi_types f t -> FTy f xs (IO' f t)
162+ FFun : ffi_types f s -> FTy f (s :: xs) t -> FTy f xs (s -> t)
163+
164+Notice that this uses the ``ffi_types`` field of the FFI descriptor
165+--- these arguments to ``FRet`` and ``FFun`` give explicit proofs that
166+the type is valid in this FFI. For example, the above ``do_fopen``
167+builds the following implicit proof as the ``fty`` argument to
168+``foreign``:
169+
170+.. code-block:: idris
171+
172+ FFun C_Str (FFun C_Str (FRet C_Ptr))
173+
174+Compiling foreign calls
175+-----------------------
176+
177+(This section assumes some knowledge of the Idris internals.)
178+
179+When writing a back end, we now need to know how to compile
180+``foreign``. We'll skip the details here of how a ``foreign`` call
181+reaches the intermediate representation (the IR), though you can look
182+in ``IO.idr`` in the ``prelude`` package to see a bit more detail ---
183+a ``foreign`` call is implemented by the primitive function
184+``mkForeignPrim``. The important part of the IR as defined in
185+``Lang.hs`` is the following constructor:
186+
187+.. code-block:: idris
188+
189+ data LExp = ...
190+ | LForeign FDesc -- Function descriptor
191+ FDesc -- Return type descriptor
192+ [(FDesc, LExp)]
193+
194+So, a ``foreign`` call appears in the IR as the ``LForeign``
195+constructor, which takes a function descriptor (of a type given by the
196+``ffi_fn`` field in the FFI descriptor), a return type descriptor
197+(given by an application of ``FTy``), and a list of arguments with
198+type descriptors (also given by an application of ``FTy``).
199+
200+An ``FDesc`` describes an application of a name to some arguments, and
201+is really just a simplified subset of an ``LExp``:
202+
203+.. code-block:: idris
204+
205+ data FDesc = FCon Name
206+ | FStr String
207+ | FUnknown
208+ | FApp Name [FDesc]
209+
210+There are corresponding structures in the lower level IRs, such as the
211+defunctionalised, simplified and bytecode forms.
212+
213+Our ``do_fopen`` example above arrives in the ``LExp`` form as:
214+
215+.. code-block:: idris
216+
217+ LForeign (FStr "fileOpen") (FCon (sUN "C_Ptr"))
218+ [(FCon (sUN "C_Str"), f), (FCon (sUN "C_Str"), m)]
219+
220+(Assuming that ``f`` and ``m`` stand for the ``LExp`` representations
221+of the arguments.) This information should be enough for any back end
222+to marshal the arguments and return value appropriately.
223+
224+.. note::
225+
226+ When processing ``FDesc``, be aware that there may be implicit
227+ arguments, which have not been erased. For example, ``C_IntT`` has
228+ an implicit argument ``i``, so will appear in an ``FDesc`` as
229+ something of the form ``FApp (sUN "C_IntT") [i, t]`` where ``i`` is
230+ the implicit argument (which can be ignored) and ``t`` is the
231+ descriptor of the integer type. See ``CodegenC.hs``, specifically
232+ the function ``toFType``, to see how this works in practice.
233+
234+JavaScript FFI descriptor
235+~~~~~~~~~~~~~~~~~~~~~~~~~
236+
237+The JavaScript FFI descriptor is a little more complex, because the
238+JavaScript FFI supports marshalling functions. It is defined as
239+follows:
240+
241+.. code-block:: idris
242+
243+ mutual
244+ data JsFn t = MkJsFn t
245+
246+ data JS_IntTypes : Type -> Type where
247+ JS_IntChar : JS_IntTypes Char
248+ JS_IntNative : JS_IntTypes Int
249+
250+ data JS_FnTypes : Type -> Type where
251+ JS_Fn : JS_Types s -> JS_FnTypes t -> JS_FnTypes (s -> t)
252+ JS_FnIO : JS_Types t -> JS_FnTypes (IO' l t)
253+ JS_FnBase : JS_Types t -> JS_FnTypes t
254+
255+ data JS_Types : Type -> Type where
256+ JS_Str : JS_Types String
257+ JS_Float : JS_Types Float
258+ JS_Ptr : JS_Types Ptr
259+ JS_Unit : JS_Types ()
260+ JS_FnT : JS_FnTypes a -> JS_Types (JsFn a)
261+ JS_IntT : JS_IntTypes i -> JS_Types i
262+
263+The reason for wrapping function types in a ``JsFn`` is to help the
264+proof search when building ``FTy``. We hope to improve proof search
265+eventually, but for the moment it works much more reliably if the
266+indices are disjoint! An example of using this appears in `IdrisScript
267+<https://github.com/idris-hackers/IdrisScript>`__ when setting
268+timeouts:
269+
270+.. code-block:: idris
271+
272+ setTimeout : (() -> JS_IO ()) -> (millis : Int) -> JS_IO Timeout
273+ setTimeout f millis = do
274+ timeout <- jscall "setTimeout(%0, %1)"
275+ (JsFn (() -> JS_IO ()) -> Int -> JS_IO Ptr)
276+ (MkJsFn f) millis
277+ return $ MkTimeout timeout
docs/reference/index.rstnew file+26
@@ -0,0 +1,26 @@
1+.. _reference-index:
2+
3+###################
4+Language Reference
5+###################
6+
7+This is the reference guide for the Idris Language.
8+It documents the language specification and internals.
9+This will tell you how Idris works, for using it you should read the Idris Tutorial.
10+
11+.. note::
12+ The documentation for Idris has been published under the Creative
13+ Commons CC0 License. As such to the extent possible under law, /The
14+ Idris Community/ has waived all copyright and related or neighboring
15+ rights to Documentation for Idris.
16+
17+ More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/
18+
19+
20+.. toctree::
21+ :maxdepth: 1
22+
23+ documenting
24+ uniqueness-types
25+ ffi
26+ erasure
docs/reference/uniqueness-types.rstnew file+251
@@ -0,0 +1,251 @@
1+Uniqueness Types
2+================
3+
4+Uniqueness Types are an experimental feature available from Idris
5+0.9.15. A value with a unique type is guaranteed to have *at most one*
6+reference to it at run-time, which means that it can safely be updated
7+in-place, reducing the need for memory allocation and garbage
8+collection. The motivation is that we would like to be able to write
9+reactive systems, programs which run in limited memory environments,
10+device drivers, and any other system with hard real-time requirements,
11+ideally while giving up as little high level conveniences as possible.
12+
13+They are inspired by linear types, `Uniqueness Types
14+<https://en.wikipedia.org/wiki/Uniqueness_type>`__ in the `Clean
15+<http://wiki.clean.cs.ru.nl/Clean>`__ programming language, and
16+ownership types and borrowed pointers in the `Rust
17+<http://www.rust-lang.org/>`__ programming language.
18+
19+Some things we hope to be able to do eventually with uniqueness types
20+include:
21+
22+- Safe, pure, in-place update of arrays, lists, etc
23+- Provide guarantees of correct resource usage, state transitions, etc
24+- Provide guarantees that critical program fragments will *never*
25+ allocate
26+
27+Using Uniqueness
28+~~~~~~~~~~~~~~~~
29+
30+If ``x : T`` and ``T : UniqueType``, then there is at most one reference
31+to ``x`` at any time during run-time execution. For example, we can
32+declare the type of unique lists as follows:
33+
34+.. code-block:: idris
35+
36+ data UList : Type -> UniqueType
37+ Nil : UList a
38+ (::) : a -> UList a -> UList a
39+
40+If we have a value ``xs : UList a``, then there is at most one
41+reference to ``xs`` at run-time. The type checker preserves this
42+guarantee by ensuring that there is at most one reference to any value
43+of a unique type in a pattern clause. For example, the following
44+function definition would be valid:
45+
46+.. code-block:: idris
47+
48+ umap : (a -> b) -> UList a -> UList b
49+ umap f [] = []
50+ umap f (x :: xs) = f x :: umap f xs
51+
52+In the second clause, ``xs`` is a value of a unique type, and only
53+appears once on the right hand side, so this clause is valid. Not only
54+that, since we know there can be no other reference to the ``UList a``
55+argument, we can reuse its space for building the result! The compiler
56+is aware of this, and compiles this definition to an in-place update
57+of the list.
58+
59+The following function definition would not be valid (even assuming an
60+implementation of ``++``), however, since ``xs`` appears twice:
61+
62+.. code-block:: idris
63+
64+ dupList : UList a -> UList a
65+ dupList xs = xs ++ xs
66+
67+This would result in a shared pointer to ``xs``, so the typechecker
68+reports:
69+
70+.. code-block:: idris
71+
72+ unique.idr:12:5:Unique name xs is used more than once
73+
74+If we explicitly copy, however, the typechecker is happy:
75+
76+.. code-block:: idris
77+
78+ dup : UList a -> UList a
79+ dup [] = []
80+ dup (x :: xs) = x :: x :: dup xs
81+
82+Note that it's fine to use ``x`` twice, because ``a`` is a ``Type``,
83+rather than a ``UniqueType``.
84+
85+There are some other restrictions on where a ``UniqueType`` can
86+appear, so that the uniqueness property is preserved. In particular,
87+the type of the function type, ``(x : a) -> b`` depends on the type of
88+``a`` or ``b`` - if either is a ``UniqueType``, then the function type
89+is also a ``UniqueType``. Then, in a data declaration, if the type
90+constructor builds a ``Type``, then no constructor can have a
91+``UniqueType``. For example, the following definition is invalid,
92+since it would embed a unique value in a possible non-unique value:
93+
94+.. code-block:: idris
95+
96+ data BadList : UniqueType -> Type
97+ Nil : {a : UniqueType} -> BadList a
98+ (::) : {a : UniqueType} -> a -> BadList a -> BadList a
99+
100+Finally, types may be polymorphic in their uniqueness, to a limited
101+extent. Since ``Type`` and ``UniqueType`` are different types, we are
102+limited in how much we can use polymorphic functions on unique types.
103+For example, if we have function composition defined as follows:
104+
105+.. code-block:: idris
106+
107+ (.) : {a, b, c : Type} -> (b -> c) -> (a -> b) -> a -> c
108+ (.) f g x = f (g x)
109+
110+And we have some functions over unique types:
111+
112+.. code-block:: idris
113+
114+ foo : UList a -> UList b
115+ bar : UList b -> UList c
116+
117+Then we cannot compose ``foo`` and ``bar`` as ``bar . foo``, because
118+``UList`` does not compute a ``Type``! Instead, we can define
119+composition as follows:
120+
121+.. code-block:: idris
122+
123+ (.) : {a, b, c : Type*} -> (b -> c) -> (a -> b) -> a -> c
124+ (.) f g x = f (g x)
125+
126+The ``Type*`` type stands for either unique or non-unique types. Since
127+such a function may be passed a ``UniqueType``, any value of type
128+``Type*`` must also satisfy the requirement that it appears at most
129+once on the right hand side.
130+
131+Borrowed Types
132+~~~~~~~~~~~~~~
133+
134+It quickly becomes obvious when working with uniqueness types that
135+having only one reference at a time can be painful. For example, what
136+if we want to display a list before updating it?
137+
138+.. code-block:: idris
139+
140+ showU : Show a => UList a -> String
141+ showU xs = "[" ++ showU' xs ++ "]" where
142+ showU' : UList a -> String
143+ showU' [] = ""
144+ showU' [x] = show x
145+ showU' (x :: xs) = show x ++ ", " ++ showU' xs
146+
147+This is a valid definition of ``showU``, but unfortunately it consumes
148+the list! So the following function would be invalid:
149+
150+.. code-block:: idris
151+
152+ printAndUpdate : UList Int -> IO ()
153+ printAndUpdate xs = do putStrLn (showU xs)
154+ let xs' = umap (*2) xs -- xs no longer available!
155+ putStrLn (showU xs')
156+
157+Still, one would hope to be able to display a unique list without
158+problem, since it merely *inspects* the list; there are no updates. We
159+can achieve this, using the notion of *borrowing*. A Borrowed type is
160+a Unique type which can be inspected at the top level (by pattern
161+matching, or by *lending* to another function) but no further. This
162+ensures that the internals (i.e. the arguments to top level patterns)
163+will not be passed to any function which will update them.
164+
165+``Borrowed`` converts a ``UniqueType`` to a ``BorrowedType``. It is
166+defined as follows (along with some additional rules in the
167+typechecker):
168+
169+.. code-block:: idris
170+
171+ data Borrowed : UniqueType -> BorrowedType where
172+ Read : {a : UniqueType} -> a -> Borrowed a
173+
174+ implicit
175+ lend : {a : UniqueType} -> a -> Borrowed a
176+ lend x = Read x
177+
178+A value can be "lent" to another function using ``lend``. Arguments to
179+``lend`` are not counted by the type checker as a reference to a unique
180+value, therefore a value can be lent as many times as desired. Using
181+this, we can write ``showU`` as follows:
182+
183+.. code-block:: idris
184+
185+ showU : Show a => Borrowed (UList a) -> String
186+ showU xs = "[" ++ showU' xs ++ "]" where
187+ showU' : Borrowed (UList a) -> String
188+ showU' [] = ""
189+ showU' [x] = show x
190+ showU' (Read (x :: xs)) = show x ++ ", " ++ showU' (lend xs)
191+
192+Unlike a unique value, a borrowed value may be referred to as many
193+times as desired. However, there is a restriction on how a borrowed
194+value can be used. After all, much like a library book or your
195+neighbour's lawnmower, if a function borrows a value it is expected to
196+return it in exactly the condition in which it was received!
197+
198+The restriction is that when a ``Borrowed`` type is matched, any
199+pattern variables under the ``Read`` which have a unique type may not
200+be referred to at all on the right hand side (unless they are
201+themselves ``lent`` to another function).
202+
203+Uniqueness information is stored in the type, and in particular in
204+function types. Once we're in a unique context, any new function which
205+is constructed will be required to have unique type, which prevents
206+the following sort of bad program being implemented:
207+
208+.. code-block:: idris
209+
210+ foo : UList Int -> IO ()
211+ foo xs = do let f = \x : Int => showU xs
212+ putStrLn $ free xs
213+ putStrLn $ f 42
214+ return ()
215+
216+Since ``lend`` is implicit, in practice for functions to lend and borrow
217+values merely requires the argument to be marked as ``Borrowed``. We can
218+therefore write ``showU`` as follows:
219+
220+.. code-block:: idris
221+
222+ showU : Show a => Borrowed (UList a) -> String
223+ showU xs = "[" ++ showU' xs ++ "]" where
224+ showU' : Borrowed (UList a) -> String
225+ showU' [] = ""
226+ showU' [x] = show x
227+ showU' (x :: xs) = show x ++ ", " ++ showU' xs
228+
229+Problems/Disadvantages/Still to do...
230+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231+
232+This is a work in progress, there is lots to do. The most obvious
233+problem is the loss of abstraction. On the one hand, we have more
234+precise control over memory usage with ``UniqueType`` and
235+``BorrowedType``, but they are not in general compatible with
236+functions polymorphic over ``Type``. In the short term, we can start
237+to write reactive and low memory systems with this, but longer term it
238+would be nice to support more abstraction.
239+
240+We also haven't checked any of the metatheory, so this could all be
241+fatally flawed! The implementation is based to a large extent on
242+`Uniqueness Typing Simplified
243+<http://lambda-the-ultimate.org/node/2708>`__, by de Vries et al, so
244+there is reason to believe things should be fine, but we still have to
245+do the work.
246+
247+Much as there are with linear types, there are some annoyances when
248+trying to prove properties of functions with unique types (for
249+example, what counts as a use of a value). Since we require *at most*
250+one use of a value, rather than *exactly* one, this seems to be less
251+of an issue in practice, but still needs thought.
docs/tutorial/classes.rstnew file+517
@@ -0,0 +1,517 @@
1+.. _sect-classes:
2+
3+============
4+Type Classes
5+============
6+
7+We often want to define functions which work across several different
8+data types. For example, we would like arithmetic operators to work on
9+``Int``, ``Integer`` and ``Float`` at the very least. We would like
10+``==`` to work on the majority of data types. We would like to be able
11+to display different types in a uniform way.
12+
13+To achieve this, we use a feature which has proved to be effective in
14+Haskell, namely *type classes*. To define a type class, we provide a
15+collection of overloaded operations which describe the interface for
16+*instances* of that class. A simple example is the ``Show`` type
17+class, which is defined in the prelude and provides an interface for
18+converting values to ``String``:
19+
20+.. code-block:: idris
21+
22+ class Show a where
23+ show : a -> String
24+
25+This generates a function of the following type (which we call a
26+*method* of the ``Show`` class):
27+
28+.. code-block:: idris
29+
30+ show : Show a => a -> String
31+
32+We can read this as: “under the constraint that ``a`` is an instance
33+of ``Show``, take an input ``a`` and return a ``String``.” An instance
34+of a class is defined with an ``instance`` declaration, which provides
35+implementations of the function for a specific type. For example, the
36+``Show`` instance for ``Nat`` could be defined as:
37+
38+.. code-block:: idris
39+
40+ instance Show Nat where
41+ show Z = "Z"
42+ show (S k) = "s" ++ show k
43+
44+::
45+
46+ Idris> show (S (S (S Z)))
47+ "sssZ" : String
48+
49+Only one instance of a class can be given for a type — instances may
50+not overlap. Instance declarations can themselves have constraints.
51+To help with resolution, the arguments of an instance must be
52+constructors (either data or type constructors), variables or
53+constants (i.e. you cannot give an instance for a function). For
54+example, to define a ``Show`` instance for vectors, we need to know
55+that there is a ``Show`` instance for the element type, because we are
56+going to use it to convert each element to a ``String``:
57+
58+.. code-block:: idris
59+
60+ instance Show a => Show (Vect n a) where
61+ show xs = "[" ++ show' xs ++ "]" where
62+ show' : Vect n a -> String
63+ show' Nil = ""
64+ show' (x :: Nil) = show x
65+ show' (x :: xs) = show x ++ ", " ++ show' xs
66+
67+Default Definitions
68+-------------------
69+
70+The library defines an ``Eq`` class which provides an interface for
71+comparing values for equality or inequality, with instances for all of
72+the built-in types:
73+
74+.. code-block:: idris
75+
76+ class Eq a where
77+ (==) : a -> a -> Bool
78+ (/=) : a -> a -> Bool
79+
80+To declare an instance of a type, we have to give definitions of all
81+of the methods. For example, for an instance of ``Eq`` for ``Nat``:
82+
83+.. code-block:: idris
84+
85+ instance Eq Nat where
86+ Z == Z = True
87+ (S x) == (S y) = x == y
88+ Z == (S y) = False
89+ (S x) == Z = False
90+
91+ x /= y = not (x == y)
92+
93+It is hard to imagine many cases where the ``/=`` method will be
94+anything other than the negation of the result of applying the ``==``
95+method. It is therefore convenient to give a default definition for
96+each method in the class declaration, in terms of the other method:
97+
98+.. code-block:: idris
99+
100+ class Eq a where
101+ (==) : a -> a -> Bool
102+ (/=) : a -> a -> Bool
103+
104+ x /= y = not (x == y)
105+ x == y = not (x /= y)
106+
107+A minimal complete definition of an ``Eq`` instance requires either
108+``==`` or ``/=`` to be defined, but does not require both. If a method
109+definition is missing, and there is a default definition for it, then
110+the default is used instead.
111+
112+Extending Classes
113+-----------------
114+
115+Classes can also be extended. A logical next step from an equality
116+relation ``Eq`` is to define an ordering relation ``Ord``. We can
117+define an ``Ord`` class which inherits methods from ``Eq`` as well as
118+defining some of its own:
119+
120+.. code-block:: idris
121+
122+ data Ordering = LT | EQ | GT
123+
124+.. code-block:: idris
125+
126+ class Eq a => Ord a where
127+ compare : a -> a -> Ordering
128+
129+ (<) : a -> a -> Bool
130+ (>) : a -> a -> Bool
131+ (<=) : a -> a -> Bool
132+ (>=) : a -> a -> Bool
133+ max : a -> a -> a
134+ min : a -> a -> a
135+
136+The ``Ord`` class allows us to compare two values and determine their
137+ordering. Only the ``compare`` method is required; every other method
138+has a default definition. Using this we can write functions such as
139+``sort``, a function which sorts a list into increasing order,
140+provided that the element type of the list is in the ``Ord`` class. We
141+give the constraints on the type variables left of the fat arrow
142+``=>``, and the function type to the right of the fat arrow:
143+
144+.. code-block:: idris
145+
146+ sort : Ord a => List a -> List a
147+
148+Functions, classes and instances can have multiple
149+constraints. Multiple constaints are written in brackets in a comma
150+separated list, for example:
151+
152+.. code-block:: idris
153+
154+ sortAndShow : (Ord a, Show a) => List a -> String
155+ sortAndShow xs = show (sort xs)
156+
157+Functors and Applicatives
158+-------------------------
159+
160+So far, we have seen single parameter type classes, where the parameter
161+is of type ``Type``. In general, there can be any number (greater than
162+0) of parameters, and the parameters can have *any* type. If the type
163+of the parameter is not ``Type``, we need to give an explicit type
164+declaration. For example, the ``Functor`` class is defined in the
165+library:
166+
167+.. code-block:: idris
168+
169+ class Functor (f : Type -> Type) where
170+ map : (m : a -> b) -> f a -> f b
171+
172+A functor allows a function to be applied across a structure, for
173+example to apply a function to every element in a ``List``:
174+
175+.. code-block:: idris
176+
177+ instance Functor List where
178+ map f [] = []
179+ map f (x::xs) = f x :: map f xs
180+
181+::
182+
183+ Idris> map (*2) [1..10]
184+ [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] : List Integer
185+
186+Having defined ``Functor``, we can define ``Applicative`` which
187+abstracts the notion of function application:
188+
189+.. code-block:: idris
190+
191+ infixl 2 <*>
192+
193+ class Functor f => Applicative (f : Type -> Type) where
194+ pure : a -> f a
195+ (<*>) : f (a -> b) -> f a -> f b
196+
197+Monads and ``do``-notation
198+--------------------------
199+
200+The ``Monad`` class allows us to encapsulate binding and computation,
201+and is the basis of ``do``-notation introduced in Section
202+:ref:`sect-do`. It extends ``Applicative`` as defined above, and is
203+defined as follows:
204+
205+.. code-block:: idris
206+
207+ class Applicative m => Monad (m : Type -> Type) where
208+ (>>=) : m a -> (a -> m b) -> m b
209+
210+Inside a ``do`` block, the following syntactic transformations are
211+applied:
212+
213+- ``x <- v; e`` becomes ``v >>= (\backslashx => e)``
214+
215+- ``v; e`` becomes ``v >>= (\backslash_ => e)``
216+
217+- ``let x = v; e`` becomes ``let x = v in e``
218+
219+``IO`` is an instance of ``Monad``, defined using primitive functions.
220+We can also define an instance for ``Maybe``, as follows:
221+
222+.. code-block:: idris
223+
224+ instance Monad Maybe where
225+ Nothing >>= k = Nothing
226+ (Just x) >>= k = k x
227+
228+Using this we can, for example, define a function which adds two
229+``Maybe Int``, using the monad to encapsulate the error handling:
230+
231+.. code-block:: idris
232+
233+ m_add : Maybe Int -> Maybe Int -> Maybe Int
234+ m_add x y = do x' <- x -- Extract value from x
235+ y' <- y -- Extract value from y
236+ return (x' + y') -- Add them
237+
238+This function will extract the values from ``x`` and ``y``, if they
239+are available, or return ``Nothing`` if they are not. Managing the
240+``Nothing`` cases is achieved by the ``>>=`` operator, hidden by the
241+``do`` notation.
242+
243+::
244+
245+ *classes> m_add (Just 20) (Just 22)
246+ Just 42 : Maybe Int
247+ *classes> m_add (Just 20) Nothing
248+ Nothing : Maybe Int
249+
250+``!``-notation
251+~~~~~~~~~~~~~~
252+
253+In many cases, using ``do``-notation can make programs unnecessarily
254+verbose, particularly in cases such as ``m_add`` above where the value
255+bound is used once, immediately. In these cases, we can use a
256+shorthand version, as follows:
257+
258+.. code-block:: idris
259+
260+ m_add : Maybe Int -> Maybe Int -> Maybe Int
261+ m_add x y = return (!x + !y)
262+
263+The notation ``!expr`` means that the expression ``expr`` should be
264+evaluated and then implicitly bound. Conceptually, we can think of
265+``!`` as being a prefix function with the following type:
266+
267+.. code-block:: idris
268+
269+ (!) : m a -> a
270+
271+Note, however, that it is not really a function, merely syntax! In
272+practice, a subexpression ``!expr`` will lift ``expr`` as high as
273+possible within its current scope, bind it to a fresh name ``x``, and
274+replace ``!expr`` with ``x``. Expressions are lifted depth first, left
275+to right. In practice, ``!``-notation allows us to program in a more
276+direct style, while still giving a notational clue as to which
277+expressions are monadic.
278+
279+For example, the expression:
280+
281+.. code-block:: idris
282+
283+ let y = 42 in f !(g !(print y) !x)
284+
285+is lifted to:
286+
287+.. code-block:: idris
288+
289+ let y = 42 in do y' <- print y
290+ x' <- x
291+ g' <- g y' x'
292+ f g'
293+
294+Monad comprehensions
295+~~~~~~~~~~~~~~~~~~~~
296+
297+The list comprehension notation we saw in Section
298+:ref:`sect-more-expr` is more general, and applies to anything which
299+is an instance of both ``Monad`` and ``Alternative``:
300+
301+.. code-block:: idris
302+
303+ class Applicative f => Alternative (f : Type -> Type) where
304+ empty : f a
305+ (<|>) : f a -> f a -> f a
306+
307+In general, a comprehension takes the form ``[ exp | qual1, qual2, …,
308+qualn ]`` where ``quali`` can be one of:
309+
310+- A generator ``x <- e``
311+
312+- A *guard*, which is an expression of type ``Bool``
313+
314+- A let binding ``let x = e``
315+
316+To translate a comprehension ``[exp | qual1, qual2, …, qualn]``, first
317+any qualifier ``qual`` which is a *guard* is translated to ``guard
318+qual``, using the following function:
319+
320+.. code-block:: idris
321+
322+ guard : Alternative f => Bool -> f ()
323+
324+Then the comprehension is converted to ``do`` notation:
325+
326+.. code-block:: idris
327+
328+ do { qual1; qual2; ...; qualn; return exp; }
329+
330+Using monad comprehensions, an alternative definition for ``m_add``
331+would be:
332+
333+.. code-block:: idris
334+
335+ m_add : Maybe Int -> Maybe Int -> Maybe Int
336+ m_add x y = [ x' + y' | x' <- x, y' <- y ]
337+
338+Idiom brackets
339+--------------
340+
341+While ``do`` notation gives an alternative meaning to sequencing,
342+idioms give an alternative meaning to *application*. The notation and
343+larger example in this section is inspired by Conor McBride and Ross
344+Paterson’s paper “Applicative Programming with Effects” [1]_.
345+
346+First, let us revisit ``m_add`` above. All it is really doing is
347+applying an operator to two values extracted from ``Maybe Int``. We
348+could abstract out the application:
349+
350+.. code-block:: idris
351+
352+ m_app : Maybe (a -> b) -> Maybe a -> Maybe b
353+ m_app (Just f) (Just a) = Just (f a)
354+ m_app _ _ = Nothing
355+
356+Using this, we can write an alternative ``m_add`` which uses this
357+alternative notion of function application, with explicit calls to
358+``m_app``:
359+
360+.. code-block:: idris
361+
362+ m_add' : Maybe Int -> Maybe Int -> Maybe Int
363+ m_add' x y = m_app (m_app (Just (+)) x) y
364+
365+Rather than having to insert ``m_app`` everywhere there is an
366+application, we can use to do the job for us. To do this, we can make
367+``Maybe`` an instance of ``Applicative`` as follows, where ``<>`` is
368+defined in the same way as ``m_app`` above (this is defined in the
369+``Idris`` library):
370+
371+.. code-block:: idris
372+
373+ instance Applicative Maybe where
374+ pure = Just
375+
376+ (Just f) <*> (Just a) = Just (f a)
377+ _ <*> _ = Nothing
378+
379+Using we can use this instance as follows, where a function
380+application ``[| f a1 …an |]`` is translated into ``pure f <> a1 <>
381+…<> an``:
382+
383+.. code-block:: idris
384+
385+ m_add' : Maybe Int -> Maybe Int -> Maybe Int
386+ m_add' x y = [| x + y |]
387+
388+An error-handling interpreter
389+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
390+
391+Idiom notation is commonly useful when defining evaluators. McBride
392+and Paterson describe such an evaluator [1]_, for a language similar
393+to the following:
394+
395+.. code-block:: idris
396+
397+ data Expr = Var String -- variables
398+ | Val Int -- values
399+ | Add Expr Expr -- addition
400+
401+Evaluation will take place relative to a context mapping variables
402+(represented as ``String``s) to integer values, and can possibly fail.
403+We define a data type ``Eval`` to wrap an evaluator:
404+
405+.. code-block:: idris
406+
407+ data Eval : Type -> Type where
408+ MkEval : (List (String, Int) -> Maybe a) -> Eval a
409+
410+Wrapping the evaluator in a data type means we will be able to make it
411+an instance of a type class later. We begin by defining a function to
412+retrieve values from the context during evaluation:
413+
414+.. code-block:: idris
415+
416+ fetch : String -> Eval Int
417+ fetch x = MkEval (\e => fetchVal e) where
418+ fetchVal : List (String, Int) -> Maybe Int
419+ fetchVal [] = Nothing
420+ fetchVal ((v, val) :: xs) = if (x == v)
421+ then (Just val)
422+ else (fetchVal xs)
423+
424+When defining an evaluator for the language, we will be applying
425+functions in the context of an ``Eval``, so it is natural to make
426+``Eval`` an instance of ``Applicative``. Before ``Eval`` can be an
427+instance of ``Applicative`` it is necessary to make ``Eval`` an
428+instance of ``Functor``:
429+
430+.. code-block:: idris
431+
432+ instance Functor Eval where
433+ map f (MkEval g) = MkEval (\e => map f (g e))
434+
435+ instance Applicative Eval where
436+ pure x = MkEval (\e => Just x)
437+
438+ (<*>) (MkEval f) (MkEval g) = MkEval (\x => app (f x) (g x)) where
439+ app : Maybe (a -> b) -> Maybe a -> Maybe b
440+ app (Just fx) (Just gx) = Just (fx gx)
441+ app _ _ = Nothing
442+
443+Evaluating an expression can now make use of the idiomatic application
444+to handle errors:
445+
446+.. code-block:: idris
447+
448+ eval : Expr -> Eval Int
449+ eval (Var x) = fetch x
450+ eval (Val x) = [| x |]
451+ eval (Add x y) = [| eval x + eval y |]
452+
453+ runEval : List (String, Int) -> Expr -> Maybe Int
454+ runEval env e = case eval e of
455+ MkEval envFn => envFn env
456+
457+Named Instances
458+---------------
459+
460+It can be desirable to have multiple instances of a type class, for
461+example to provide alternative methods for sorting or printing values.
462+To achieve this, instances can be *named* as follows:
463+
464+.. code-block:: idris
465+
466+ instance [myord] Ord Nat where
467+ compare Z (S n) = GT
468+ compare (S n) Z = LT
469+ compare Z Z = EQ
470+ compare (S x) (S y) = compare @{myord} x y
471+
472+This declares an instance as normal, but with an explicit name,
473+``myord``. The syntax ``compare @{myord}`` gives an explicit instance to
474+``compare``, otherwise it would use the default instance for ``Nat``. We
475+can use this, for example, to sort a list of ``Nat`` in reverse.
476+Given the following list:
477+
478+.. code-block:: idris
479+
480+ testList : List Nat
481+ testList = [3,4,1]
482+
483+We can sort it using the default ``Ord`` instance, then the named
484+instance ``myord`` as follows, at the ``Idris`` prompt:
485+
486+::
487+
488+ *named_instance> show (sort testList)
489+ "[sO, sssO, ssssO]" : String
490+ *named_instance> show (sort @{myord} testList)
491+ "[ssssO, sssO, sO]" : String
492+
493+
494+Determining Parameters
495+----------------------
496+
497+When a class has more than one parameter, it can help resolution if
498+the parameters used to resolve the type class are restricted. For
499+example:
500+
501+.. code-block:: idris
502+
503+ class Monad m => MonadState s (m : Type -> Type) | m where
504+ get : m s
505+ put : s -> m ()
506+
507+In this class, only ``m`` needs to be known to resolve this class, and
508+``s`` can then be determined from the instance. This is declared with
509+the ``| m`` after the class declaration. We call ``m`` a *determining
510+parameter* of the ``MonadState`` class, because it is the parameter
511+used to resolve an instance.
512+
513+
514+.. [1] Conor Mcbride and Ross Paterson. 2008. Applicative programming
515+ with effects. J. Funct. Program. 18, 1 (January 2008),
516+ 1-13. DOI=10.1017/S0956796807006326
517+ http://dx.doi.org/10.1017/S0956796807006326
docs/tutorial/conclusions.rstnew file+54
@@ -0,0 +1,54 @@
1+.. _sect-concs:
2+
3+===============
4+Further Reading
5+===============
6+
7+Further information about ``Idris`` programming, and programming with
8+dependent types in general, can be obtained from various sources:
9+
10+- The ``Idris`` web site (http://idris-lang.org/) and by asking
11+ questions on the mailing list.
12+
13+- The IRC channel ``#idris``, on
14+ `chat.freenode.net <http://chat.freenode.net>`__.
15+
16+- The wiki (https://github.com/idris-lang/Idris-dev/wiki/) has further
17+ user provided information, in particular:
18+
19+ - https://github.com/idris-lang/Idris-dev/wiki/Manual
20+
21+ - https://github.com/idris-lang/Idris-dev/wiki/Language-Features
22+
23+- Examining the prelude and exploring the ``samples`` in the
24+ distribution. The ``Idris`` source can be found online at:
25+ https://github.com/idris-lang/Idris-dev.
26+
27+- Existing projects on the ``Idris Hackers`` web space:
28+ http://idris-hackers.github.io.
29+
30+- Various papers (e.g. [1]_, [2]_, and [3]_). Although these mostly
31+ describe older versions of ``Idris``.
32+
33+.. [1] Edwin Brady and Kevin Hammond. 2012. Resource-Safe systems
34+ programming with embedded domain specific languages. In
35+ Proceedings of the 14th international conference on Practical
36+ Aspects of Declarative Languages (PADL'12), Claudio Russo and
37+ Neng-Fa Zhou (Eds.). Springer-Verlag, Berlin, Heidelberg,
38+ 242-257. DOI=10.1007/978-3-642-27694-1_18
39+ http://dx.doi.org/10.1007/978-3-642-27694-1_18
40+
41+.. [2] Edwin C. Brady. 2011. IDRIS ---: systems programming meets full
42+ dependent types. In Proceedings of the 5th ACM workshop on
43+ Programming languages meets program verification (PLPV
44+ '11). ACM, New York, NY, USA,
45+ 43-54. DOI=10.1145/1929529.1929536
46+ http://doi.acm.org/10.1145/1929529.1929536
47+
48+.. [3] Edwin C. Brady and Kevin Hammond. 2010. Scrapping your
49+ inefficient engine: using partial evaluation to improve
50+ domain-specific language implementation. In Proceedings of the
51+ 15th ACM SIGPLAN international conference on Functional
52+ programming (ICFP '10). ACM, New York, NY, USA,
53+ 297-308. DOI=10.1145/1863543.1863587
54+ http://doi.acm.org/10.1145/1863543.1863587
docs/tutorial/index.rstnew file+33
@@ -0,0 +1,33 @@
1+.. _tutorial-index:
2+
3+####################
4+ The Idris Tutorial
5+####################
6+
7+The is the Idris Tutorial. It will teach you about programming in the Idris Language.
8+
9+.. note::
10+ The documentation for Idris has been published under the Creative
11+ Commons CC0 License. As such to the extent possible under law, /The
12+ Idris Community/ has waived all copyright and related or neighboring
13+ rights to Documentation for Idris.
14+
15+ More information concerning the CC0 can be found online at: http://creativecommons.org/publicdomain/zero/1.0/
16+
17+
18+.. toctree::
19+ :maxdepth: 1
20+
21+ introduction
22+ starting
23+ typesfuns
24+ classes
25+ modules
26+ interp
27+ views
28+ theorems
29+ provisional
30+ interactive
31+ syntax
32+ miscellany
33+ conclusions
docs/tutorial/interactive.rstnew file+258
@@ -0,0 +1,258 @@
1+.. _sect-interactive:
2+
3+===================
4+Interactive Editing
5+===================
6+
7+By now, we have seen several examples of how ``Idris``’ dependent type
8+system can give extra confidence in a function’s correctness by giving
9+a more precise description of its intended behaviour in its *type*. We
10+have also seen an example of how the type system can help with EDSL
11+development by allowing a programmer to describe the type system of an
12+object language. However, precise types give us more than verification
13+of programs — we can also exploit types to help write programs which
14+are *correct by construction*.
15+
16+The ``Idris`` REPL provides several commands for inspecting and
17+modifying parts of programs, based on their types, such as case
18+splitting on a pattern variable, inspecting the type of a
19+metavariable, and even a basic proof search mechanism. In this
20+section, we explain how these features can be exploited by a text
21+editor, and specifically how to do so in `Vim
22+<https://github.com/idris-hackers/idris-vim>`_. An interactive mode
23+for `Emacs <https://github.com/idris-hackers/idris-emacs>`_ is also
24+available.
25+
26+
27+Editing at the REPL
28+-------------------
29+
30+The REPL provides a number of commands, which we will describe
31+shortly, which generate new program fragments based on the currently
32+loaded module. These take the general form
33+
34+::
35+
36+ :command [line number] [name]
37+
38+That is, each command acts on a specific source line, at a specific
39+name, and outputs a new program fragment. Each command has an
40+alternative form, which *updates* the source file in-place:
41+
42+::
43+
44+ :command! [line number] [name]
45+
46+When the REPL is loaded, it also starts a background process which
47+accepts and responds to REPL commands, using ``idris --client``. For
48+example, if we have a REPL running elsewhere, we can execute commands
49+such as:
50+
51+::
52+
53+ $ idris --client ':t plus'
54+ Prelude.Nat.plus : Nat -> Nat -> Nat
55+ $ idris --client '2+2'
56+ 4 : Integer
57+
58+A text editor can take advantage of this, along with the editing
59+commands, in order to provide interactive editing support.
60+
61+Editing Commands
62+----------------
63+
64+:addclause
65+~~~~~~~~~~
66+
67+The ``:addclause n f`` command (abbreviated ``:ac n f``) creates a
68+template definition for the function named ``f`` declared on line
69+``n``. For example, if the code beginning on line 94 contains:
70+
71+.. code-block:: idris
72+
73+ vzipWith : (a -> b -> c) ->
74+ Vect n a -> Vect n b -> Vect n c
75+
76+then ``:ac 94 vzipWith`` will give:
77+
78+.. code-block:: idris
79+
80+ vzipWith f xs ys = ?vzipWith_rhs
81+
82+The names are chosen according to hints which may be given by a
83+programmer, and then made unique by the machine by adding a digit if
84+necessary. Hints can be given as follows:
85+
86+.. code-block:: idris
87+
88+ %name Vect xs, ys, zs, ws
89+
90+This declares that any names generated for types in the ``Vect`` family
91+should be chosen in the order ``xs``, ``ys``, ``zs``, ``ws``.
92+
93+:casesplit
94+~~~~~~~~~~
95+
96+The ``:casesplit n x`` command, abbreviated ``:cs n x``, splits the
97+pattern variable ``x`` on line ``n`` into the various pattern forms it
98+may take, removing any cases which are impossible due to unification
99+errors. For example, if the code beginning on line 94 is:
100+
101+.. code-block:: idris
102+
103+ vzipWith : (a -> b -> c) ->
104+ Vect n a -> Vect n b -> Vect n c
105+ vzipWith f xs ys = ?vzipWith_rhs
106+
107+then ``:cs 96 xs`` will give:
108+
109+.. code-block:: idris
110+
111+ vzipWith f [] ys = ?vzipWith_rhs_1
112+ vzipWith f (x :: xs) ys = ?vzipWith_rhs_2
113+
114+That is, the pattern variable ``xs`` has been split into the two
115+possible cases ``[]`` and ``x :: xs``. Again, the names are chosen
116+according to the same heuristic. If we update the file (using
117+``:cs!``) then case split on ``ys`` on the same line, we get:
118+
119+.. code-block:: idris
120+
121+ vzipWith f [] [] = ?vzipWith_rhs_3
122+
123+That is, the pattern variable ``ys`` has been split into one case
124+``[]``, ``Idris`` having noticed that the other possible case ``y ::
125+ys`` would lead to a unification error.
126+
127+:addmissing
128+~~~~~~~~~~~
129+
130+The ``:addmissing n f`` command, abbreviated ``:am n f``, adds the
131+clauses which are required to make the function ``f`` on line ``n``
132+cover all inputs. For example, if the code beginning on line 94 is
133+
134+.. code-block:: idris
135+
136+ vzipWith : (a -> b -> c) ->
137+ Vect n a -> Vect n b -> Vect n c
138+ vzipWith f [] [] = ?vzipWith_rhs_1
139+
140+then ``:am 96 vzipWith`` gives:
141+
142+.. code-block:: idris
143+
144+ vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2
145+
146+That is, it notices that there are no cases for non-empty vectors,
147+generates the required clauses, and eliminates the clauses which would
148+lead to unification errors.
149+
150+:proofsearch
151+~~~~~~~~~~~~
152+
153+The ``:proofsearch n f`` command, abbreviated ``:ps n f``, attempts to
154+find a value for the metavariable ``f`` on line ``n`` by proof search,
155+trying values of local variables, recursive calls and constructors of
156+the required family. Optionally, it can take a list of *hints*, which
157+are functions it can try applying to solve the metavariable. For
158+example, if the code beginning on line 94 is:
159+
160+.. code-block:: idris
161+
162+ vzipWith : (a -> b -> c) ->
163+ Vect n a -> Vect n b -> Vect n c
164+ vzipWith f [] [] = ?vzipWith_rhs_1
165+ vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2
166+
167+then ``:ps 96 vzipWith_rhs_1`` will give
168+
169+.. code-block:: idris
170+
171+ []
172+
173+This works because it is searching for a ``Vect`` of length 0, of
174+which the empty vector is the only possibiliy. Similarly, and perhaps
175+surprisingly, there is only one possibility if we try to solve ``:ps
176+97 vzipWith_rhs_2``:
177+
178+.. code-block:: idris
179+
180+ f x y :: (vzipWith f xs ys)
181+
182+This works because ``vzipWith`` has a precise enough type: The
183+resulting vector has to be non-empty (a ``::``); the first element
184+must have type ``c`` and the only way to get this is to apply ``f`` to
185+``x`` and ``y``; finally, the tail of the vector can only be built
186+recursively.
187+
188+:makewith
189+~~~~~~~~~
190+
191+The ``:makewith n f`` command, abbreviated ``:mw n f``, adds a
192+``with`` to a pattern clause. For example, recall ``parity``. If line
193+10 is:
194+
195+.. code-block:: idris
196+
197+ parity (S k) = ?parity_rhs
198+
199+then ``:mw 10 parity`` will give:
200+
201+.. code-block:: idris
202+
203+ parity (S k) with (_)
204+ parity (S k) | with_pat = ?parity_rhs
205+
206+If we then fill in the placeholder ``_`` with ``parity k`` and case
207+split on ``with_pat`` using ``:cs 11 with_pat`` we get the following
208+patterns:
209+
210+.. code-block:: idris
211+
212+ parity (S (plus n n)) | even = ?parity_rhs_1
213+ parity (S (S (plus n n))) | odd = ?parity_rhs_2
214+
215+Note that case splitting has normalised the patterns here (giving
216+``plus`` rather than ``+``). In any case, we see that using
217+interactive editing significantly simplifies the implementation of
218+dependent pattern matching by showing a programmer exactly what the
219+valid patterns are.
220+
221+Interactive Editing in Vim
222+--------------------------
223+
224+The editor mode for Vim provides syntax highlighting, indentation and
225+interactive editing support using the commands described above.
226+Interactive editing is achieved using the following editor commands,
227+each of which update the buffer directly:
228+
229+- ``\d`` adds a template definition for the name declared on the
230+ current line (using ``:addclause``).
231+
232+- ``\c`` case splits the variable at the cursor (using
233+ ``:casesplit``).
234+
235+- ``\m`` adds the missing cases for the name at the cursor (using
236+ ``:addmissing``).
237+
238+- ``\w`` adds a ``with`` clause (using ``:makewith``).
239+
240+- ``\o`` invokes a proof search to solve the metavariable under the
241+ cursor (using ``:proofsearch``).
242+
243+- ``\p`` invokes a proof search with additional hints to solve the
244+ metavariable under the cursor (using ``:proofsearch``).
245+
246+There are also commands to invoke the type checker and evaluator:
247+
248+- ``\t`` displays the type of the (globally visible) name under the
249+ cursor. In the case of a metavariable, this displays the context
250+ and the expected type.
251+
252+- ``\e`` prompts for an expression to evaluate.
253+
254+- ``\r`` reloads and type checks the buffer.
255+
256+Corresponding commands are also available in the Emacs mode. Support
257+for other editors can be added in a relatively straighforward manner
258+by using ``idris –client``.
docs/tutorial/interp.rstnew file+289
@@ -0,0 +1,289 @@
1+.. _sect-interp:
2+
3+===================================
4+Example: The Well-Typed Interpreter
5+===================================
6+
7+In this section, we’ll use the features we’ve seen so far to write a
8+larger example, an interpreter for a simple functional programming
9+language, with variables, function application, binary operators and
10+an ``if...then...else`` construct. We will use the dependent type
11+system to ensure that any programs which can be represented are
12+well-typed.
13+
14+Representing Languages
15+----------------------
16+
17+First, let us define the types in the language. We have integers,
18+booleans, and functions, represented by ``Ty``:
19+
20+.. code-block:: idris
21+
22+ data Ty = TyInt | TyBool | TyFun Ty Ty
23+
24+We can write a function to translate these representations to a concrete
25+``Idris`` type — remember that types are first class, so can be
26+calculated just like any other value:
27+
28+.. code-block:: idris
29+
30+ interpTy : Ty -> Type
31+ interpTy TyInt = Int
32+ interpTy TyBool = Bool
33+ interpTy (TyFun A T) = interpTy A -> interpTy T
34+
35+We’re going to define a representation of our language in such a way
36+that only well-typed programs can be represented. We’ll index the
37+representations of expressions by their type and the types of local
38+variables (the context), which we’ll be using regularly as an implicit
39+argument, so we define everything in a ``using`` block:
40+
41+.. code-block:: idris
42+
43+ using (G:Vect n Ty)
44+
45+The full representation of expressions is given in Listing :ref:`exprty`.
46+They are indexed by the types of the local variables, and the type of
47+the expression itself:
48+
49+.. code-block:: idris
50+
51+ data Expr : Vect n Ty -> Ty -> Type
52+
53+Since expressions are indexed by their type, we can read the typing
54+rules of the language from the definitions of the constructors. Let us
55+look at each constructor in turn.
56+
57+.. _exprty:
58+.. code-block:: idris
59+ :caption: Expression representation
60+
61+ data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where
62+ Stop : HasType FZ (t :: G) t
63+ Pop : HasType k G t -> HasType (FS k) (u :: G) t
64+
65+ data Expr : Vect n Ty -> Ty -> Type where
66+ Var : HasType i G t -> Expr G t
67+ Val : (x : Int) -> Expr G TyInt
68+ Lam : Expr (a :: G) t -> Expr G (TyFun a t)
69+ App : Expr G (TyFun a t) -> Expr G a -> Expr G t
70+ Op : (interpTy a -> interpTy b -> interpTy c) ->
71+ Expr G a -> Expr G b -> Expr G c
72+ If : Expr G TyBool ->
73+ Lazy (Expr G a) ->
74+ Lazy (Expr G a) -> Expr G a
75+
76+We use a nameless representation for variables — they are *de Bruijn
77+indexed*. Variables are represented by a proof of their membership in
78+the context, ``HasType i G T``, which is a proof that variable ``i``
79+in context ``G`` has type ``T``. This is defined as follows:
80+
81+.. code-block:: idris
82+
83+ data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where
84+ Stop : HasType FZ (t :: G) t
85+ Pop : HasType k G t -> HasType (FS k) (u :: G) t
86+
87+We can treat *Stop* as a proof that the most recently defined variable
88+is well-typed, and *Pop n* as a proof that, if the ``n``\ th most
89+recently defined variable is well-typed, so is the ``n+1``\ th. In
90+practice, this means we use ``Stop`` to refer to the most recently
91+defined variable, ``Pop Stop`` to refer to the next, and so on, via
92+the ``Var`` constructor:
93+
94+.. code-block:: idris
95+
96+ Var : HasType i G t -> Expr G t
97+
98+So, in an expression ``\x,\y. x y``, the variable ``x`` would have a
99+de Bruijn index of 1, represented as ``Pop Stop``, and ``y 0``,
100+represented as ``Stop``. We find these by counting the number of
101+lambdas between the definition and the use.
102+
103+A value carries a concrete representation of an integer:
104+
105+.. code-block:: idris
106+
107+ Val : (x : Int) -> Expr G TyInt
108+
109+A lambda creates a function. In the scope of a function of type ``a ->
110+t``, there is a new local variable of type ``a``, which is expressed
111+by the context index:
112+
113+.. code-block:: idris
114+
115+ Lam : Expr (a :: G) t -> Expr G (TyFun a t)
116+
117+Function application produces a value of type ``t`` given a function
118+from ``a`` to ``t`` and a value of type ``a``:
119+
120+.. code-block:: idris
121+
122+ App : Expr G (TyFun a t) -> Expr G a -> Expr G t
123+
124+We allow arbitrary binary operators, where the type of the operator
125+informs what the types of the arguments must be:
126+
127+.. code-block:: idris
128+
129+ Op : (interpTy a -> interpTy b -> interpTy c) ->
130+ Expr G a -> Expr G b -> Expr G c
131+
132+Finally, if expressions make a choice given a boolean. Each branch
133+must have the same type, and we will evaluate the branches lazily so
134+that only the branch which is taken need be evaluated:
135+
136+.. code-block:: idris
137+
138+ If : Expr G TyBool ->
139+ Lazy (Expr G a) ->
140+ Lazy (Expr G a) ->
141+ Expr G a
142+
143+Writing the Interpreter
144+-----------------------
145+
146+When we evaluate an ``Expr``, we’ll need to know the values in scope,
147+as well as their types. ``Env`` is an environment, indexed over the
148+types in scope. Since an environment is just another form of list,
149+albeit with a strongly specified connection to the vector of local
150+variable types, we use the usual ``::`` and ``Nil`` constructors so
151+that we can use the usual list syntax. Given a proof that a variable
152+is defined in the context, we can then produce a value from the
153+environment:
154+
155+.. code-block:: idris
156+
157+ data Env : Vect n Ty -> Type where
158+ Nil : Env Nil
159+ (::) : interpTy a -> Env G -> Env (a :: G)
160+
161+ lookup : HasType i G t -> Env G -> interpTy t
162+ lookup Stop (x :: xs) = x
163+ lookup (Pop k) (x :: xs) = lookup k xs
164+
165+.. _interpdef:
166+.. code-block:: idris
167+ :caption: Intepreter Definition
168+
169+ interp : Env G -> Expr G t -> interpTy t
170+ interp env (Var i) = lookup i env
171+ interp env (Val x) = x
172+ interp env (Lam sc) = \x => interp (x :: env) sc
173+ interp env (App f s) = interp env f (interp env s)
174+ interp env (Op op x y) = op (interp env x) (interp env y)
175+ interp env (If x t e) = if interp env x then interp env t
176+ else interp env e
177+
178+Given this, an interpreter (Listing :ref:`interpdef`) is a function which
179+translates an ``Expr`` into a concrete ``Idris`` value with respect to a
180+specific environment:
181+
182+.. code-block:: idris
183+
184+ interp : Env G -> Expr G t -> interpTy t
185+
186+To translate a variable, we simply look it up in the environment:
187+
188+.. code-block:: idris
189+
190+ interp env (Var i) = lookup i env
191+
192+To translate a value, we just return the concrete representation of the
193+value:
194+
195+.. code-block:: idris
196+
197+ interp env (Val x) = x
198+
199+Lambdas are more interesting. In this case, we construct a function
200+which interprets the scope of the lambda with a new value in the
201+environment. So, a function in the object language is translated to an
202+``Idris`` function:
203+
204+.. code-block:: idris
205+
206+ interp env (Lam sc) = \x => interp (x :: env) sc
207+
208+For an application, we interpret the function and its argument and apply
209+it directly. We know that interpreting ``f`` must produce a function,
210+because of its type:
211+
212+.. code-block:: idris
213+
214+ interp env (App f s) = interp env f (interp env s)
215+
216+Operators and interpreters are, again, direct translations into the
217+equivalent ``Idris`` constructs. For operators, we apply the function to
218+its operands directly, and for ``If``, we apply the ``Idris``
219+``if...then...else`` construct directly.
220+
221+.. code-block:: idris
222+
223+ interp env (Op op x y) = op (interp env x) (interp env y)
224+ interp env (If x t e) = if interp env x then interp env t
225+ else interp env e
226+
227+Testing
228+-------
229+
230+We can make some simple test functions. Firstly, adding two inputs
231+``\x. \y. y + x`` is written as follows:
232+
233+.. code-block:: idris
234+
235+ add : Expr G (TyFun TyInt (TyFun TyInt TyInt))
236+ add = Lam (Lam (Op (+) (Var Stop) (Var (Pop Stop))))
237+
238+More interestingly, a factorial function ``fact``
239+(e.g. ``\. if (x == 0) then 1 else (fact (x-1) * x)``),
240+can be written as:
241+
242+.. code-block:: idris
243+
244+ fact : Expr G (TyFun TyInt TyInt)
245+ fact = Lam (If (Op (==) (Var Stop) (Val 0))
246+ (Val 1)
247+ (Op (*) (App fact (Op (-) (Var Stop) (Val 1)))
248+ (Var Stop)))
249+
250+Running
251+-------
252+
253+To finish, we write a ``main`` program which interprets the factorial
254+function on user input:
255+
256+.. code-block:: idris
257+
258+ main : IO ()
259+ main = do putStr "Enter a number: "
260+ x <- getLine
261+ print (interp [] fact (cast x))
262+
263+Here, ``cast`` is an overloaded function which converts a value from
264+one type to another if possible. Here, it converts a string to an
265+integer, giving 0 if the input is invalid. An example run of this
266+program at the ``Idris`` interactive environment is shown in Listing
267+:ref:`factrun`.
268+
269+
270+.. literalinclude:: ../listing/idris-prompt-interp.txt
271+ :caption: Running the well-typed interpreter
272+ :name: factrun
273+
274+Aside: ``cast``
275+~~~~~~~~~~~~~~~
276+
277+The prelude defines a type class ``Cast`` which allows conversion
278+between types:
279+
280+.. code-block:: idris
281+
282+ class Cast from to where
283+ cast : from -> to
284+
285+It is a *multi-parameter* type class, defining the source type and
286+object type of the cast. It must be possible for the type checker to
287+infer *both* parameters at the point where the cast is applied. There
288+are casts defined between all of the primitive types, as far as they
289+make sense.
docs/tutorial/introduction.rstnew file+69
@@ -0,0 +1,69 @@
1+.. _sect-intro:
2+
3+===========
4+Introducton
5+===========
6+
7+In conventional programming languages, there is a clear distinction
8+between *types* and *values*. For example, in `Haskell
9+<http://www.haskell.org>`_, the following are types, representing
10+integers, characters, lists of characters, and lists of any value
11+respectively:
12+
13+- ``Int``, ``Char``, ``[Char]``, ``[a]``
14+
15+Correspondingly, the following values are examples of inhabitants of
16+those types:
17+
18+- ``42``, ``’a’``, ``Hello world!``, ``[2,3,4,5,6]``
19+
20+In a language with *dependent types*, however, the distinction is less
21+clear. Dependent types allow types to “depend” on values — in other
22+words, types are a *first class* language construct and can be
23+manipulated like any other value. The standard example is the type of
24+lists of a given length [1]_, ``Vect n a``, where ``a`` is the element
25+type and ``n`` is the length of the list and can be an arbitrary term.
26+
27+When types can contain values, and where those values describe
28+properties (e.g. the length of a list) the type of a function can
29+begin to describe its own properties. For example, concatenating two
30+lists has the property that the resulting list’s length is the sum of
31+the lengths of the two input lists. We can therefore give the
32+following type to the ``app`` function, which concatenates vectors:
33+
34+.. code-block:: idris
35+
36+ app : Vect n a -> Vect m a -> Vect (n + m) a
37+
38+This tutorial introduces ``Idris``, a general purpose functional
39+programming language with dependent types. The goal of the ``Idris``
40+project is to build a dependently typed language suitable for
41+verifiable *systems* programming. To this end, ``Idris`` is a compiled
42+language which aims to generate efficient executable code. It also has
43+a lightweight foreign function interface which allows easy interaction
44+with external ``C`` libraries.
45+
46+Intended Audience
47+-----------------
48+
49+This tutorial is intended as a brief introduction to the language, and
50+is aimed at readers already familiar with a functional language such
51+as `Haskell <http://www.haskell.org>`_ or `OCaml <http://ocaml.org>`_.
52+In particular, a certain amount of familiarity with Haskell syntax is
53+assumed, although most concepts will at least be explained
54+briefly. The reader is also assumed to have some interest in using
55+dependent types for writing and verifying systems software.
56+
57+Example Code
58+------------
59+
60+This tutorial includes some example code, which has been tested with
61+``Idris`` version . The files are available in the ``Idris``
62+distribution, and provided along side the tutorial source, so that you
63+can try them out easily, under ``tutorial/examples``. However, it is
64+strongly recommended that you can type them in yourself, rather than
65+simply loading and reading them.
66+
67+.. [1]
68+ Typically, and perhaps confusingly, referred to in the dependently
69+ typed programming literature as “vectors”
docs/tutorial/miscellany.rstnew file+546
@@ -0,0 +1,546 @@
1+.. _sect-misc:
2+
3+==========
4+Miscellany
5+==========
6+
7+In this section we discuss a variety of additional features:
8+
9++ auto, implicit, and default arguments;
10++ literate programming;
11++ interfacing with external libraries through the foreign function
12++ interface;
13++ type providers;
14++ code generation; and
15++ the universe hierarchy.
16+
17+Auto implicit arguments
18+-----------------------
19+
20+We have already seen implicit arguments, which allows arguments to be
21+omitted when they can be inferred by the type checker, e.g.
22+
23+.. code-block:: idris
24+
25+ index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a
26+
27+In other situations, it may be possible to infer arguments not by type
28+checking but by searching the context for an appropriate value, or
29+constructing a proof. For example, the following definition of ``head``
30+which requires a proof that the list is non-empty:
31+
32+.. code-block:: idris
33+
34+ isCons : List a -> Bool
35+ isCons [] = False
36+ isCons (x :: xs) = True
37+
38+ head : (xs : List a) -> (isCons xs = True) -> a
39+ head (x :: xs) _ = x
40+
41+If the list is statically known to be non-empty, either because its
42+value is known or because a proof already exists in the context, the
43+proof can be constructed automatically. Auto implicit arguments allow
44+this to happen silently. We define ``head`` as follows:
45+
46+.. code-block:: idris
47+
48+ head : (xs : List a) -> {auto p : isCons xs = True} -> a
49+ head (x :: xs) = x
50+
51+The ``auto`` annotation on the implicit argument means that ``Idris``
52+will attempt to fill in the implicit argument using the ``trivial``
53+tactic, which searches through the context for a proof, and tries to
54+solve with ``refl`` if a proof is not found. Now when ``head`` is
55+applied, the proof can be omitted. In the case that a proof is not
56+found, it can be provided explicitly as normal:
57+
58+.. code-block:: idris
59+
60+ head xs {p = ?headProof}
61+
62+More generally, we can fill in implicit arguments with a default value
63+by annotating them with ``default``. The definition above is equivalent
64+to:
65+
66+.. code-block:: idris
67+
68+ head : (xs : List a) ->
69+ {default proof { trivial; } p : isCons xs = True} -> a
70+ head (x :: xs) = x
71+
72+Implicit conversions
73+--------------------
74+
75+``Idris`` supports the creation of *implicit conversions*, which allow
76+automatic conversion of values from one type to another when required to
77+make a term type correct. This is intended to increase convenience and
78+reduce verbosity. A contrived but simple example is the following:
79+
80+.. code-block:: idris
81+
82+ implicit intString : Int -> String
83+ intString = show
84+
85+ test : Int -> String
86+ test x = "Number " ++ x
87+
88+In general, we cannot append an ``Int`` to a ``String``, but the
89+implicit conversion function ``intString`` can convert ``x`` to a
90+``String``, so the definition of ``test`` is type correct. An implicit
91+conversion is implemented just like any other function, but given the
92+``implicit`` modifier, and restricted to one explicit argument.
93+
94+Only one implicit conversion will be applied at a time. That is,
95+implicit conversions cannot be chained. Implicit conversions of simple
96+types, as above, are however discouraged! More commonly, an implicit
97+conversion would be used to reduce verbosity in an embedded domain
98+specific language, or to hide details of a proof. Such examples are
99+beyond the scope of this tutorial.
100+
101+Literate programming
102+--------------------
103+
104+Like Haskell, ``Idris`` supports *literate* programming. If a file has
105+an extension of ``.lidr`` then it is assumed to be a literate file. In
106+literate programs, everything is assumed to be a comment unless the line
107+begins with a greater than sign ``>``, for example:
108+
109+.. code-block:: idris
110+
111+ > module literate
112+
113+ This is a comment. The main program is below
114+
115+ > main : IO ()
116+ > main = putStrLn "Hello literate world!\n"
117+
118+An additional restriction is that there must be a blank line between a
119+program line (beginning with ``>``) and a comment line (beginning with
120+any other character).
121+
122+Foreign function calls
123+----------------------
124+
125+For practical programming, it is often necessary to be able to use
126+external libraries, particularly for interfacing with the operating
127+system, file system, networking, *et cetera*. ``Idris`` provides a
128+lightweight foreign function interface for achieving this, as part of
129+the prelude. For this, we assume a certain amount of knowledge of C and
130+the ``gcc`` compiler. First, we define a datatype which describes the
131+external types we can handle:
132+
133+.. code-block:: idris
134+
135+ data FTy = FInt | FFloat | FChar | FString | FPtr | FUnit
136+
137+Each of these corresponds directly to a C type. Respectively: ``int``,
138+``double``, ``char``, ``char*``, ``void*`` and ``void``. There is also a
139+translation to a concrete ``Idris`` type, described by the following
140+function:
141+
142+.. code-block:: idris
143+
144+ interpFTy : FTy -> Type
145+ interpFTy FInt = Int
146+ interpFTy FFloat = Float
147+ interpFTy FChar = Char
148+ interpFTy FString = String
149+ interpFTy FPtr = Ptr
150+ interpFTy FUnit = ()
151+
152+A foreign function is described by a list of input types and a return
153+type, which can then be converted to an ``Idris`` type:
154+
155+.. code-block:: idris
156+
157+ ForeignTy : (xs:List FTy) -> (t:FTy) -> Type
158+
159+A foreign function is assumed to be impure, so ``ForeignTy`` builds an
160+``IO`` type, for example:
161+
162+.. code-block:: idris
163+
164+ Idris> ForeignTy [FInt, FString] FString
165+ Int -> String -> IO String : Type
166+
167+ Idris> ForeignTy [FInt, FString] FUnit
168+ Int -> String -> IO () : Type
169+
170+We build a call to a foreign function by giving the name of the
171+function, a list of argument types and the return type. The built in
172+construct ``mkForeign`` converts this description to a function callable
173+by ``Idris``:
174+
175+.. code-block:: idris
176+
177+ data Foreign : Type -> Type where
178+ FFun : String -> (xs:List FTy) -> (t:FTy) ->
179+ Foreign (ForeignTy xs t)
180+
181+ mkForeign : Foreign x -> x
182+
183+Note that the compiler expects ``mkForeign`` to be fully applied to
184+build a complete foreign function call. For example, the ``putStr``
185+function is implemented as follows, as a call to an external function
186+``putStr`` defined in the run-time system:
187+
188+.. code-block:: idris
189+
190+ putStr : String -> IO ()
191+ putStr x = mkForeign (FFun "putStr" [FString] FUnit) x
192+
193+Include and linker directives
194+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195+
196+Foreign function calls are translated directly to calls to C functions,
197+with appropriate conversion between the ``Idris`` representation of a
198+value and the C representation. Often this will require extra libraries
199+to be linked in, or extra header and object files. This is made possible
200+through the following directives:
201+
202+- ``%lib target x`` — include the ``libx`` library. If the target is
203+ ``C`` this is equivalent to passing the ``-lx`` option to ``gcc``. If
204+ the target is Java the library will be interpreted as a
205+ ``groupId:artifactId:packaging:version`` dependency coordinate for
206+ maven.
207+
208+- ``%include target x`` — use the header file or import ``x`` for the
209+ given back end target.
210+
211+- ``%link target x.o`` — link with the object file ``x.o`` when using
212+ the given back end target.
213+
214+- ``%dynamic x.so`` — dynamically link the interpreter with the shared
215+ object ``x.so``.
216+
217+Testing foreign function calls
218+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
219+
220+Normally, the Idris interpreter (used for typechecking and at the REPL)
221+will not perform IO actions. Additionally, as it neither generates C
222+code nor compiles to machine code, the ``%lib``, ``%include`` and
223+``%link`` directives have no effect. IO actions and FFI calls can be
224+tested using the special REPL command ``:x EXPR``, and C libraries can
225+be dynamically loaded in the interpreter by using the ``:dynamic``
226+command or the ``%dynamic`` directive. For example:
227+
228+.. code-block:: idris
229+
230+ Idris> :dynamic libm.so
231+ Idris> :x unsafePerformIO ((mkForeign (FFun "sin" [FFloat] FFloat)) 1.6)
232+ 0.9995736030415051 : Float
233+
234+Type Providers
235+--------------
236+
237+Idris type providers, inspired by F#’s type providers, are a means of
238+making our types be “about” something in the world outside of Idris. For
239+example, given a type that represents a database schema and a query that
240+is checked against it, a type provider could read the schema of a real
241+database during type checking.
242+
243+Idris type providers use the ordinary execution semantics of Idris to
244+run an IO action and extract the result. This result is then saved as a
245+constant in the compiled code. It can be a type, in which case it is
246+used like any other type, or it can be a value, in which case it can be
247+used as any other value, including as an index in types.
248+
249+Type providers are still an experimental extension. To enable the
250+extension, use the ``%language`` directive:
251+
252+.. code-block:: idris
253+
254+ %language TypeProviders
255+
256+A provider ``p`` for some type ``t`` is simply an expression of type
257+``IO (Provider t)``. The ``%provide`` directive causes the type checker
258+to execute the action and bind the result to a name. This is perhaps
259+best illustrated with a simple example. The type provider ``fromFile``
260+reads a text file. If the file consists of the string ``Int``, then the
261+type ``Int`` will be provided. Otherwise, it will provide the type
262+``Nat``.
263+
264+.. code-block:: idris
265+
266+ strToType : String -> Type
267+ strToType "Int" = Int
268+ strToType _ = Nat
269+
270+ fromFile : String -> IO (Provider Type)
271+ fromFile fname = do str <- readFile fname
272+ return (Provide (strToType (trim str)))
273+
274+We then use the ``%provide`` directive:
275+
276+.. code-block:: idris
277+
278+ %provide (T1 : Type) with fromFile "theType"
279+
280+ foo : T1
281+ foo = 2
282+
283+If the file named ``theType`` consists of the word ``Int``, then ``foo``
284+will be an ``Int``. Otherwise, it will be a ``Nat``. When Idris
285+encounters the directive, it first checks that the provider expression
286+``fromFile theType`` has type ``IO (Provider Type)``. Next, it executes
287+the provider. If the result is ``Provide t``, then ``T1`` is defined as
288+``t``. Otherwise, the result is an error.
289+
290+Our datatype ``Provider t`` has the following definition:
291+
292+.. code-block:: idris
293+
294+ data Provider a = Error String
295+ | Provide a
296+
297+We have already seen the ``Provide`` constructor. The ``Error``
298+constructor allows type providers to return useful error messages. The
299+example in this section was purposefully simple. More complex type
300+provider implementations, including a statically-checked SQLite binding,
301+are available in an external collection [1]_.
302+
303+C Target
304+--------
305+
306+The default target of ``Idris`` is C. Compiling via :
307+
308+::
309+
310+ $ idris hello.idr -o hello
311+
312+is equivalent to :
313+
314+::
315+
316+ $ idris --codegen C hello.idr -o hello
317+
318+When the command above is used, a temporary C source is generated, which
319+is then compiled into an executable named ``hello``.
320+
321+In order to view the generated C code, compile via :
322+
323+::
324+
325+ $ idris hello.idr -S -o hello.c
326+
327+To turn optimisations on, use the ``%flag C`` pragma within the code, as
328+is shown below :
329+
330+.. code-block:: idris
331+
332+ module Main
333+ %flag C "-O3"
334+
335+ factorial : Int -> Int
336+ factorial 0 = 1
337+ factorial n = n * (factorial (n-1))
338+
339+ main : IO ()
340+ main = do
341+ putStrLn $ show $ factorial 3
342+
343+JavaScript Target
344+-----------------
345+
346+``Idris`` is capable of producing *JavaScript* code that can be run in a
347+browser as well as in the *NodeJS* environment or alike. One can use the
348+FFI to communicate with the *JavaScript* ecosystem.
349+
350+Code Generation
351+~~~~~~~~~~~~~~~
352+
353+Code generation is split into two separate targets. To generate code
354+that is tailored for running in the browser issue the following command:
355+
356+::
357+
358+ $ idris --codegen javascript hello.idr -o hello.js
359+
360+The resulting file can be embedded into your HTML just like any other
361+*JavaScript* code.
362+
363+Generating code for *NodeJS* is slightly different. ``Idris`` outputs a
364+*JavaScript* file that can be directly executed via ``node``.
365+
366+::
367+
368+ $ idris --codegen node hello.idr -o hello
369+ $ ./hello
370+ Hello world
371+
372+Take into consideration that the *JavaScript* code generator is using
373+``console.log`` to write text to ``stdout``, this means that it will
374+automatically add a newline to the end of each string. This behaviour
375+does not show up in the *NodeJS* code generator.
376+
377+Using the FFI
378+~~~~~~~~~~~~~
379+
380+To write a useful application we need to communicate with the outside
381+world. Maybe we want to manipulate the DOM or send an Ajax request. For
382+this task we can use the FFI. Since most *JavaScript* APIs demand
383+callbacks we need to extend the FFI so we can pass functions as
384+arguments.
385+
386+The *JavaScript* FFI works a little bit differently than the regular
387+FFI. It uses positional arguments to directly insert our arguments into
388+a piece of *JavaScript* code.
389+
390+One could use the primitive addition of *JavaScript* like so:
391+
392+.. code-block:: idris
393+
394+ module Main
395+
396+ primPlus : Int -> Int -> IO Int
397+ primPlus a b = mkForeign (FFun "%0 + %1" [FInt, FInt] FInt) a b
398+
399+ main : IO ()
400+ main = do
401+ a <- primPlus 1 1
402+ b <- primPlus 1 2
403+ print (a, b)
404+
405+Notice that the ``%n`` notation qualifies the position of the ``n``-th
406+argument given to our foreign function starting from 0. When you need a
407+percent sign rather than a position simply use ``%%`` instead.
408+
409+Passing functions to a foreign function is very similar. Let’s assume
410+that we want to call the following function from the *JavaScript* world:
411+
412+.. code-block:: idris
413+
414+ function twice(f, x) {
415+ return f(f(x));
416+ }
417+
418+We obviously need to pass a function ``f`` here (we can infer it from
419+the way we use ``f`` in ``twice``, it would be more obvious if
420+*JavaScript* had types).
421+
422+The *JavaScript* FFI is able to understand functions as arguments when
423+you give it something of type ``FFunction``. The following example code
424+calls ``twice`` in *JavaScript* and returns the result to our ``Idris``
425+program:
426+
427+.. code-block:: idris
428+
429+ module Main
430+
431+ twice : (Int -> Int) -> Int -> IO Int
432+ twice f x = mkForeign (
433+ FFun "twice(%0,%1)" [FFunction FInt FInt, FInt] FInt
434+ ) f x
435+
436+ main : IO ()
437+ main = do
438+ a <- twice (+1) 1
439+ print a
440+
441+The program outputs ``3``, just like we expected.
442+
443+Including external *JavaScript* files
444+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
445+
446+Whenever one is working with *JavaScript* one might want to include
447+external libraries or just some functions that she or he wants to call
448+via FFI which are stored in external files. The *JavaScript* and
449+*NodeJS* code generators understand the ``%include`` directive. Keep in
450+mind that *JavaScript* and *NodeJS* are handled as different code
451+generators, therefore you will have to state which one you want to
452+target. This means that you can include different files for *JavaScript*
453+and *NodeJS* in the same ``Idris`` source file.
454+
455+So whenever you want to add an external *JavaScript* file you can do
456+this like so:
457+
458+For *NodeJS*:
459+
460+.. code-block:: idris
461+
462+ %include Node "path/to/external.js"
463+
464+And for use in the browser:
465+
466+.. code-block:: idris
467+
468+ %include JavaScript "path/to/external.js"
469+
470+The given files will be added to the top of the generated code.
471+
472+Including *NodeJS* modules
473+~~~~~~~~~~~~~~~~~~~~~~~~~~
474+
475+The *NodeJS* code generator can also include modules with the ``%lib``
476+directive.
477+
478+.. code-block:: idris
479+
480+ %lib Node "fs"
481+
482+This directive compiles into the following *JavaScript*
483+
484+.. code-block:: javascript
485+
486+ var fs = require("fs");
487+
488+Shrinking down generated *JavaScript*
489+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
490+
491+``Idris`` can produce very big chunks of *JavaScript* code. However, the
492+generated code can be minified using the ``closure-compiler`` from
493+Google. Any other minifier is also suitable but ``closure-compiler``
494+offers advanced compilation that does some aggressive inlining and code
495+elimination. ``Idris`` can take full advantage of this compilation mode
496+and it’s highly recommended to use it when shipping a *JavaScript*
497+application written in ``Idris``.
498+
499+Cumulativity
500+------------
501+
502+Since values can appear in types and *vice versa*, it is natural that
503+types themselves have types. For example:
504+
505+::
506+
507+ *universe> :t Nat
508+ Nat : Type
509+ *universe> :t Vect
510+ Vect : Nat -> Type -> Type
511+
512+But what about the type of ``Type``? If we ask ``Idris`` it reports
513+
514+::
515+
516+ *universe> :t Type
517+ Type : Type 1
518+
519+If ``Type`` were its own type, it would lead to an inconsistency due to
520+`Girard’s paradox <http://www.cs.cmu.edu/afs/cs.cmu.edu/user/kw/www/scans/girard72thesis.pdf>`_ , so internally there is a
521+*hierarchy* of types (or *universes*):
522+
523+.. code-block:: idris
524+
525+ Type : Type 1 : Type 2 : Type 3 : ...
526+
527+Universes are *cumulative*, that is, if ``x : Type n`` we can also have
528+that ``x : Type m``, as long as ``n < m``. The typechecker generates
529+such universe constraints and reports an error if any inconsistencies
530+are found. Ordinarily, a programmer does not need to worry about this,
531+but it does prevent (contrived) programs such as the following:
532+
533+.. code-block:: idris
534+
535+ myid : (a : Type) -> a -> a
536+ myid _ x = x
537+
538+ idid : (a : Type) -> a -> a
539+ idid = myid _ myid
540+
541+The application of ``myid`` to itself leads to a cycle in the universe
542+hierarchy — ``myid``\ ’s first argument is a ``Type``, which cannot be
543+at a lower level than required if it is applied to itself.
544+
545+.. [1]
546+ https://github.com/david-christiansen/idris-type-providers
docs/tutorial/modules.rstnew file+222
@@ -0,0 +1,222 @@
1+.. _sect-namespaces:
2+
3+=======================
4+Modules and Namespaces
5+=======================
6+
7+An ``Idris`` program consists of a collection of modules. Each module
8+includes an optional ``module`` declaration giving the name of the
9+module, a list of ``import`` statements giving the other modules which
10+are to be imported, and a collection of declarations and definitions of
11+types, classes and functions. For example, Listing :ref:`bstmod` gives a
12+module which defines a binary tree type ``BTree`` (in a file
13+``btree.idr``) and Listing :ref:`bstmain` gives a main program (in a file
14+``bmain.idr`` which uses the ``bst`` module to sort a list.
15+
16+.. _bstmod:
17+.. code-block:: idris
18+ :caption: Binary Tree Module
19+
20+ module btree
21+
22+ data BTree a = Leaf
23+ | Node (BTree a) a (BTree a)
24+
25+ insert : Ord a => a -> BTree a -> BTree a
26+ insert x Leaf = Node Leaf x Leaf
27+ insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)
28+ else (Node l v (insert x r))
29+
30+ toList : BTree a -> List a
31+ toList Leaf = []
32+ toList (Node l v r) = btree.toList l ++ (v :: btree.toList r)
33+
34+ toTree : Ord a => List a -> BTree a
35+ toTree [] = Leaf
36+ toTree (x :: xs) = insert x (toTree xs)
37+
38+.. _bstmain:
39+.. code-block:: idris
40+ :caption: Binary Tree Main Program
41+
42+ module Main
43+
44+ import btree
45+
46+ main : IO ()
47+ main = do let t = toTree [1,8,2,7,9,3]
48+ print (btree.toList t)
49+
50+The same names can be defined in multiple modules. This is possible
51+because in practice names are *qualified* with the name of the module.
52+The names defined in the ``btree`` module are, in full:
53+
54++ ``btree.BTree``
55++ ``btree.Leaf``
56++ ``btree.Node``
57++ ``btree.insert``
58++ ``btree.toList``
59++ ``btree.toTree``
60+
61+If names are otherwise unambiguous, there is no need to give the fully
62+qualified name. Names can be disambiguated either by giving an explicit
63+qualification, or according to their type.
64+
65+There is no formal link between the module name and its filename,
66+although it is generally advisable to use the same name for each. An
67+``import`` statement refers to a filename, using dots to separate
68+directories. For example, ``import foo.bar`` would import the file
69+``foo/bar.idr``, which would conventionally have the module declaration
70+``module foo.bar``. The only requirement for module names is that the
71+main module, with the ``main`` function, must be called
72+``Main``—although its filename need not be ``Main.idr``.
73+
74+Export Modifiers
75+----------------
76+
77+By default, all names defined in a module are exported for use by other
78+modules. However, it is good practice only to export a minimal interface
79+and keep internal details abstract. ``Idris`` allows functions, types,
80+and classes to be marked as: ``public``, ``abstract`` or ``private``:
81+
82+- ``public`` means that both the name and definition are exported. For
83+ functions, this means that the implementation is exported (which
84+ means, for example, it can be used in a dependent type). For data
85+ types, this means that the type name and the constructors are
86+ exported. For classes, this means that the class name and method
87+ names are exported.
88+
89+- ``abstract`` means that only the name is exported. For functions,
90+ this means that the implementation is not exported. For data types,
91+ this means that the type name is exported but not the constructors.
92+ For classes, this means that the class name is exported but not the
93+ method names.
94+
95+- ``private`` means that neither the name nor the definition is
96+ exported.
97+
98+.. note::
99+ If any definition is given an export modifier, then all names with no modifier are assumed to be ``private``.
100+
101+For our ``btree`` module, it makes sense for the tree data type and the
102+functions to be exported as ``abstract``, as we see in
103+Listing :ref:`bstmodp`.
104+
105+.. _bstmodp:
106+.. code-block:: idris
107+ :caption: Binary Tree Module, with export modifiers
108+
109+ module btree
110+
111+ abstract data BTree a = Leaf
112+ | Node (BTree a) a (BTree a)
113+
114+ abstract
115+ insert : Ord a => a -> BTree a -> BTree a
116+ insert x Leaf = Node Leaf x Leaf
117+ insert x (Node l v r) = if (x < v) then (Node (insert x l) v r)
118+ else (Node l v (insert x r))
119+
120+ abstract
121+ toList : BTree a -> List a
122+ toList Leaf = []
123+ toList (Node l v r) = btree.toList l ++ (v :: btree.toList r)
124+
125+ abstract
126+ toTree : Ord a => List a -> BTree a
127+ toTree [] = Leaf
128+ toTree (x :: xs) = insert x (toTree xs)
129+
130+Finally, the default export mode can be changed with the ``%access``
131+directive, for example:
132+
133+In this case, any function with no access modifier will be exported as
134+``abstract``, rather than left ``private``.
135+
136+Additionally, a module can re-export a module it has imported, by using
137+the ``public`` modifier on an ``import``. For example:
138+
139+.. code-block:: idris
140+
141+ module A
142+
143+ import B import public C
144+
145+ public a : AType a = ...
146+
147+The module ``A`` will export the name ``a``, as well as any public or
148+abstract names in module ``C``, but will not re-export anything from
149+module ``B``.
150+
151+Explicit Namespaces
152+-------------------
153+
154+Defining a module also defines a namespace implicitly. However,
155+namespaces can also be given *explicitly*. This is most useful if you
156+wish to overload names within the same module:
157+
158+.. code-block:: idris
159+
160+ module foo
161+
162+ namespace x
163+ test : Int -> Int
164+ test x = x * 2
165+
166+ namespace y
167+ test : String -> String
168+ test x = x ++ x
169+
170+This (admittedly contrived) module defines two functions with fully
171+qualified names ``foo.x.test`` and ``foo.y.test``, which can be
172+disambiguated by their types:
173+
174+::
175+
176+ *foo> test 3
177+ 6 : Int
178+ *foo> test "foo"
179+ "foofoo" : String
180+
181+Parameterised blocks
182+--------------------
183+
184+Groups of functions can be parameterised over a number of arguments
185+using a ``parameters`` declaration, for example:
186+
187+.. code-block:: idris
188+
189+ parameters (x : Nat, y : Nat)
190+ addAll : Nat -> Nat
191+ addAll z = x + y + z
192+
193+The effect of a ``parameters`` block is to add the declared parameters
194+to every function, type and data constructor within the block. Outside
195+the block, the parameters must be given explicitly:
196+
197+::
198+
199+ *params> :t addAll
200+ addAll : Nat -> Nat -> Nat -> Nat
201+
202+Parameters blocks can be nested, and can also include data declarations,
203+in which case the parameters are added explicitly to all type and data
204+constructors. They may also be dependent types with implicit arguments:
205+
206+.. code-block:: idris
207+
208+ parameters (y : Nat, xs : Vect x a)
209+ data Vects : Type -> Type where
210+ MkVects : Vect y a -> Vects a
211+
212+ append : Vects a -> Vect (x + y) a
213+ append (MkVects ys) = xs ++ ys
214+
215+To use ``Vects`` or ``append`` outside the block, we must also give the
216+``xs`` and ``y`` arguments. Here, we can use placeholders for the values
217+which can be inferred by the type checker:
218+
219+::
220+
221+ *params> show (append _ _ (MkVects _ [1,2,3] [4,5,6]))
222+ "[1, 2, 3, 4, 5, 6]" : String
docs/tutorial/provisional.rstnew file+268
@@ -0,0 +1,268 @@
1+.. _sect-provisional:
2+
3+=======================
4+Provisional Definitions
5+=======================
6+
7+Sometimes when programming with dependent types, the type required by
8+the type checker and the type of the program we have written will be
9+different (in that they do not have the same normal form), but
10+nevertheless provably equal. For example, recall the ``parity``
11+function:
12+
13+.. code-block:: idris
14+
15+ data Parity : Nat -> Type where
16+ Even : Parity (n + n)
17+ Odd : Parity (S (n + n))
18+
19+We’d like to implement this as follows:
20+
21+.. code-block:: idris
22+
23+ parity : (n:Nat) -> Parity n
24+ parity Z = Even {n=Z}
25+ parity (S Z) = Odd {n=Z}
26+ parity (S (S k)) with (parity k)
27+ parity (S (S (j + j))) | Even = Even {n=S j}
28+ parity (S (S (S (j + j)))) | Odd = Odd {n=S j}
29+
30+This simply states that zero is even, one is odd, and recursively, the
31+parity of ``k+2`` is the same as the parity of ``k``. Explicitly marking
32+the value of ``n`` is even and odd is necessary to help type inference.
33+Unfortunately, the type checker rejects this:
34+
35+::
36+
37+ viewsbroken.idr:12:10:When elaborating right hand side of ViewsBroken.parity:
38+ Can't unify
39+ Parity (plus (S j) (S j))
40+ with
41+ Parity (S (S (plus j j)))
42+
43+ Specifically:
44+ Can't unify
45+ plus (S j) (S j)
46+ with
47+ S (S (plus j j))
48+
49+The type checker is telling us that ``(j+1)+(j+1)`` and ``2+j+j`` do not
50+normalise to the same value. This is because ``plus`` is defined by
51+recursion on its first argument, and in the second value, there is a
52+successor symbol on the second argument, so this will not help with
53+reduction. These values are obviously equal — how can we rewrite the
54+program to fix this problem?
55+
56+Provisional definitions
57+-----------------------
58+
59+*Provisional definitions* help with this problem by allowing us to defer
60+the proof details until a later point. There are two main reasons why
61+they are useful.
62+
63+- When *prototyping*, it is useful to be able to test programs before
64+ finishing all the details of proofs.
65+
66+- When *reading* a program, it is often much clearer to defer the proof
67+ details so that they do not distract the reader from the underlying
68+ algorithm.
69+
70+Provisional definitions are written in the same way as ordinary
71+definitions, except that they introduce the right hand side with a
72+``?=`` rather than ``=``. We define ``parity`` as follows:
73+
74+When written in this form, instead of reporting a type error, ``Idris``
75+will insert a metavariable standing for a theorem which will correct the
76+type error. ``Idris`` tells us we have two proof obligations, with names
77+generated from the module and function names:
78+
79+.. code-block:: idris
80+
81+ *views> :m
82+ Global metavariables:
83+ [views.parity_lemma_2,views.parity_lemma_1]
84+
85+The first of these has the following type:
86+
87+.. code-block:: idris
88+
89+ *views> :p views.parity_lemma_1
90+
91+ ---------------------------------- (views.parity_lemma_1) --------
92+ {hole0} : (j : Nat) -> (Parity (plus (S j) (S j))) -> Parity (S (S (plus j j)))
93+
94+ -views.parity_lemma_1>
95+
96+The two arguments are ``j``, the variable in scope from the pattern
97+match, and ``value``, which is the value we gave in the right hand side
98+of the provisional definition. Our goal is to rewrite the type so that
99+we can use this value. We can achieve this using the following theorem
100+from the prelude:
101+
102+.. code-block:: idris
103+
104+ plusSuccRightSucc : (left : Nat) -> (right : Nat) ->
105+ S (left + right) = left + (S right)
106+
107+We need to use ``compute`` again to unfold the definition of ``plus``:
108+
109+.. code-block:: idris
110+
111+ -views.parity_lemma_1> compute
112+
113+
114+ ---------------------------------- (views.parity_lemma_1) --------
115+ {hole0} : (j : Nat) -> (Parity (S (plus j (S j)))) -> Parity (S (S (plus j j)))
116+
117+After applying ``intros`` we have:
118+
119+.. code-block:: idris
120+
121+ -views.parity_lemma_1> intros
122+
123+ j : Nat
124+ value : Parity (S (plus j (S j)))
125+ ---------------------------------- (views.parity_lemma_1) --------
126+ {hole2} : Parity (S (S (plus j j)))
127+
128+Then we apply the ``plusSuccRightSucc`` rewrite rule, symmetrically, to
129+``j`` and ``j``, giving:
130+
131+.. code-block:: idris
132+
133+ -views.parity_lemma_1> rewrite sym (plusSuccRightSucc j j)
134+
135+ j : Nat
136+ value : Parity (S (plus j (S j)))
137+ ---------------------------------- (views.parity_lemma_1) --------
138+ {hole3} : Parity (S (plus j (S j)))
139+
140+``sym`` is a function, defined in the library, which reverses the order
141+of the rewrite:
142+
143+.. code-block:: idris
144+
145+ sym : l = r -> r = l
146+ sym Refl = Refl
147+
148+We can complete this proof using the ``trivial`` tactic, which finds
149+``value`` in the premises. The proof of the second lemma proceeds in
150+exactly the same way.
151+
152+We can now test the ``natToBin`` function from Section :ref:`sect-nattobin`
153+at the prompt. The number 42 is 101010 in binary. The binary digits are
154+reversed:
155+
156+.. code-block:: idris
157+
158+ *views> show (natToBin 42)
159+ "[False, True, False, True, False, True]" : String
160+
161+Suspension of Disbelief
162+-----------------------
163+
164+``Idris`` requires that proofs be complete before compiling programs
165+(although evaluation at the prompt is possible without proof details).
166+Sometimes, especially when prototyping, it is easier not to have to do
167+this. It might even be beneficial to test programs before attempting to
168+prove things about them — if testing finds an error, you know you had
169+better not waste your time proving something!
170+
171+Therefore, ``Idris`` provides a built-in coercion function, which allows
172+you to use a value of the incorrect types:
173+
174+.. code-block:: idris
175+
176+ believe_me : a -> b
177+
178+Obviously, this should be used with extreme caution. It is useful when
179+prototyping, and can also be appropriate when asserting properties of
180+external code (perhaps in an external C library). The “proof” of
181+``views.parity_lemma_1`` using this is:
182+
183+.. code-block:: idris
184+
185+ views.parity_lemma_2 = proof {
186+ intro;
187+ intro;
188+ exact believe_me value;
189+ }
190+
191+The ``exact`` tactic allows us to provide an exact value for the proof.
192+In this case, we assert that the value we gave was correct.
193+
194+Example: Binary numbers
195+-----------------------
196+
197+Previously, we implemented conversion to binary numbers using the
198+``Parity`` view. Here, we show how to use the same view to implement a
199+verified conversion to binary. We begin by indexing binary numbers over
200+their ``Nat`` equivalent. This is a common pattern, linking a
201+representation (in this case ``Binary``) with a meaning (in this case
202+``Nat``):
203+
204+.. code-block:: idris
205+
206+ data Binary : Nat -> Type where
207+ bEnd : Binary Z
208+ bO : Binary n -> Binary (n + n)
209+ bI : Binary n -> Binary (S (n + n))
210+
211+``bO`` and ``bI`` take a binary number as an argument and effectively
212+shift it one bit left, adding either a zero or one as the new least
213+significant bit. The index, ``n + n`` or ``S (n + n)`` states the result
214+that this left shift then add will have to the meaning of the number.
215+This will result in a representation with the least significant bit at
216+the front.
217+
218+Now a function which converts a Nat to binary will state, in the type,
219+that the resulting binary number is a faithful representation of the
220+original Nat:
221+
222+.. code-block:: idris
223+
224+ natToBin : (n:Nat) -> Binary n
225+
226+The ``Parity`` view makes the definition fairly simple — halving the
227+number is effectively a right shift after all — although we need to use
228+a provisional definition in the odd case:
229+
230+.. code-block:: idris
231+
232+ natToBin : (n:Nat) -> Binary n
233+ natToBin Z = bEnd
234+ natToBin (S k) with (parity k)
235+ natToBin (S (j + j)) | even = bI (natToBin j)
236+ natToBin (S (S (j + j))) | odd ?= bO (natToBin (S j))
237+
238+The problem with the odd case is the same as in the definition of
239+``parity``, and the proof proceeds in the same way:
240+
241+.. code-block:: idris
242+
243+ natToBin_lemma_1 = proof {
244+ intro;
245+ intro;
246+ rewrite sym (plusSuccRightSucc j j);
247+ trivial;
248+ }
249+
250+To finish, we’ll implement a main program which reads an integer from
251+the user and outputs it in binary.
252+
253+.. code-block:: idris
254+
255+ main : IO ()
256+ main = do putStr "Enter a number: "
257+ x <- getLine
258+ print (natToBin (fromInteger (cast x)))
259+
260+For this to work, of course, we need a ``Show`` instance for
261+``Binary n``:
262+
263+.. code-block:: idris
264+
265+ instance Show (Binary n) where
266+ show (bO x) = show x ++ "0"
267+ show (bI x) = show x ++ "1"
268+ show bEnd = ""
docs/tutorial/starting.rstnew file+84
@@ -0,0 +1,84 @@
1+.. _sect-starting:
2+
3+===============
4+Getting Started
5+===============
6+
7+Prerequisites
8+-------------
9+
10+Before installing ``Idris``, you will need to make sure you have all
11+of the necessary libraries and tools. You will need:
12+
13+- A fairly recent Haskell platform. Version 2013.2.0.0 should be
14+ sufficiently recent, though it is better to be completely up to
15+ date.
16+
17+- The *GNU Multiple Precision Arithmetic Library* (GMP) is available
18+ from MacPorts/Homebrew and all major Linux distributions.
19+
20+Downloading and Installing
21+--------------------------
22+
23+The easiest way to install ``Idris``, if you have all of the
24+prerequisites, is to type:
25+
26+::
27+
28+ cabal update; cabal install idris
29+
30+This will install the latest version released on Hackage, along with
31+any dependencies. If, however, you would like the most up to date
32+development version you can find it, as well as build intructions, on
33+GitHub at: https://github.com/idris-lang/Idris-dev.
34+
35+To check that installation has succeeded, and to write your first
36+``Idris`` program, create a file called “``hello.idr``” containing the
37+following text:
38+
39+If you are familiar with Haskell, it should be fairly clear what the
40+program is doing and how it works, but if not, we will explain the
41+details later. You can compile the program to an executable by
42+entering ``idris hello.idr -o hello`` at the shell prompt. This will
43+create an executable called ``hello``, which you can run:
44+
45+::
46+
47+ $ idris hello.idr -o hello
48+ $ ./hello
49+ Hello world
50+
51+Note that the ``$`` indicates the shell prompt! Should the ``Idris``
52+executable not be found please ensure that you have added
53+``~/.cabal/bin`` to your ``$PATH`` environment variable. Mac OS X
54+users may find they need to use ``~/Library/Haskell/bin``
55+instead. Some useful options to the ``Idris`` command are:
56+
57+- ``-o prog`` to compile to an executable called ``prog``.
58+
59+- ``--check`` type check the file and its dependencies without
60+ starting the interactive environment.
61+
62+- ``--help`` display usage summary and command line options
63+
64+The Interactive Environment
65+---------------------------
66+
67+Entering ``idris`` at the shell prompt starts up the interactive
68+environment. You should see something like the following:
69+
70+.. literalinclude:: ../listing/idris-prompt-start.txt
71+
72+This gives a ``ghci`` style interface which allows evaluation of, as
73+well as type checking of, expressions; theorem proving, compilation;
74+editing; and various other operations. The command ``:?`` gives a list
75+of supported commands. Listing :ref:`run1` shows an example run in
76+which ``hello.idr`` is loaded, the type of ``main`` is checked and
77+then the program is compiled to the executable ``hello``. Type
78+checking a file, if successful, creates a bytecode version of the file
79+(in this case ``hello.ibc``) to speed up loading in future. The
80+bytecode is regenerated if the source file changes.
81+
82+.. literalinclude:: ../listing/idris-prompt-helloworld.txt
83+ :caption: Sample Interactive Run
84+ :name: run1
docs/tutorial/syntax.rstnew file+208
@@ -0,0 +1,208 @@
1+Syntax Extensions
2+=================
3+
4+supports the implementation of *Embedded Domain Specific Languages*
5+(EDSLs) in several ways [1]_. One way, as we have already seen, is
6+through extending ``do`` notation. Another important way is to allow
7+extension of the core syntax. In this section we describe two ways of
8+extending the syntax: ``syntax`` rules and ``dsl`` notation.
9+
10+``syntax`` rules
11+----------------
12+
13+We have seen ``if...then...else`` expressions, but these are not built
14+in. Instead, we can define a function in the prelude as follows (we
15+have already seen this function in Section :ref:`sect-lazy`):
16+
17+.. code-block:: idris
18+
19+ boolCase : (x:Bool) -> Lazy a -> Lazy a -> a;
20+ boolCase True t e = t;
21+ boolCase False t e = e;
22+
23+and then extend the core syntax with a ``syntax`` declaration:
24+
25+.. code-block:: idris
26+
27+ syntax "if" [test] "then" [t] "else" [e] = boolCase test t e;
28+
29+The left hand side of a ``syntax`` declaration describes the syntax
30+rule, and the right hand side describes its expansion. The syntax rule
31+itself consists of:
32+
33+- **Keywords** — here, ``if``, ``then`` and ``else``, which must be
34+ valid identifiers
35+
36+- **Non-terminals** — included in square brackets, ``[test]``, ``[t]``
37+ and ``[e]`` here, which stand for arbitrary expressions. To avoid
38+ parsing ambiguities, these expressions cannot use syntax extensions
39+ at the top level (though they can be used in parentheses).
40+
41+- **Names** — included in braces, which stand for names which may be
42+ bound on the right hand side.
43+
44+- **Symbols** — included in quotations marks, e.g. ``:=``. This can
45+ also be used to include reserved words in syntax rules, such as
46+ ``let`` or ``in``.
47+
48+The limitations on the form of a syntax rule are that it must include
49+at least one symbol or keyword, and there must be no repeated
50+variables standing for non-terminals. Any expression can be used, but
51+if there are two non-terminals in a row in a rule, only simple
52+expressions may be used (that is, variables, constants, or bracketed
53+expressions). Rules can use previously defined rules, but may not be
54+recursive. The following syntax extensions would therefore be valid:
55+
56+.. code-block:: idris
57+
58+ syntax [var] ":=" [val] = Assign var val;
59+ syntax [test] "?" [t] ":" [e] = if test then t else e;
60+ syntax "select" [x] "from" [t] "where" [w] = SelectWhere x t w;
61+ syntax "select" [x] "from" [t] = Select x t;
62+
63+Syntax macros can be further restricted to apply only in patterns (i.e.,
64+only on the left hand side of a pattern match clause) or only in terms
65+(i.e. everywhere but the left hand side of a pattern match clause) by
66+being marked as ``pattern`` or ``term`` syntax rules. For example, we
67+might define an interval as follows, with a static check that the lower
68+bound is below the upper bound using ``so``:
69+
70+.. code-block:: idris
71+
72+ data Interval : Type where
73+ MkInterval : (lower : Float) -> (upper : Float) ->
74+ so (lower < upper) -> Interval
75+
76+We can define a syntax which, in patterns, always matches ``oh`` for
77+the proof argument, and in terms requires a proof term to be provided:
78+
79+.. code-block:: idris
80+
81+ pattern syntax "[" [x] "..." [y] "]" = MkInterval x y oh
82+ term syntax "[" [x] "..." [y] "]" = MkInterval x y ?bounds_lemma
83+
84+In terms, the syntax ``[x...y]`` will generate a proof obligation
85+``bounds_lemma`` (possibly renamed).
86+
87+Finally, syntax rules may be used to introduce alternative binding
88+forms. For example, a ``for`` loop binds a variable on each iteration:
89+
90+.. code-block:: idris
91+
92+ syntax "for" {x} "in" [xs] ":" [body] = forLoop xs (\x => body)
93+
94+ main : IO ()
95+ main = do for x in [1..10]:
96+ putStrLn ("Number " ++ show x)
97+ putStrLn "Done!"
98+
99+Note that we have used the ``{x}`` form to state that ``x`` represents
100+a bound variable, substituted on the right hand side. We have also put
101+``in`` in quotation marks since it is already a reserved word.
102+
103+``dsl`` notation
104+----------------
105+
106+The well-typed interpreter in Section :ref:`sect-interp` is a simple
107+example of a common programming pattern with dependent types. Namely:
108+describe an *object language* and its type system with dependent types
109+to guarantee that only well-typed programs can be represented, then
110+program using that representation. Using this approach we can, for
111+example, write programs for serialising binary data [2]_ or running
112+concurrent processes safely [3]_.
113+
114+Unfortunately, the form of object language programs makes it rather
115+hard to program this way in practice. Recall the factorial program in
116+``Expr`` for example:
117+
118+.. code-block:: idris
119+
120+ fact : Expr G (TyFun TyInt TyInt)
121+ fact = Lam (If (Op (==) (Var Stop) (Val 0))
122+ (Val 1) (Op (*) (app fact (Op (-) (Var Stop) (Val 1)))
123+ (Var Stop)))
124+
125+Since this is a particularly useful pattern, ``Idris`` provides syntax
126+overloading [1]_ to make it easier to program in such object
127+languages:
128+
129+.. code-block:: idris
130+
131+ mkLam : TTName -> Expr (t::g) t' -> Expr g (TyFun t t')
132+ mkLam _ body = Lam body
133+
134+ dsl expr
135+ variable = Var
136+ index_first = Stop
137+ index_next = Pop
138+ lambda = mkLam
139+
140+A ``dsl`` block describes how each syntactic construct is represented
141+in an object language. Here, in the ``expr`` language, any variable is
142+translated to the ``Var`` constructor, using ``Pop`` and ``Stop`` to
143+construct the de Bruijn index (i.e., to count how many bindings since
144+the variable itself was bound); and any lambda is translated to a
145+``Lam`` constructor. The ``mkLam`` function simply ignores its first
146+argument, which is the name that the user chose for the variable. It
147+is also possible to overload ``let`` and dependent function syntax
148+(``pi``) in this way. We can now write ``fact`` as follows:
149+
150+.. code-block:: idris
151+
152+ fact : Expr G (TyFun TyInt TyInt)
153+ fact = expr (\x => If (Op (==) x (Val 0))
154+ (Val 1) (Op (*) (app fact (Op (-) x (Val 1))) x))
155+
156+In this new version, ``expr`` declares that the next expression will
157+be overloaded. We can take this further, using idiom brackets, by
158+declaring:
159+
160+.. code-block:: idris
161+
162+ (<$>) : (f : Lazy (Expr G (TyFun a t))) -> Expr G a -> Expr G t
163+ (<$>) f a = App f a
164+
165+ pure : Expr G a -> Expr G a
166+ pure = id
167+
168+Note that there is no need for these to be part of an instance of
169+``Applicative``, since idiom bracket notation translates directly to
170+the names ``<*>`` and ``pure``, and ad-hoc type-directed overloading
171+is allowed. We can now say:
172+
173+.. code-block:: idris
174+
175+ fact : Expr G (TyFun TyInt TyInt)
176+ fact = expr (\x => If (Op (==) x (Val 0))
177+ (Val 1) (Op (*) [| fact (Op (-) x (Val 1)) |] x))
178+
179+With some more ad-hoc overloading and type class instances, and a new
180+syntax rule, we can even go as far as:
181+
182+.. code-block:: idris
183+
184+ syntax "IF" [x] "THEN" [t] "ELSE" [e] = If x t e
185+
186+ fact : Expr G (TyFun TyInt TyInt)
187+ fact = expr (\x => IF x == 0 THEN 1 ELSE [| fact (x - 1) |] * x)
188+
189+
190+.. [1] Edwin Brady and Kevin Hammond. 2012. Resource-Safe systems
191+ programming with embedded domain specific languages. In
192+ Proceedings of the 14th international conference on Practical
193+ Aspects of Declarative Languages (PADL'12), Claudio Russo and
194+ Neng-Fa Zhou (Eds.). Springer-Verlag, Berlin, Heidelberg,
195+ 242-257. DOI=10.1007/978-3-642-27694-1_18
196+ http://dx.doi.org/10.1007/978-3-642-27694-1_18
197+
198+.. [2] Edwin C. Brady. 2011. IDRIS ---: systems programming meets full
199+ dependent types. In Proceedings of the 5th ACM workshop on
200+ Programming languages meets program verification (PLPV
201+ '11). ACM, New York, NY, USA,
202+ 43-54. DOI=10.1145/1929529.1929536
203+ http://doi.acm.org/10.1145/1929529.1929536
204+
205+.. [3] Edwin Brady and Kevin Hammond. 2010. Correct-by-Construction
206+ Concurrency: Using Dependent Types to Verify Implementations of
207+ Effectful Resource Usage Protocols. Fundam. Inf. 102, 2 (April
208+ 2010), 145-176. http://dl.acm.org/citation.cfm?id=1883636
docs/tutorial/theorems.rstnew file+444
@@ -0,0 +1,444 @@
1+.. _sect-theorems:
2+
3+===============
4+Theorem Proving
5+===============
6+
7+Equality
8+--------
9+
10+allows propositional equalities to be declared, allowing theorems about
11+programs to be stated and proved. Equality is built in, but conceptually
12+has the following definition:
13+
14+.. code-block:: idris
15+
16+ data (=) : a -> b -> Type where
17+ Refl : x = x
18+
19+Equalities can be proposed between any values of any types, but the only
20+way to construct a proof of equality is if values actually are equal.
21+For example:
22+
23+.. code-block:: idris
24+
25+ fiveIsFive : 5 = 5
26+ fiveIsFive = Refl
27+
28+ twoPlusTwo : 2 + 2 = 4
29+ twoPlusTwo = Refl
30+
31+.. _sect-empty:
32+
33+The Empty Type
34+--------------
35+
36+There is an empty type, :math:`\bot`, which has no constructors. It is
37+therefore impossible to construct an element of the empty type, at least
38+without using a partially defined or general recursive function (see
39+Section :ref:`sect-totality` for more details). We can therefore use the
40+empty type to prove that something is impossible, for example zero is
41+never equal to a successor:
42+
43+.. code-block:: idris
44+
45+ disjoint : (n : Nat) -> Z = S n -> Void
46+ disjoint n p = replace {P = disjointTy} p ()
47+ where
48+ disjointTy : Nat -> Type
49+ disjointTy Z = ()
50+ disjointTy (S k) = Void
51+
52+There is no need to worry too much about how this function works —
53+essentially, it applies the library function ``replace``, which uses an
54+equality proof to transform a predicate. Here we use it to transform a
55+value of a type which can exist, the empty tuple, to a value of a type
56+which can’t, by using a proof of something which can’t exist.
57+
58+Once we have an element of the empty type, we can prove anything.
59+``void`` is defined in the library, to assist with proofs by
60+contradiction.
61+
62+.. code-block:: idris
63+
64+ void : Void -> a
65+
66+Simple Theorems
67+---------------
68+
69+When type checking dependent types, the type itself gets *normalised*.
70+So imagine we want to prove the following theorem about the reduction
71+behaviour of ``plus``:
72+
73+.. code-block:: idris
74+
75+ plusReduces : (n:Nat) -> plus Z n = n
76+
77+We’ve written down the statement of the theorem as a type, in just the
78+same way as we would write the type of a program. In fact there is no
79+real distinction between proofs and programs. A proof, as far as we are
80+concerned here, is merely a program with a precise enough type to
81+guarantee a particular property of interest.
82+
83+We won’t go into details here, but the Curry-Howard correspondence [1]_
84+explains this relationship. The proof itself is trivial, because
85+``plus Z n`` normalises to ``n`` by the definition of ``plus``:
86+
87+.. code-block:: idris
88+
89+ plusReduces n = Refl
90+
91+It is slightly harder if we try the arguments the other way, because
92+plus is defined by recursion on its first argument. The proof also works
93+by recursion on the first argument to ``plus``, namely ``n``.
94+
95+.. code-block:: idris
96+
97+ plusReducesZ : (n:Nat) -> n = plus n Z
98+ plusReducesZ Z = Refl
99+ plusReducesZ (S k) = cong (plusReducesZ k)
100+
101+``cong`` is a function defined in the library which states that equality
102+respects function application:
103+
104+.. code-block:: idris
105+
106+ cong : {f : t -> u} -> a = b -> f a = f b
107+
108+We can do the same for the reduction behaviour of plus on successors:
109+
110+.. code-block:: idris
111+
112+ plusReducesS : (n:Nat) -> (m:Nat) -> S (plus n m) = plus n (S m)
113+ plusReducesS Z m = Refl
114+ plusReducesS (S k) m = cong (plusReducesS k m)
115+
116+Even for trival theorems like these, the proofs are a little tricky to
117+construct in one go. When things get even slightly more complicated, it
118+becomes too much to think about to construct proofs in this ‘batch
119+mode’. therefore provides an interactive proof mode.
120+
121+Interactive theorem proving
122+---------------------------
123+
124+Instead of writing the proof in one go, we can use ’s interactive proof
125+mode. To do this, we write the general *structure* of the proof, and use
126+the interactive mode to complete the details. We’ll be constructing the
127+proof by *induction*, so we write the cases for ``Z`` and ``S``, with a
128+recursive call in the ``S`` case giving the inductive hypothesis, and
129+insert *metavariables* for the rest of the definition:
130+
131+.. code-block:: idris
132+
133+ plusReducesZ' : (n:Nat) -> n = plus n Z
134+ plusReducesZ' Z = ?plusredZ_Z
135+ plusReducesZ' (S k) = let ih = plusReducesZ' k in
136+ ?plusredZ_S
137+
138+On running , two global names are created, ``plusredZ_Z`` and
139+``plusredZ_S``, with no definition. We can use the ``:m`` command at the
140+prompt to find out which metavariables are still to be solved (or, more
141+precisely, which functions exist but have no definitions), then the
142+``:t`` command to see their types:
143+
144+.. code-block:: idris
145+
146+ *theorems> :m
147+ Global metavariables:
148+ [plusredZ_S,plusredZ_Z]
149+
150+.. code-block:: idris
151+
152+ *theorems> :t plusredZ_Z
153+ plusredZ_Z : Z = plus Z Z
154+
155+ *theorems> :t plusredZ_S
156+ plusredZ_S : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
157+
158+The ``:p`` command enters interactive proof mode, which can be used to
159+complete the missing definitions.
160+
161+.. code-block:: idris
162+
163+ *theorems> :p plusredZ_Z
164+
165+ ---------------------------------- (plusredZ_Z) --------
166+ {hole0} : Z = plus Z Z
167+
168+This gives us a list of premises (above the line; there are none here)
169+and the current goal (below the line; named ``{hole0}`` here). At the
170+prompt we can enter tactics to direct the construction of the proof. In
171+this case, we can normalise the goal with the ``compute`` tactic:
172+
173+.. code-block:: idris
174+
175+ -plusredZ_Z> compute
176+
177+ ---------------------------------- (plusredZ_Z) --------
178+ {hole0} : Z = Z
179+
180+Now we have to prove that ``Z`` equals ``Z``, which is easy to prove by
181+``Refl``. To apply a function, such as ``Refl``, we use ``refine`` which
182+introduces subgoals for each of the function’s explicit arguments
183+(``Refl`` has none):
184+
185+.. code-block:: idris
186+
187+ -plusredZ_Z> refine Refl
188+ plusredZ_Z: no more goals
189+
190+Here, we could also have used the ``trivial`` tactic, which tries to
191+refine by ``Refl``, and if that fails, tries to refine by each name in
192+the local context. When a proof is complete, we use the ``qed`` tactic
193+to add the proof to the global context, and remove the metavariable from
194+the unsolved metavariables list. This also outputs a trace of the proof:
195+
196+.. code-block:: idris
197+
198+ -plusredZ_Z> qed
199+ plusredZ_Z = proof
200+ compute
201+ refine Refl
202+
203+.. code-block:: idris
204+
205+ *theorems> :m
206+ Global metavariables:
207+ [plusredZ_S]
208+
209+The ``:addproof`` command, at the interactive prompt, will add the proof
210+to the source file (effectively in an appendix). Let us now prove the
211+other required lemma, ``plusredZ_S``:
212+
213+.. code-block:: idris
214+
215+ *theorems> :p plusredZ_S
216+
217+ ---------------------------------- (plusredZ_S) --------
218+ {hole0} : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
219+
220+In this case, the goal is a function type, using ``k`` (the argument
221+accessible by pattern matching) and ``ih`` — the local variable
222+containing the result of the recursive call. We can introduce these as
223+premisses using the ``intro`` tactic twice (or ``intros``, which
224+introduces all arguments as premisses). This gives:
225+
226+.. code-block:: idris
227+
228+ k : Nat
229+ ih : k = plus k Z
230+ ---------------------------------- (plusredZ_S) --------
231+ {hole2} : S k = plus (S k) Z
232+
233+Since plus is defined by recursion on its first argument, the term
234+``plus (S k) Z`` in the goal can be simplified, so we use ``compute``.
235+
236+.. code-block:: idris
237+
238+ k : Nat
239+ ih : k = plus k Z
240+ ---------------------------------- (plusredZ_S) --------
241+ {hole2} : S k = S (plus k Z)
242+
243+We know, from the type of ``ih``, that ``k = plus k Z``, so we would
244+like to use this knowledge to replace ``plus k Z`` in the goal with
245+``k``. We can achieve this with the ``rewrite`` tactic:
246+
247+.. code-block:: idris
248+
249+ -plusredZ_S> rewrite ih
250+
251+ k : Nat
252+ ih : k = plus k Z
253+ ---------------------------------- (plusredZ_S) --------
254+ {hole3} : S k = S k
255+
256+ -plusredZ_S>
257+
258+The ``rewrite`` tactic takes an equality proof as an argument, and tries
259+to rewrite the goal using that proof. Here, it results in an equality
260+which is trivially provable:
261+
262+.. code-block:: idris
263+
264+ -plusredZ_S> trivial
265+ plusredZ_S: no more goals
266+ -plusredZ_S> qed
267+ plusredZ_S = proof {
268+ intros;
269+ rewrite ih;
270+ trivial;
271+ }
272+
273+Again, we can add this proof to the end of our source file using the
274+``:addproof`` command at the interactive prompt.
275+
276+.. _sect-totality:
277+
278+Totality Checking
279+-----------------
280+
281+If we really want to trust our proofs, it is important that they are
282+defined by *total* functions — that is, a function which is defined for
283+all possible inputs and is guaranteed to terminate. Otherwise we could
284+construct an element of the empty type, from which we could prove
285+anything:
286+
287+.. code-block:: idris
288+
289+ -- making use of 'hd' being partially defined
290+ empty1 : Void
291+ empty1 = hd [] where
292+ hd : List a -> a
293+ hd (x :: xs) = x
294+
295+ -- not terminating
296+ empty2 : Void
297+ empty2 = empty2
298+
299+Internally, checks every definition for totality, and we can check at
300+the prompt with the ``:total`` command. We see that neither of the above
301+definitions is total:
302+
303+::
304+
305+ *theorems> :total empty1
306+ possibly not total due to: empty1#hd
307+ not total as there are missing cases
308+ *theorems> :total empty2
309+ possibly not total due to recursive path empty2
310+
311+Note the use of the word “possibly” — a totality check can, of course,
312+never be certain due to the undecidability of the halting problem. The
313+check is, therefore, conservative. It is also possible (and indeed
314+advisable, in the case of proofs) to mark functions as total so that it
315+will be a compile time error for the totality check to fail:
316+
317+.. code-block:: idris
318+
319+ total empty2 : Void
320+ empty2 = empty2
321+
322+::
323+
324+ Type checking ./theorems.idr
325+ theorems.idr:25:empty2 is possibly not total due to recursive path empty2
326+
327+Reassuringly, our proof in Section :ref:`sect-empty` that the zero and
328+successor constructors are disjoint is total:
329+
330+.. code-block:: idris
331+
332+ *theorems> :total disjoint
333+ Total
334+
335+The totality check is, necessarily, conservative. To be recorded as
336+total, a function ``f`` must:
337+
338+- Cover all possible inputs
339+
340+- Be *well-founded* — i.e. by the time a sequence of (possibly
341+ mutually) recursive calls reaches ``f`` again, it must be possible to
342+ show that one of its arguments has decreased.
343+
344+- Not use any data types which are not *strictly positive*
345+
346+- Not call any non-total functions
347+
348+Directives and Compiler Flags for Totality
349+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
350+
351+By default, allows all definitions, whether total or not. However, it is
352+desirable for functions to be total as far as possible, as this provides
353+a guarantee that they provide a result for all possible inputs, in
354+finite time. It is possible to make total functions a requirement,
355+either:
356+
357+- By using the ``--total`` compiler flag.
358+
359+- By adding a ``%default total`` directive to a source file. All
360+ definitions after this will be required to be total, unless
361+ explicitly flagged as ``partial``.
362+
363+All functions *after* a ``%default total`` declaration are required to
364+be total. Correspondingly, after a ``%default partial`` declaration, the
365+requirement is relaxed.
366+
367+Finally, the compiler flag ``--warnpartial`` causes to print a warning
368+for any undeclared partial function.
369+
370+Totality checking issues
371+~~~~~~~~~~~~~~~~~~~~~~~~
372+
373+Please note that the totality checker is not perfect! Firstly, it is
374+necessarily conservative due to the undecidability of the halting
375+problem, so many programs which *are* total will not be detected as
376+such. Secondly, the current implementation has had limited effort put
377+into it so far, so there may still be cases where it believes a function
378+is total which is not. Do not rely on it for your proofs yet!
379+
380+Hints for totality
381+~~~~~~~~~~~~~~~~~~
382+
383+In cases where you believe a program is total, but does not agree, it is
384+possible to give hints to the checker to give more detail for a
385+termination argument. The checker works by ensuring that all chains of
386+recursive calls eventually lead to one of the arguments decreasing
387+towards a base case, but sometimes this is hard to spot. For example,
388+the following definition cannot be checked as ``total`` because the
389+checker cannot decide that ``filter (<= x) xs`` will always be smaller
390+than ``(x :: xs)``:
391+
392+.. code-block:: idris
393+
394+ qsort : Ord a => List a -> List a
395+ qsort [] = []
396+ qsort (x :: xs)
397+ = qsort (filter (< x) xs) ++
398+ (x :: qsort (filter (>= x) xs))
399+
400+The function ``assert_smaller``, defined in the Prelude, is intended to
401+address this problem:
402+
403+.. code-block:: idris
404+
405+ assert_smaller : a -> a -> a
406+ assert_smaller x y = y
407+
408+It simply evaluates to its second argument, but also asserts to the
409+totality checker that ``y`` is structurally smaller than ``x``. This can
410+be used to explain the reasoning for totality if the checker cannot work
411+it out itself. The above example can now be written as:
412+
413+.. code-block:: idris
414+
415+ total
416+ qsort : Ord a => List a -> List a
417+ qsort [] = []
418+ qsort (x :: xs)
419+ = qsort (assert_smaller (x :: xs) (filter (< x) xs)) ++
420+ (x :: qsort (assert_smaller (x :: xs) (filter (>= x) xs)))
421+
422+The expression ``assert_smaller (x :: xs) (filter (<= x) xs)`` asserts
423+that the result of the filter will always be smaller than the pattern
424+``(x :: xs)``.
425+
426+In more extreme cases, the function ``assert_total`` marks a
427+subexpression as always being total:
428+
429+.. code-block:: idris
430+
431+ assert_total : a -> a
432+ assert_total x = x
433+
434+In general, this function should be avoided, but it can be very useful
435+when reasoning about primitives or externally defined functions (for
436+example from a C library) where totality can be shown by an external
437+argument.
438+
439+
440+.. [1] Timothy G. Griffin. 1989. A formulae-as-type notion of
441+ control. In Proceedings of the 17th ACM SIGPLAN-SIGACT
442+ symposium on Principles of programming languages (POPL
443+ '90). ACM, New York, NY, USA, 47-58. DOI=10.1145/96709.96714
444+ http://doi.acm.org/10.1145/96709.96714
docs/tutorial/typesfuns.rstnew file+1048
@@ -0,0 +1,1048 @@
1+.. _sect-typefuns:
2+
3+===================
4+Types and Functions
5+===================
6+
7+Primitive Types
8+---------------
9+
10+``Idris`` defines several primitive types: ``Int``, ``Integer`` and
11+``Float`` for numeric operations, ``Char`` and ``String`` for text
12+manipulation, and ``Ptr`` which represents foreign pointers. There are
13+also several data types declared in the library, including ``Bool``,
14+with values ``True`` and ``False``. We can declare some constants with
15+these types. Enter the following into a file ``prims.idr`` and load it
16+into the ``Idris`` interactive environment by typing ``idris
17+prims.idr``:
18+
19+.. code-block:: idris
20+
21+ module prims
22+
23+ x : Int
24+ x = 42
25+
26+ foo : String
27+ foo = "Sausage machine"
28+
29+ bar : Char
30+ bar = 'Z'
31+
32+ quux : Bool
33+ quux = False
34+
35+An ``Idris`` file consists of an optional module declaration (here
36+``module prims``) followed by an optional list of imports (none here,
37+however ``Idris`` programs can consist of several modules, and the
38+definitions in each module each have their own namespace, as we will
39+discuss in Section :ref:`sect-namespaces`) and a collection of
40+declarations and definitions. The order of definitions is significant
41+— functions and data types must be defined before use. Each definition
42+must have a type declaration, for example see ``x : Int``, ``foo :
43+String``, from the above listing. Indentation is significant — a new
44+declaration begins at the same level of indentation as the preceding
45+declaration. Alternatively, declarations may be terminated with a
46+semicolon.
47+
48+A library module ``prelude`` is automatically imported by every
49+``Idris`` program, including facilities for IO, arithmetic, data
50+structures and various common functions. The prelude defines several
51+arithmetic and comparison operators, which we can use at the prompt.
52+Evaluating things at the prompt gives an answer, and the type of the
53+answer. For example:
54+
55+::
56+
57+ *prims> 6*6+6
58+ 42 : Int
59+ *prims> x == 6*6+6
60+ True : Bool
61+
62+All of the usual arithmetic and comparison operators are defined for
63+the primitive types. They are overloaded using type classes, as we
64+will discuss in Section :ref:`sect-classes` and can be extended to
65+work on user defined types. Boolean expressions can be tested with the
66+``if...then...else`` construct:
67+
68+::
69+
70+ *prims> if x == 6 * 6 + 6 then "The answer!" else "Not the answer"
71+ "The answer!" : String
72+
73+Data Types
74+----------
75+
76+Data types are declared in a similar way to Haskell data types, with a
77+similar syntax. Natural numbers and lists, for example, can be
78+declared as follows:
79+
80+.. code-block:: idris
81+
82+ data Nat = Z | S Nat -- Natural numbers
83+ -- (zero and successor)
84+ data List a = Nil | (::) a (List a) -- Polymorphic lists
85+
86+The above declarations are taken from the standard library. Unary
87+natural numbers can be either zero (``Z``), or the successor of
88+another natural number (``S k``). Lists can either be empty (``Nil``)
89+or a value added to the front of another list (``x :: xs``). In the
90+declaration for ``List``, we used an infix operator ``::``. New
91+operators such as this can be added using a fixity declaration, as
92+follows:
93+
94+::
95+
96+ infixr 10 ::
97+
98+Functions, data constructors and type constructors may all be given
99+infix operators as names. They may be used in prefix form if enclosed
100+in brackets, e.g. ``(::)``. Infix operators can use any of the
101+symbols:
102+
103+::
104+
105+ :+-*/=_.?|&><!@$%^~.
106+
107+Functions
108+---------
109+
110+Functions are implemented by pattern matching, again using a similar
111+syntax to Haskell. The main difference is that ``Idris`` requires type
112+declarations for all functions, using a single colon ``:`` (rather
113+than Haskell’s double colon ``::``). Some natural number arithmetic
114+functions can be defined as follows, again taken from the standard
115+library:
116+
117+.. code-block:: idris
118+
119+ -- Unary addition
120+ plus : Nat -> Nat -> Nat
121+ plus Z y = y
122+ plus (S k) y = S (plus k y)
123+
124+ -- Unary multiplication
125+ mult : Nat -> Nat -> Nat
126+ mult Z y = Z
127+ mult (S k) y = plus y (mult k y)
128+
129+The standard arithmetic operators ``+`` and ``*`` are also overloaded
130+for use by ``Nat``, and are implemented using the above functions.
131+Unlike Haskell, there is no restriction on whether types and function
132+names must begin with a capital letter or not. Function names
133+(``plus`` and ``mult`` above), data constructors (``Z``, ``S``,
134+``Nil`` and ``::``) and type constructors (``Nat`` and ``List``) are
135+all part of the same namespace. We can test these functions at the
136+``Idris`` prompt:
137+
138+::
139+
140+ Idris> plus (S (S Z)) (S (S Z))
141+ 4 : Nat
142+ Idris> mult (S (S (S Z))) (plus (S (S Z)) (S (S Z)))
143+ 12 : Nat
144+
145+.. note::
146+
147+ ``Idris`` automatically desugars the ``Nat`` representation into a
148+ more human readable format. The result of ``plus (S (S Z)) (S (S Z))``
149+ is actually ``(S (S (S (S Z))))`` which is the Integer 4. This can be
150+ checked at the ``Idris`` prompt:
151+
152+::
153+
154+ Idris> (S (S (S (S Z))))
155+ 4 : Nat
156+
157+Like arithmetic operations, integer literals are also overloaded using
158+type classes, meaning that we can also test the functions as follows:
159+
160+::
161+
162+ Idris> plus 2 2
163+ 4 : Nat
164+ Idris> mult 3 (plus 2 2)
165+ 12 : Nat
166+
167+You may wonder, by the way, why we have unary natural numbers when our
168+computers have perfectly good integer arithmetic built in. The reason
169+is primarily that unary numbers have a very convenient structure which
170+is easy to reason about, and easy to relate to other data structures
171+as we will see later. Nevertheless, we do not want this convenience to
172+be at the expense of efficiency. Fortunately, ``Idris`` knows about
173+the relationship between ``Nat`` (and similarly structured types) and
174+numbers. This means it can optimise the representation, and functions
175+such as ``plus`` and ``mult``.
176+
177+``where`` clauses
178+~~~~~~~~~~~~~~~~~
179+
180+Functions can also be defined *locally* using ``where`` clauses. For
181+example, to define a function which reverses a list, we can use an
182+auxiliary function which accumulates the new, reversed list, and which
183+does not need to be visible globally:
184+
185+.. code-block:: idris
186+
187+ reverse : List a -> List a
188+ reverse xs = revAcc [] xs where
189+ revAcc : List a -> List a -> List a
190+ revAcc acc [] = acc
191+ revAcc acc (x :: xs) = revAcc (x :: acc) xs
192+
193+Indentation is significant — functions in the ``where`` block must be
194+indented further than the outer function.
195+
196+**Scope:** Any names which are visible in the outer scope are also
197+visible in the ``where`` clause (unless they have been redefined, such
198+as ``xs`` here). A name which appears only in the type will be in scope
199+in the ``where`` clause if it is a *parameter* to one of the types,
200+i.e. it is fixed across the entire structure.
201+
202+As well as functions, ``where`` blocks can include local data
203+declarations, such as the following where ``MyLT`` is not accessible
204+outside the definition of ``foo``:
205+
206+.. code-block:: idris
207+
208+ foo : Int -> Int
209+ foo x = case isLT of
210+ Yes => x*2
211+ No => x*4
212+ where
213+ data MyLT = Yes | No
214+
215+ isLT : MyLT
216+ isLT = if x < 20 then Yes else No
217+
218+In general, functions defined in a ``where`` clause need a type
219+declaration just like any top level function. However, the type
220+declaration for a function ``f`` *can* be omitted if:
221+
222+- ``f`` appears in the right hand side of the top level definition
223+
224+- The type of ``f`` can be completely determined from its first
225+ application
226+
227+So, for example, the following definitions are legal:
228+
229+.. code-block:: idris
230+
231+ even : Nat -> Bool
232+ even Z = True
233+ even (S k) = odd k where
234+ odd Z = False
235+ odd (S k) = even k
236+
237+ test : List Nat
238+ test = [c (S 1), c Z, d (S Z)]
239+ where c x = 42 + x
240+ d y = c (y + 1 + z y)
241+ where z w = y + w
242+
243+Dependent Types
244+---------------
245+
246+Vectors
247+~~~~~~~
248+
249+A standard example of a dependent type is the type of “lists with
250+length”, conventionally called vectors in the dependent type
251+literature. They are available as part of the ``Idris`` library, by
252+importing ``Data.Vect``, or we can declare them as follows:
253+
254+.. code-block:: idris
255+
256+ data Vect : Nat -> Type -> Type where
257+ Nil : Vect Z a
258+ (::) : a -> Vect k a -> Vect (S k) a
259+
260+Note that we have used the same constructor names as for ``List``.
261+Ad-hoc name overloading such as this is accepted by ``Idris``,
262+provided that the names are declared in different namespaces (in
263+practice, normally in different modules). Ambiguous constructor names
264+can normally be resolved from context.
265+
266+This declares a family of types, and so the form of the declaration is
267+rather different from the simple type declarations above. We
268+explicitly state the type of the type constructor ``Vect`` — it takes
269+a ``Nat`` and a type as an argument, where ``Type`` stands for the
270+type of types. We say that ``Vect`` is *indexed* over ``Nat`` and
271+*parameterised* by ``Type``. Each constructor targets a different part
272+of the family of types. ``Nil`` can only be used to construct vectors
273+with zero length, and ``::`` to construct vectors with non-zero
274+length. In the type of ``::``, we state explicitly that an element of
275+type ``a`` and a tail of type ``Vect k a`` (i.e., a vector of length
276+``k``) combine to make a vector of length ``S k``.
277+
278+We can define functions on dependent types such as ``Vect`` in the same
279+way as on simple types such as ``List`` and ``Nat`` above, by pattern
280+matching. The type of a function over ``Vect`` will describe what
281+happens to the lengths of the vectors involved. For example, ``++``,
282+defined as follows, appends two ``Vect``:
283+
284+.. code-block:: idris
285+
286+ (++) : Vect n a -> Vect m a -> Vect (n + m) a
287+ (++) Nil ys = ys
288+ (++) (x :: xs) ys = x :: xs ++ ys
289+
290+The type of ``(++)`` states that the resulting vector’s length will be
291+the sum of the input lengths. If we get the definition wrong in such a
292+way that this does not hold, ``Idris`` will not accept the definition.
293+For example:
294+
295+.. code-block:: idris
296+
297+ (++) : Vect n a -> Vect m a -> Vect (n + m) a
298+ (++) Nil ys = ys
299+ (++) (x :: xs) ys = x :: xs ++ xs -- BROKEN
300+
301+When run through the ``Idris`` type checker, this results in the
302+following:
303+
304+::
305+
306+ $ idris vbroken.idr --check
307+ vbroken.idr:9:23:When elaborating right hand side of Vect.++:
308+ When elaborating an application of constructor Vect.:::
309+ Can't unify
310+ Vect (k + k) a
311+ with
312+ Vect (plus k m) a
313+
314+ Specifically:
315+ Can't unify
316+ plus k k
317+ with
318+ plus k m
319+
320+This error message suggests that there is a length mismatch between
321+two vectors — we needed a vector of length ``k + m``, but provided a
322+vector of length ``k + k``.
323+
324+The Finite Sets
325+~~~~~~~~~~~~~~~
326+
327+Finite sets, as the name suggests, are sets with a finite number of
328+elements. They are available as part of the ``Idris`` library, by
329+importing ``Data.Fin``, or can be declared as follows:
330+
331+.. code-block:: idris
332+
333+ data Fin : Nat -> Type where
334+ FZ : Fin (S k)
335+ FS : Fin k -> Fin (S k)
336+
337+``FZ`` is the zeroth element of a finite set with ``S k`` elements;
338+``FS n`` is the ``n+1``\ th element of a finite set with ``S k``
339+elements. ``Fin`` is indexed by a ``Nat``, which represents the number
340+of elements in the set. Obviously we can’t construct an element of an
341+empty set, so neither constructor targets ``Fin Z``.
342+
343+A useful application of the ``Fin`` family is to represent bounded
344+natural numbers. Since the first ``n`` natural numbers form a finite
345+set of ``n`` elements, we can treat ``Fin n`` as the set of natural
346+numbers bounded by ``n``.
347+
348+For example, the following function which looks up an element in a
349+``Vect``, by a bounded index given as a ``Fin n``, is defined in the
350+prelude:
351+
352+.. code-block:: idris
353+
354+ index : Fin n -> Vect n a -> a
355+ index FZ (x :: xs) = x
356+ index (FS k) (x :: xs) = index k xs
357+
358+This function looks up a value at a given location in a vector. The
359+location is bounded by the length of the vector (``n`` in each case),
360+so there is no need for a run-time bounds check. The type checker
361+guarantees that the location is no larger than the length of the
362+vector.
363+
364+Note also that there is no case for ``Nil`` here. This is because it
365+is impossible. Since there is no element of ``Fin Z``, and the
366+location is a ``Fin n``, then ``n`` can not be ``Z``. As a result,
367+attempting to look up an element in an empty vector would give a
368+compile time type error, since it would force ``n`` to be ``Z``.
369+
370+Implicit Arguments
371+~~~~~~~~~~~~~~~~~~
372+
373+Let us take a closer look at the type of ``index``:
374+
375+.. code-block:: idris
376+
377+ index : Fin n -> Vect n a -> a
378+
379+It takes two arguments, an element of the finite set of ``n`` elements,
380+and a vector with ``n`` elements of type ``a``. But there are also two
381+names, ``n`` and ``a``, which are not declared explicitly. These are
382+*implicit* arguments to ``index``. We could also write the type of
383+``index`` as:
384+
385+.. code-block:: idris
386+
387+ index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a
388+
389+Implicit arguments, given in braces ``{}`` in the type declaration,
390+are not given in applications of ``index``; their values can be
391+inferred from the types of the ``Fin n`` and ``Vect n a``
392+arguments. Any name with a which appears as a parameter or index in a
393+type declaration, but which is otherwise free, will be automatically
394+bound as an implicit argument. Implicit arguments can still be given
395+explicitly in applications, using ``{a=value}`` and ``{n=value}``, for
396+example:
397+
398+.. code-block:: idris
399+
400+ index {a=Int} {n=2} FZ (2 :: 3 :: Nil)
401+
402+In fact, any argument, implicit or explicit, may be given a name. We
403+could have declared the type of ``index`` as:
404+
405+.. code-block:: idris
406+
407+ index : (i:Fin n) -> (xs:Vect n a) -> a
408+
409+It is a matter of taste whether you want to do this — sometimes it can
410+help document a function by making the purpose of an argument more
411+clear.
412+
413+“``using``” notation
414+~~~~~~~~~~~~~~~~~~~~
415+
416+Sometimes it is useful to provide types of implicit arguments,
417+particularly where there is a dependency ordering, or where the
418+implicit arguments themselves have dependencies. For example, we may
419+wish to state the types of the implicit arguments in the following
420+definition, which defines a predicate on vectors:
421+
422+.. code-block:: idris
423+
424+ data Elem : a -> Vect n a -> Type where
425+ Here : {x:a} -> {xs:Vect n a} -> Elem x (x :: xs)
426+ There : {x,y:a} -> {xs:Vect n a} -> Elem x xs -> Elem x (y :: xs)
427+
428+An instance of ``Elem x xs`` states that ``x`` is an element of
429+``xs``. We can construct such a predicate if the required element is
430+``Here``, at the head of the vector, or ``There``, in the tail of the
431+vector. For example:
432+
433+.. code-block:: idris
434+
435+ testVec : Vect 4 Int
436+ testVec = 3 :: 4 :: 5 :: 6 :: Nil
437+
438+ inVect : Elem 5 testVec
439+ inVect = There (There Here)
440+
441+If the same implicit arguments are being used a lot, it can make a
442+definition difficult to read. To avoid this problem, a ``using`` block
443+gives the types and ordering of any implicit arguments which can
444+appear within the block:
445+
446+.. code-block:: idris
447+
448+ using (x:a, y:a, xs:Vect n a)
449+ data Elem : a -> Vect n a -> Type where
450+ Here : Elem x (x :: xs)
451+ There : Elem x xs -> Elem x (y :: xs)
452+
453+Note: Declaration Order and ``mutual`` blocks
454+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
455+
456+In general, functions and data types must be defined before use, since
457+dependent types allow functions to appear as part of types, and their
458+reduction behaviour to affect type checking. However, this restriction
459+can be relaxed by using a ``mutual`` block, which allows data types
460+and functions to be defined simultaneously:
461+
462+.. code-block:: idris
463+
464+ mutual
465+ even : Nat -> Bool
466+ even Z = True
467+ even (S k) = odd k
468+
469+ odd : Nat -> Bool
470+ odd Z = False
471+ odd (S k) = even k
472+
473+In a ``mutual`` block, first all of the type declarations are added,
474+then the function bodies. As a result, none of the function types can
475+depend on the reduction behaviour of any of the functions in the
476+block.
477+
478+I/O
479+---
480+
481+Computer programs are of little use if they do not interact with the
482+user or the system in some way. The difficulty in a pure language such
483+as ``Idris`` — that is, a language where expressions do not have
484+side-effects — is that I/O is inherently side-effecting. Therefore in
485+``Idris``, such interactions are encapsulated in the type ``IO``:
486+
487+.. code-block:: idris
488+
489+ data IO a -- IO operation returning a value of type a
490+
491+We’ll leave the definition of ``IO`` abstract, but effectively it
492+describes what the I/O operations to be executed are, rather than how
493+to execute them. The resulting operations are executed externally, by
494+the run-time system. We’ve already seen one IO program:
495+
496+.. code-block:: idris
497+
498+ main : IO ()
499+ main = putStrLn "Hello world"
500+
501+The type of ``putStrLn`` explains that it takes a string, and returns
502+an element of the unit type ``()`` via an I/O action. There is a
503+variant ``putStr`` which outputs a string without a newline:
504+
505+.. code-block:: idris
506+
507+ putStrLn : String -> IO ()
508+ putStr : String -> IO ()
509+
510+We can also read strings from user input:
511+
512+.. code-block:: idris
513+
514+ getLine : IO String
515+
516+A number of other I/O operations are defined in the prelude, for
517+example for reading and writing files, including:
518+
519+.. code-block:: idris
520+
521+ data File -- abstract
522+ data Mode = Read | Write | ReadWrite
523+
524+ openFile : String -> Mode -> IO File
525+ closeFile : File -> IO ()
526+
527+ fread : File -> IO String
528+ fwrite : File -> String -> IO ()
529+ feof : File -> IO Bool
530+
531+ readFile : String -> IO String
532+
533+.. _sect-do:
534+
535+“``do``” notation
536+-----------------
537+
538+I/O programs will typically need to sequence actions, feeding the
539+output of one computation into the input of the next. ``IO`` is an
540+abstract type, however, so we can’t access the result of a computation
541+directly. Instead, we sequence operations with ``do`` notation:
542+
543+.. code-block:: idris
544+
545+ greet : IO ()
546+ greet = do putStr "What is your name? "
547+ name <- getLine
548+ putStrLn ("Hello " ++ name)
549+
550+The syntax ``x <- iovalue`` executes the I/O operation ``iovalue``, of
551+type ``IO a``, and puts the result, of type ``a`` into the variable
552+``x``. In this case, ``getLine`` returns an ``IO String``, so ``name``
553+has type ``String``. Indentation is significant — each statement in
554+the do block must begin in the same column. The ``return`` operation
555+allows us to inject a value directly into an IO operation:
556+
557+.. code-block:: idris
558+
559+ return : a -> IO a
560+
561+As we will see later, ``do`` notation is more general than this, and
562+can be overloaded.
563+
564+.. _sect-lazy:
565+
566+Laziness
567+--------
568+
569+Normally, arguments to functions are evaluated before the function
570+itself (that is, ``Idris`` uses *eager* evaluation). However, this is
571+not always the best approach. Consider the following function:
572+
573+.. code-block:: idris
574+
575+ boolCase : Bool -> a -> a -> a;
576+ boolCase True t e = t;
577+ boolCase False t e = e;
578+
579+This function uses one of the ``t`` or ``e`` arguments, but not both
580+(in fact, this is used to implement the ``if...then...else`` construct
581+as we will see later. We would prefer if *only* the argument which was
582+used was evaluated. To achieve this, ``Idris`` provides a ``Lazy``
583+data type, which allows evaluation to be suspended:
584+
585+.. code-block:: idris
586+
587+ data Lazy : Type -> Type where
588+ Delay : (val : a) -> Lazy a
589+
590+ Force : Lazy a -> a
591+
592+A value of type ``Lazy a`` is unevaluated until it is forced by
593+``Force``. The ``Idris`` type checker knows about the ``Lazy`` type,
594+and inserts conversions where necessary between ``Lazy a`` and ``a``,
595+and vice versa. We can therefore write ``boolCase`` as follows,
596+without any explicit use of ``Force`` or ``Delay``:
597+
598+.. code-block:: idris
599+
600+ boolCase : Bool -> Lazy a -> Lazy a -> a;
601+ boolCase True t e = t;
602+ boolCase False t e = e;
603+
604+Useful Data Types
605+-----------------
606+
607+``Idris`` includes a number of useful data types and library functions
608+(see the ``libs/`` directory in the distribution). This chapter
609+describes a few of these. The functions described here are imported
610+automatically by every ``Idris`` program, as part of ``Prelude.idr``.
611+
612+``List`` and ``Vect``
613+~~~~~~~~~~~~~~~~~~~~~
614+
615+We have already seen the ``List`` and ``Vect`` data types:
616+
617+.. code-block:: idris
618+
619+ data List a = Nil | (::) a (List a)
620+
621+ data Vect : Nat -> Type -> Type where
622+ Nil : Vect Z a
623+ (::) : a -> Vect k a -> Vect (S k) a
624+
625+Note that the constructor names are the same for each — constructor
626+names (in fact, names in general) can be overloaded, provided that
627+they are declared in different namespaces (see Section
628+:ref:`sect-namespaces`), and will typically be resolved according to
629+their type. As syntactic sugar, any type with the constructor names
630+``Nil`` and ``::`` can be written in list form. For example:
631+
632+- ``[]`` means ``Nil``
633+
634+- ``[1,2,3]`` means ``1 :: 2 :: 3 :: Nil``
635+
636+The library also defines a number of functions for manipulating these
637+types. ``map`` is overloaded both for ``List`` and ``Vect`` and
638+applies a function to every element of the list or vector.
639+
640+.. code-block:: idris
641+
642+ map : (a -> b) -> List a -> List b
643+ map f [] = []
644+ map f (x :: xs) = f x :: map f xs
645+
646+ map : (a -> b) -> Vect n a -> Vect n b
647+ map f [] = []
648+ map f (x :: xs) = f x :: map f xs
649+
650+For example, given the following vector of integers, and a function to
651+double an integer:
652+
653+.. code-block:: idris
654+
655+ intVec : Vect 5 Int
656+ intVec = [1, 2, 3, 4, 5]
657+
658+ double : Int -> Int
659+ double x = x * 2
660+
661+the function ``map`` can be used as follows to double every element in
662+the vector:
663+
664+::
665+
666+ *usefultypes> show (map double intVec)
667+ "[2, 4, 6, 8, 10]" : String
668+
669+You’ll find these examples in ``usefultypes.idr`` in the ``examples/``
670+directory. For more details of the functions available on ``List`` and
671+``Vect``, look in the library files:
672+
673+- ``libs/prelude/Prelude/List.idr``
674+
675+- ``libs/base/Data/List.idr``
676+
677+- ``libs/base/Data/Vect.idr``
678+
679+- ``libs/base/Data/VectType.idr``
680+
681+Functions include filtering, appending, reversing, and so on. Also
682+remember that ``Idris`` is still in development, so if you don’t see
683+the function you need, please feel free to add it and submit a patch!
684+
685+Aside: Anonymous functions and operator sections
686+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
687+
688+There are actually neater ways to write the above expression. One way
689+would be to use an anonymous function:
690+
691+::
692+
693+ *usefultypes> show (map (\x => x * 2) intVec)
694+ "[2, 4, 6, 8, 10]" : String
695+
696+The notation ``\x => val`` constructs an anonymous function which takes
697+one argument, ``x`` and returns the expression ``val``. Anonymous
698+functions may take several arguments, separated by commas,
699+e.g. ``\x, y, z => val``. Arguments may also be given explicit types,
700+e.g. ``\x : Int => x * 2``, and can pattern match,
701+e.g. ``\(x, y) => x + y``. We could also use an operator section:
702+
703+::
704+
705+ *usefultypes> show (map (* 2) intVec)
706+ "[2, 4, 6, 8, 10]" : String
707+
708+``(*2)`` is shorthand for a function which multiplies a number
709+by 2. It expands to ``\x => x * 2``. Similarly, ``(2*)`` would expand
710+to ``\x => 2 * x``.
711+
712+Maybe
713+~~~~~
714+
715+``Maybe`` describes an optional value. Either there is a value of the
716+given type, or there isn’t:
717+
718+.. code-block:: idris
719+
720+ data Maybe a = Just a | Nothing
721+
722+``Maybe`` is one way of giving a type to an operation that may
723+fail. For example, looking something up in a ``List`` (rather than a
724+vector) may result in an out of bounds error:
725+
726+.. code-block:: idris
727+
728+ list_lookup : Nat -> List a -> Maybe a
729+ list_lookup _ Nil = Nothing
730+ list_lookup Z (x :: xs) = Just x
731+ list_lookup (S k) (x :: xs) = list_lookup k xs
732+
733+The ``maybe`` function is used to process values of type ``Maybe``,
734+either by applying a function to the value, if there is one, or by
735+providing a default value:
736+
737+.. code-block:: idris
738+
739+ maybe : Lazy b -> (a -> b) -> Maybe a -> b
740+
741+Note that the type of the first argument is ``Lazy b`` rather than
742+simply ``b``. Since the default value might not be used, we mark it as
743+``Lazy`` in case it is a large expression where evaluating it then
744+discarding it would be wasteful.
745+
746+Tuples and Dependent Pairs
747+~~~~~~~~~~~~~~~~~~~~~~~~~~
748+
749+Values can be paired with the following built-in data type:
750+
751+.. code-block:: idris
752+
753+ data Pair a b = MkPair a b
754+
755+As syntactic sugar, we can write ``(a, b)`` which, according to
756+context, means either ``Pair a b`` or ``MkPair a b``. Tuples can
757+contain an arbitrary number of values, represented as nested pairs:
758+
759+.. code-block:: idris
760+
761+ fred : (String, Int)
762+ fred = ("Fred", 42)
763+
764+ jim : (String, Int, String)
765+ jim = ("Jim", 25, "Cambridge")
766+
767+Dependent Pairs
768+~~~~~~~~~~~~~~~
769+
770+Dependent pairs allow the type of the second element of a pair to depend
771+on the value of the first element. Traditionally, these are referred to
772+as “sigma types”:
773+
774+.. code-block:: idris
775+
776+ data Sigma : (A : Type) -> (P : A -> Type) -> Type where
777+ MkSigma : {P : A -> Type} -> (a : A) -> P a -> Sigma A P
778+
779+Again, there is syntactic sugar for this. ``(a : A ** P)`` is the type
780+of a pair of A and P, where the name ``a`` can occur inside ``P``.
781+``( a ** p )`` constructs a value of this type. For example, we can
782+pair a number with a ``Vect`` of a particular length.
783+
784+.. code-block:: idris
785+
786+ vec : (n : Nat ** Vect n Int)
787+ vec = (2 ** [3, 4])
788+
789+If you like, you can write it out the long way, the two are precisely
790+equivalent.
791+
792+.. code-block:: idris
793+
794+ vec : Sigma Nat (\n => Vect n Int)
795+ vec = MkSigma 2 [3, 4]
796+
797+The type checker could of course infer the value of the first element
798+from the length of the vector. We can write an underscore ``_`` in
799+place of values which we expect the type checker to fill in, so the
800+above definition could also be written as:
801+
802+.. code-block:: idris
803+
804+ vec : (n : Nat ** Vect n Int)
805+ vec = (_ ** [3, 4])
806+
807+We might also prefer to omit the type of the first element of the
808+pair, since, again, it can be inferred:
809+
810+.. code-block:: idris
811+
812+ vec : (n ** Vect n Int)
813+ vec = (_ ** [3, 4])
814+
815+One use for dependent pairs is to return values of dependent types
816+where the index is not necessarily known in advance. For example, if
817+we filter elements out of a ``Vect`` according to some predicate, we
818+will not know in advance what the length of the resulting vector will
819+be:
820+
821+.. code-block:: idris
822+
823+ filter : (a -> Bool) -> Vect n a -> (p ** Vect p a)
824+
825+If the ``Vect`` is empty, the result is easy:
826+
827+.. code-block:: idris
828+
829+ filter p Nil = (_ ** [])
830+
831+In the ``::`` case, we need to inspect the result of a recursive call
832+to ``filter`` to extract the length and the vector from the result. To
833+do this, we use ``with`` notation, which allows pattern matching on
834+intermediate values:
835+
836+.. code-block:: idris
837+
838+ filter p (x :: xs) with (filter p xs)
839+ | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' )
840+
841+We will see more on ``with`` notation later.
842+
843+.. _sect-more-expr:
844+
845+More Expressions
846+----------------
847+
848+``let`` bindings
849+~~~~~~~~~~~~~~~~
850+
851+Intermediate values can be calculated using ``let`` bindings:
852+
853+.. code-block:: idris
854+
855+ data Person = MkPerson String Int
856+
857+ showPerson : Person -> String
858+ showPerson p = let MkPerson name age = p in
859+ name ++ " is " ++ show age ++ " years old"
860+
861+ splitAt : Char -> String -> (String, String)
862+ splitAt c x = case break (== c) x of
863+ (x, y) => (x, strTail y)
864+
865+We can do simple pattern matching in ``let`` bindings too. For
866+example, we can extract fields from a record as follows, as well as by
867+pattern matching at the top level:
868+
869+.. code-block:: idris
870+
871+ data Person = MkPerson String Int
872+
873+ showPerson : Person -> String
874+ showPerson p = let MkPerson name age = p in
875+ name ++ " is " ++ show age ++ " years old"
876+
877+List comprehensions
878+~~~~~~~~~~~~~~~~~~~
879+
880+``Idris`` provides *comprehension* notation as a convenient shorthand
881+for building lists. The general form is:
882+
883+::
884+
885+ [ expression | qualifiers ]
886+
887+This generates the list of values produced by evaluating the
888+``expression``, according to the conditions given by the comma
889+separated ``qualifiers``. For example, we can build a list of
890+Pythagorean triples as follows:
891+
892+.. code-block:: idris
893+
894+ pythag : Int -> List (Int, Int, Int)
895+ pythag n = [ (x, y, z) | z <- [1..n], y <- [1..z], x <- [1..y],
896+ x*x + y*y == z*z ]
897+
898+The ``[a..b]`` notation is another shorthand which builds a list of
899+numbers between ``a`` and ``b``. Alternatively ``[a,b..c]`` builds a
900+list of numbers between ``a`` and ``c`` with the increment specified
901+by the difference between ``a`` and ``b``. This works for any numeric
902+type, using the ``count`` function from the prelude.
903+
904+``case`` expressions
905+~~~~~~~~~~~~~~~~~~~~
906+
907+Another way of inspecting intermediate values of *simple* types is to
908+use a ``case`` expression. The following function, for example, splits
909+a string into two at a given character:
910+
911+.. code-block:: idris
912+
913+ splitAt : Char -> String -> (String, String)
914+ splitAt c x = case break (== c) x of
915+ (x, y) => (x, strTail y)
916+
917+``break`` is a library function which breaks a string into a pair of
918+strings at the point where the given function returns true. We then
919+deconstruct the pair it returns, and remove the first character of the
920+second string.
921+
922+A ``case`` expression can match several cases, for example, to inspect
923+an intermediate value of type ``Maybe a``. Recall ``list_lookup``
924+which looks up an index in a list, returning ``Nothing`` if the index
925+is out of bounds. We can use this to write ``lookup_default``, which
926+looks up an index and returns a default value if the index is out of
927+bounds:
928+
929+.. code-block:: idris
930+
931+ lookup_default : Nat -> List a -> a -> a
932+ lookup_default i xs def = case list_lookup i xs of
933+ Nothing => def
934+ Just x => x
935+
936+If the index is in bounds, we get the value at that index, otherwise
937+we get a default value:
938+
939+::
940+
941+ *usefultypes> lookup_default 2 [3,4,5,6] (-1)
942+ 5 : Integer
943+ *usefultypes> lookup_default 4 [3,4,5,6] (-1)
944+ -1 : Integer
945+
946+**Restrictions:** The ``case`` construct is intended for simple
947+analysis of intermediate expressions to avoid the need to write
948+auxiliary functions, and is also used internally to implement pattern
949+matching ``let`` and lambda bindings. It will *only* work if:
950+
951+- Each branch *matches* a value of the same type, and *returns* a value
952+ of the same type.
953+
954+- The type of the result is “known”. i.e. the type of the expression
955+ can be determined *without* type checking the ``case``-expression
956+ itself.
957+
958+Dependent Records
959+-----------------
960+
961+*Records* are data types which collect several values (the record’s
962+*fields*) together. ``Idris`` provides syntax for defining records and
963+*automatically generating field access and update functions. For
964+*example, we can represent a person’s name and age in a record:
965+
966+.. code-block:: idris
967+
968+ record Person : Type where
969+ MkPerson : (name : String) ->
970+ (age : Int) -> Person
971+
972+ fred : Person
973+ fred = MkPerson "Fred" 30
974+
975+Record declarations are like ``data`` declarations, except that they
976+are introduced by the ``record`` keyword, and can only have one
977+constructor. The names of the binders in the constructor type
978+(``name`` and ``age``) here are the field names, which we can use to
979+access the field values:
980+
981+::
982+
983+ *record> name fred
984+ "Fred" : String
985+ *record> age fred
986+ 30 : Int
987+ *record> :t name
988+ name : Person -> String
989+
990+We can also use the field names to update a record (or, more
991+precisely, produce a new record with the given fields updated).
992+
993+.. code-block:: bash
994+
995+ *record> record { name = "Jim" } fred
996+ MkPerson "Jim" 30 : Person
997+ *record> record { name = "Jim", age = 20 } fred
998+ MkPerson "Jim" 20 : Person
999+
1000+The syntax ``record { field = val, ... }`` generates a function which
1001+updates the given fields in a record.
1002+
1003+Records, and fields within records, can have dependent types. Updates
1004+are allowed to change the type of a field, provided that the result is
1005+well-typed, and the result does not affect the type of the record as a
1006+whole. For example:
1007+
1008+.. code-block:: idris
1009+
1010+ record Class : Type where
1011+ ClassInfo : (students : Vect n Person) ->
1012+ (className : String) ->
1013+ Class
1014+
1015+It is safe to update the ``students`` field to a vector of a different
1016+length because it will not affect the type of the record:
1017+
1018+.. code-block:: idris
1019+
1020+ addStudent : Person -> Class -> Class
1021+ addStudent p c = record { students = p :: students c } c
1022+
1023+::
1024+
1025+ *record> addStudent fred (ClassInfo [] "CS")
1026+ ClassInfo (prelude.vect.:: (MkPerson "Fred" 30) (prelude.vect.Nil)) "CS"
1027+ : Class
1028+
1029+Nested record update
1030+~~~~~~~~~~~~~~~~~~~~
1031+
1032+``Idris`` also provides a convenient syntax for accessing and updating
1033+nested records. For example, if a field is accessible with the
1034+expression ``c (b (a x))``, it can be updated using the following
1035+syntax:
1036+
1037+.. code-block:: idris
1038+
1039+ record { a->b->c = val } x
1040+
1041+This returns a new record, with the field accessed by the path
1042+``a->b->c`` set to ``x``. The syntax is first class, i.e. ``record {
1043+a->b->c = val }`` itself has a function type. Symmetrically, the field
1044+can also be accessed with the following syntax:
1045+
1046+.. code-block:: idris
1047+
1048+ record { a->b->c } x
docs/tutorial/views.rstnew file+98
@@ -0,0 +1,98 @@
1+.. _sec-views:
2+
3+=============================
4+Views and the “``with``” rule
5+=============================
6+
7+Dependent pattern matching
8+--------------------------
9+
10+Since types can depend on values, the form of some arguments can be
11+determined by the value of others. For example, if we were to write
12+down the implicit length arguments to ``(++)``, we’d see that the form
13+of the length argument was determined by whether the vector was empty
14+or not:
15+
16+.. code-block:: idris
17+
18+ (++) : Vect n a -> Vect m a -> Vect (n + m) a
19+ (++) {n=Z} [] ys = ys
20+ (++) {n=S k} (x :: xs) ys = x :: xs ++ ys
21+
22+If ``n`` was a successor in the ``[]`` case, or zero in the ``::``
23+case, the definition would not be well typed.
24+
25+.. _sect-nattobin:
26+
27+The ``with`` rule — matching intermediate values
28+------------------------------------------------
29+
30+Very often, we need to match on the result of an intermediate
31+computation. ``Idris`` provides a construct for this, the ``with``
32+rule, inspired by views in ``Epigram`` [1]_, which takes account of
33+the fact that matching on a value in a dependently typed language can
34+affect what we know about the forms of other values. In its simplest
35+form, the ``with`` rule adds another argument to the function being
36+defined, e.g. we have already seen a vector filter function, defined
37+as follows:
38+
39+.. code-block:: idris
40+
41+ filter : (a -> Bool) -> Vect n a -> (p ** Vect p a)
42+ filter p [] = ( _ ** [] )
43+ filter p (x :: xs) with (filter p xs)
44+ | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' )
45+
46+Here, the ``with`` clause allows us to deconstruct the result of
47+``filter p xs``. Effectively, it adds this value as an extra argument,
48+which we place after the vertical bar.
49+
50+If the intermediate computation itself has a dependent type, then the
51+result can affect the forms of other arguments — we can learn the form
52+of one value by testing another. For example, a ``Nat`` is either even
53+or odd. If it’s even it will be the sum of two equal ``Nat``.
54+Otherwise, it is the sum of two equal ``Nat`` plus one:
55+
56+.. code-block:: idris
57+
58+ data Parity : Nat -> Type where
59+ Even : Parity (n + n)
60+ Odd : Parity (S (n + n))
61+
62+We say ``Parity`` is a *view* of ``Nat``. It has a *covering function*
63+which tests whether it is even or odd and constructs the predicate
64+accordingly.
65+
66+.. code-block:: idris
67+
68+ parity : (n:Nat) -> Parity n
69+
70+We’ll come back to the definition of ``parity`` shortly. We can use it
71+to write a function which converts a natural number to a list of
72+binary digits (least significant first) as follows, using the ``with``
73+rule:
74+
75+.. code-block:: idris
76+
77+ natToBin : Nat -> List Bool
78+ natToBin Z = Nil
79+ natToBin k with (parity k)
80+ natToBin (j + j) | Even = False :: natToBin j
81+ natToBin (S (j + j)) | Odd = True :: natToBin j
82+
83+The value of the result of ``parity k`` affects the form of ``k``,
84+because the result of ``parity k`` depends on ``k``. So, as well as
85+the patterns for the result of the intermediate computation (``Even``
86+and ``odd``) right of the ``\mid``, we also write how the results
87+affect the other patterns left of the :math:`\mid`. Note that there is
88+a function in the patterns (``+``) and repeated occurrences of
89+``j``—this is allowed because another argument has determined the form
90+of these patterns.
91+
92+We will return to this function in Section :ref:`sect-provisional` to
93+complete the definition of ``parity``.
94+
95+.. [1] Conor McBride and James McKinna. 2004. The view from the
96+ left. J. Funct. Program. 14, 1 (January 2004),
97+ 69-111. DOI=10.1017/S0956796803004829
98+ http://dx.doi.org/10.1017/S0956796803004829ñ
samples/ConsoleIO.idrnew file+15
@@ -0,0 +1,15 @@
1+module Main
2+
3+import Effects
4+import Effect.StdIO
5+import Effect.State
6+
7+hello : { [STATE Int, STDIO] } Eff ()
8+hello = do putStr "Name? "
9+ putStrLn ("Hello " ++ trim !getStr ++ "!")
10+ update (+1)
11+ putStrLn ("I've said hello to: " ++ show !get ++ " people")
12+ hello
13+
14+main : IO ()
15+main = run hello
samples/Exception.idrnew file+21
@@ -0,0 +1,21 @@
1+module Main
2+
3+import Effects
4+import Effect.Exception
5+import Effect.StdIO
6+import Control.IOExcept
7+
8+data MyErr = NotANumber | OutOfRange
9+
10+instance Show MyErr where
11+ show NotANumber = "Not a number"
12+ show OutOfRange = "Out of range"
13+
14+parseNumber : Int -> String -> { [EXCEPTION MyErr] } Eff Int
15+parseNumber num str
16+ = if all isDigit (unpack str)
17+ then let x = cast str in
18+ if (x >=0 && x <= num)
19+ then pure x
20+ else raise OutOfRange
21+ else raise NotANumber
samples/Makefile+2−2
@@ -2,7 +2,7 @@ check:
22 rm -f *.ibc
33 for x in *.idr ; do \
44 echo "Checking $$x"; \
5− idris --check $$x; \
5+ idris -p effects --check $$x; \
66 done
7−
7+
88.PHONY: check
samples/Random.idrnew file+37
@@ -0,0 +1,37 @@
1+module Main
2+
3+import Effects
4+import Effect.Random
5+import Effect.Exception
6+import Effect.StdIO
7+
8+data MyErr = NotANumber | OutOfRange
9+
10+parseNumber : Int -> String -> { [EXCEPTION MyErr] } Eff Int
11+parseNumber num str
12+ = if all isDigit (unpack str)
13+ then let x = cast str in
14+ if (x >=0 && x <= num)
15+ then pure x
16+ else raise OutOfRange
17+ else raise NotANumber
18+
19+guess : Int -> { [STDIO] } Eff ()
20+guess target
21+ = do putStr "Guess: "
22+ case run {m=Maybe} (parseNumber 100 (trim !getStr)) of
23+ Nothing => do putStrLn "Invalid input"
24+ guess target
25+ Just v => case compare v target of
26+ LT => do putStrLn "Too low"
27+ guess target
28+ EQ => putStrLn "You win!"
29+ GT => do putStrLn "Too high"
30+ guess target
31+
32+game : { [RND, STDIO] } Eff ()
33+game = do srand 123456789
34+ guess (fromInteger !(rndInt 0 100))
35+
36+main : IO ()
37+main = run game
samples/ReadInt.idrnew file+22
@@ -0,0 +1,22 @@
1+module ReadInt
2+
3+import Effects
4+import Effect.State
5+import Effect.StdIO
6+
7+readInt : { [STATE (Vect n Int), STDIO] ==>
8+ {ok} if ok then [STATE (Vect (S n) Int), STDIO]
9+ else [STATE (Vect n Int), STDIO] } Eff Bool
10+readInt = do let x = trim !getStr
11+ case all isDigit (unpack x) of
12+ False => pure False
13+ True => do updateM (\xs => cast x ::xs)
14+ pure True
15+
16+readN : (n : Nat) ->
17+ { [STATE (Vect m Int), STDIO] ==>
18+ [STATE (Vect (n + m) Int), STDIO] } Eff ()
19+readN Z = pure ()
20+readN {m} (S k) = case !readInt of
21+ True => rewrite plusSuccRightSucc k m in readN k
22+ False => readN (S k)
samples/Select.idrnew file+17
@@ -0,0 +1,17 @@
1+module Main
2+
3+import Effects
4+import Effect.Select
5+import Effect.Exception
6+
7+triple : Int -> { [SELECT, EXCEPTION String] } Eff (Int, Int, Int)
8+triple max = do z <- select [1..max]
9+ y <- select [1..z]
10+ x <- select [1..y]
11+ if (x * x + y * y == z * z)
12+ then pure (x, y, z)
13+ else raise "No triple"
14+
15+main : IO ()
16+main = do print $ the (Maybe _) $ run (triple 100)
17+ print $ the (List _) $ run (triple 100)
samples/TreeTag-noeff.idrnew file+21
@@ -0,0 +1,21 @@
1+
2+data BTree a = Leaf
3+ | Node (BTree a) a (BTree a)
4+
5+testTree : BTree String
6+testTree = Node (Node Leaf "Jim" Leaf)
7+ "Fred"
8+ (Node (Node Leaf "Alice" Leaf)
9+ "Sheila"
10+ (Node Leaf "Bob" Leaf))
11+
12+treeTagAux : (i : Int) -> BTree a -> (Int, BTree (Int, a))
13+treeTagAux i Leaf = (i, Leaf)
14+treeTagAux i (Node l x r)
15+ = let (i', l') = treeTagAux i l in
16+ let x' = (i', x) in
17+ let (i'', r') = treeTagAux (i' + 1) r in
18+ (i'', Node l' x' r')
19+
20+treeTag : (i : Int) -> BTree a -> BTree (Int, a)
21+treeTag i x = snd (treeTagAux i x)
samples/TreeTag.idrnew file+40
@@ -0,0 +1,40 @@
1+module Main
2+
3+import Effects
4+import Effect.State
5+
6+data BTree a = Leaf
7+ | Node (BTree a) a (BTree a)
8+
9+instance Show a => Show (BTree a) where
10+ show Leaf = "[]"
11+ show (Node l x r) = "[" ++ show l ++ " "
12+ ++ show x ++ " "
13+ ++ show r ++ "]"
14+
15+testTree : BTree String
16+testTree = Node (Node Leaf "Jim" Leaf)
17+ "Fred"
18+ (Node (Node Leaf "Alice" Leaf)
19+ "Sheila"
20+ (Node Leaf "Bob" Leaf))
21+
22+treeTagAux : BTree a -> { [STATE Int] } Eff (BTree (Int, a))
23+treeTagAux Leaf = return Leaf
24+treeTagAux (Node l x r)
25+ = do l' <- treeTagAux l
26+ i <- get
27+ put (i + 1)
28+ r' <- treeTagAux r
29+ return (Node l' (i, x) r')
30+
31+treeTag : (i : Int) -> BTree a -> BTree (Int, a)
32+treeTag i x = runPure (do put i
33+ treeTagAux x)
34+
35+treeTagIO : (i : Int) -> BTree a -> IO (BTree (Int, a))
36+treeTagIO i x = run (do put i
37+ treeTagAux x)
38+
39+main : IO ()
40+main = print (treeTag 1 testTree)
samples/TreeTagCount.idrnew file+29
@@ -0,0 +1,29 @@
1+import Effects
2+import Effect.State
3+import Effect.StdIO
4+
5+data BTree a = Leaf
6+ | Node (BTree a) a (BTree a)
7+
8+testTree : BTree String
9+testTree = Node (Node Leaf "Jim" Leaf)
10+ "Fred"
11+ (Node (Node Leaf "Alice" Leaf)
12+ "Sheila"
13+ (Node Leaf "Bob" Leaf))
14+
15+treeTagAux : BTree a -> { ['Tag ::: STATE Int,
16+ 'Leaves ::: STATE Int] } Eff (BTree (Int, a))
17+treeTagAux Leaf = do 'Leaves :- update (+1)
18+ pure Leaf
19+treeTagAux (Node l x r)
20+ = do l' <- treeTagAux l
21+ i <- 'Tag :- get
22+ 'Tag :- put (i + 1)
23+ r' <- treeTagAux r
24+ pure (Node l' (i, x) r')
25+
26+treeTag : (i : Int) -> BTree a -> (BTree (Int, a), Int)
27+treeTag i x = runPureInit ['Tag := i, 'Leaves := 0]
28+ (do x' <- treeTagAux x
29+ pure (x', !('Leaves :- get)))
samples/binary.idr+1−1
@@ -41,7 +41,7 @@ adc (numx # bx) (numy # by) carry
4141main : IO ()
4242main = do let n1 = zero # b1 # b0 # b1 # b0
4343 let n2 = zero # b1 # b1 # b1 # b0
44− printLn (adc n1 n2 b0)
44+ print (adc n1 n2 b0)
4545
4646
4747
samples/hworld.idrnew file+10
@@ -0,0 +1,10 @@
1+module Main
2+
3+import Effects
4+import Effect.StdIO
5+
6+hello : { [STDIO] } Eff ()
7+hello = putStrLn "Hello world!"
8+
9+main : IO ()
10+main = run hello
samples/vadd.idrnew file+41
@@ -0,0 +1,41 @@
1+module Main
2+
3+import Effects
4+import Effect.Exception
5+import Effect.StdIO
6+
7+parseNumber : String -> { [EXCEPTION String] } Eff Int
8+parseNumber str
9+ = if all (\x => isDigit x || x == '-') (unpack str)
10+ then pure (cast str)
11+ else raise "Not a number"
12+
13+vadd : Vect n Int -> Vect n Int -> Vect n Int
14+vadd [] [] = []
15+vadd (x :: xs) (y :: ys) = x + y :: vadd xs ys
16+
17+vadd_check : Vect n Int -> Vect m Int ->
18+ { [EXCEPTION String] } Eff (Vect m Int)
19+vadd_check {n} {m} xs ys with (decEq n m)
20+ vadd_check {n} {m=n} xs ys | (Yes Refl) = pure (vadd xs ys)
21+ vadd_check {n} {m} xs ys | (No _) = raise "Length mismatch"
22+
23+read_vec : { [STDIO] } Eff (p ** Vect p Int)
24+read_vec = do putStr "Number (-1 when done): "
25+ case run {m=Maybe} (parseNumber (trim !getStr)) of
26+ Nothing => do putStrLn "Input error"
27+ read_vec
28+ Just v => if (v /= -1)
29+ then do (_ ** xs) <- read_vec
30+ pure (_ ** v :: xs)
31+ else pure (_ ** [])
32+
33+do_vadd : { [STDIO, EXCEPTION String] } Eff ()
34+do_vadd = do putStrLn "Vector 1"
35+ (_ ** xs) <- read_vec
36+ putStrLn "Vector 2"
37+ (_ ** ys) <- read_vec
38+ putStrLn (show !(vadd_check xs ys))
39+
40+main : IO ()
41+main = run do_vadd