on master help sign in
Merge remote-tracking branch 'refs/remotes/upstream/master' into issue/1987
commit84d3629244b23edcacc075e284480b6246ee5376 authorDavid Raymond Christiansen <david@davidchristiansen.dk> dateFri 20 Mar 2015, 11:18 (12 years ago) parent742cf9c3d81858
145 files changed+9723−229
.travis.yml+2 CHANGELOG+2 CONTRIBUTING.md+11−9 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 idris.cabal+2 libs/base/Language/Reflection/Utils.idr+1 libs/prelude/Language/Reflection/Errors.idr+1 libs/prelude/Prelude/Applicative.idr−4 libs/prelude/Prelude/Functor.idr−2 libs/prelude/Prelude/Monad.idr−3 rts/idris_gc.c+3−14 rts/idris_heap.c+6−3 rts/idris_heap.h+1−1 rts/idris_rts.c+11−3 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 src/Idris/AbsSyntax.hs−6 src/Idris/AbsSyntaxTree.hs+24−21 src/Idris/CmdOptions.hs+30 src/Idris/Core/Binary.hs+6 src/Idris/Core/DeepSeq.hs+1 src/Idris/Core/Execute.hs+10−13 src/Idris/Core/TT.hs+27−10 src/Idris/Delaborate.hs+4 src/Idris/Elab/Clause.hs+9−9 src/Idris/Elab/Instance.hs+28−1 src/Idris/Elab/Transform.hs+2−2 src/Idris/Elab/Type.hs+3−3 src/Idris/Elab/Utils.hs+16−10 src/Idris/Elab/Value.hs+2−2 src/Idris/ElabTerm.hs+6−2 src/Idris/Prover.hs+1−1 src/Idris/REPL.hs+12−2 test/basic006/run+3−2 test/basic009/run+6−3 test/docs001/expected+1−2 test/docs001/run+1−1 test/docs002/run+1−1 test/error003/expected+2−1 test/error003/run+1−1 test/error004/expected+6−3 test/error004/run+1−1 test/error005/expected+2−1 test/error005/run+1−1 test/ffi002/run+1−1 test/literate001/run+2−2 test/proof002/expected+2−1 test/proof002/run+2−2 test/proof007/expected+2−1 test/proof007/run+1−1 test/quasiquote001/expected+2−2 test/quasiquote003/run+1−1 test/quasiquote004/expected+2−1 test/quasiquote004/run+1−1 test/reg003/run+2−2 test/reg006/expected+2−1 test/reg006/run+1−1 test/reg007/run+1−1 test/reg010/expected+2−1 test/reg010/run+1−1 test/reg018/expected+10−5 test/reg018/run+4−4 test/reg023/run+1−1 test/reg027/expected+2−1 test/reg027/run+2−2 test/reg028/expected+4−2 test/reg028/run+2−2 test/reg034/run+1−1 test/reg035/run+3−3 test/reg044/run+1−1 test/reg049/run+1−1 test/reg054/run+1−1 test/reg055/run+2−2 test/reg056/run+1−1 test/totality001/expected+6−3 test/totality001/run+3−3 test/totality002/expected+4−2 test/totality002/run+3−3 test/totality003/expected+2−1 test/totality003/run+2−2 test/totality004/expected+4−2 test/totality004/run+2−2 test/totality006/expected+4−2 test/totality006/run+3−3 test/totality007/expected+2−1 test/totality007/totality.ipkg+1−1 test/totality008/expected+2−1 test/totality008/run+1−1 test/tutorial006/expected+2−1 test/tutorial006/run+2−2 test/unique001/expected+2−1 test/unique001/run+6−6 test/unique002/run+2−2 test/unique003/run+1−1
.travis.yml+2
@@ -16,6 +16,7 @@ before_install:
1616 - sudo apt-get install hscolour
1717 # test dependency
1818 - sudo apt-get install -qq expect
19+ - sudo apt-get install -qq cppcheck
1920 - cabal install alex-3.1.3
2021install:
2122 - cabal install -f FFI --enable-tests --dependencies-only
@@ -30,6 +31,7 @@ script:
3031 - if [[ "$TESTS" != "doc" ]]; then cabal build; fi
3132 - if [[ "$TESTS" != "doc" ]]; then cabal copy; fi
3233 - if [[ "$TESTS" != "doc" ]]; then cabal register; fi
34+ - if [[ "$TESTS" == "test_c" ]]; then cppcheck -j 2 --error-exitcode=1 ./rts/idris_bitstring.c ./rts/idris_bitstring.h ./rts/idris_gc.h ./rts/idris_gc.c ./rts/idris_gmp.h ./rts/idris_gmp.c ./rts/idris_heap.h ./rts/idris_heap.c ./rts/idris_main.c ./rts/idris_net.h ./rts/idris_net.c ./rts/idris_opts.h ./rts/idris_opts.c ./rts/idris_rts.h ./rts/idris_rts.c ./rts/idris_stats.h ./rts/idris_stats.c ./rts/idris_stdfgn.h ./rts/idris_stdfgn.c ./rts/libtest.c ; fi
3335 - if [[ "$TESTS" == "test_llvm" ]]; then git clone --depth 1 https://github.com/idris-hackers/idris-llvm.git ; cd idris-llvm ; cabal install ; cd .. ; fi
3436 - make -j2 $TESTS
3537env:
CHANGELOG+2
@@ -43,6 +43,8 @@ New in 0.9.17:
4343* New package 'contrib' containing things that are less mature or less used
4444 than the contents of 'base'. 'contrib' is not available by default, so you
4545 may need to add '-p contrib' to your .ipkg file or Idris command line.
46+* Arguments to class instances are now checked for injectivity.
47+ Unification assumes this, so we need to check when instances are defined.
4648
4749New in 0.9.16:
4850--------------
CONTRIBUTING.md+11−9
@@ -9,7 +9,7 @@ Here are a few guidelines that we would like contributors to follow so that we c
991. Make sure you are familiar with [Git](http://git-scm.com/book).
10101. Make sure you have a [GitHub account](https://github.com/signup/free).
11111. Make sure you are familiar with: [Idris](http://eb.host.cs.st-andrews.ac.uk/writings/idris-tutorial.pdf).
12−1. Make sure you can install `Idris`:
12+1. Make sure you can install Idris:
1313 * [Mac OS X](https://github.com/idris-lang/Idris-dev/wiki/Idris-on-OS-X-using-Homebrew)
1414 * [Ubuntu](https://github.com/idris-lang/Idris-dev/wiki/Idris-on-Ubuntu)
1515 * [Debian](https://github.com/idris-lang/Idris-dev/wiki/Idris-on-Debian)
@@ -27,18 +27,20 @@ Please clean up any messes that you find, and don't leave behind new messes for
2727
2828## Contributing to the default libraries.
2929
30−`Idris` ships with a set of packages in `libs/` that is provided as a default library.
30+Idris ships with a set of packages in `libs/` that is provided as a default library.
3131These packages should not be seen as the *standard* as when working with dependent types we do not necessarily know how best to work with dependent types.
32−These packages offer functionality that can be built on top of when constructing `Idris` programs.
32+These packages offer functionality that can be built on top of when constructing Idris programs.
3333
3434One major point to make is that everything in prelude will be imported automatically, unless given
3535the `--noprelude` option.
36−A central idea within the `Idris` Community is that what counts as `Idris` is: **the compiler plus the Standard Prelude**.
37−Other libraries (base, effects, etc) are still part of the distribution, but not necessarily standard.
36+Likewise, the contents of base are available with no special options.
37+The other two packages that ship with Idris, contrib and effects, require a the use of the `-p` command-line argument to bring their contents into the include path.
38+New contributions should probably be sent to contrib first, so that they can get maintained with the Idris distribution.
39+If they turn out to be widely applicable and useful, they may later be moved into base.
3840
39−As `Idris` is still being developed we are open to suggestions and changes that make improvements to these default packages.
40−Major changes to the library (or `Idris` itself) should ideally be discussed first through the projects official channels of communication i.e. the mailing list, github wiki, or IRC, or as a [Dragon Egg](https://github.com/idris-lang/Idris-dev/wiki/Feature-proposals).
41−Developers then seeking to add content to `Idris`s prelude and default library, should do so through a PR where more discussion's and refinements can be made.
41+As Idris is still being developed we are open to suggestions and changes that make improvements to these default packages.
42+Major changes to the library (or Idris itself) should ideally be discussed first through the projects official channels of communication i.e. the mailing list, github wiki, or IRC, or as a [Dragon Egg](https://github.com/idris-lang/Idris-dev/wiki/Feature-proposals).
43+Developers then seeking to add content to Idris's prelude and default library, should do so through a PR where more discussion's and refinements can be made.
4244
4345We do not want you wasting your time nor duplicating somebody's work!
4446
@@ -140,7 +142,7 @@ To help increase the chance of your pull request being accepted:
140142
1411431. Run the tests.
1421441. Update the documentation, the surrounding one, examples elsewhere, guides, whatever is affected by your contribution
143−1. Use appropriate code formatting for both `Idris` and `Haskell`.
145+1. Use appropriate code formatting for both Idris and Haskell.
144146
145147## Additional Resources
146148
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 = "default"
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ñ
idris.cabal+2
@@ -111,6 +111,7 @@ Extra-source-files:
111111
112112 libs/contrib/contrib.ipkg
113113 libs/contrib/Makefile
114+ libs/contrib/Classes/*.idr
114115 libs/contrib/Control/*.idr
115116 libs/contrib/Control/Isomorphism/*.idr
116117 libs/contrib/Data/*.idr
@@ -815,6 +816,7 @@ Library
815816 , vector-binary-instances < 0.3
816817 , xml < 1.4
817818 , zlib < 0.6
819+ , safe
818820 Extensions: MultiParamTypeClasses
819821 , DeriveFoldable
820822 , DeriveTraversable
libs/base/Language/Reflection/Utils.idr+1
@@ -270,6 +270,7 @@ instance Show Err where
270270 show (NoTypeDecl n) = "NoTypeDecl " ++ show n
271271 show (NotInjective tm tm' x) = "NotInjective " ++ show tm ++ " " ++ show tm'
272272 show (CantResolve tm) = "CantResolve " ++ show tm
273+ show (InvalidTCArg n tm) = "InvalidTCName " ++ show n ++ " (" ++ show tm ++ ")"
273274 show (CantResolveAlts xs) = "CantResolveAlts " ++ show xs
274275 show (IncompleteTerm tm) = "IncompleteTerm " ++ show tm
275276 show (NoEliminator s tm) = "NoEliminator " ++ show s ++ " " ++ show tm
libs/prelude/Language/Reflection/Errors.idr+1
@@ -29,6 +29,7 @@ data Err = Msg String
2929 | NoTypeDecl TTName
3030 | NotInjective TT TT TT
3131 | CantResolve TT
32+ | InvalidTCArg TTName TT
3233 | CantResolveAlts (List TTName)
3334 | IncompleteTerm TT
3435 | NoEliminator String TT
libs/prelude/Prelude/Applicative.idr−4
@@ -15,10 +15,6 @@ class Functor f => Applicative (f : Type -> Type) where
1515 pure : a -> f a
1616 (<*>) : f (a -> b) -> f a -> f b
1717
18−instance Applicative id where
19− pure a = a
20− f <*> a = f a
21−
2218infixl 2 <*
2319(<*) : Applicative f => f a -> f b -> f a
2420a <* b = map const a <*> b
libs/prelude/Prelude/Functor.idr−2
@@ -18,5 +18,3 @@ infixl 4 <$>
1818(<$>) : Functor f => (m : a -> b) -> f a -> f b
1919m <$> x = map m x
2020
21−instance Functor id where
22− map f a = f a
libs/prelude/Prelude/Monad.idr−3
@@ -14,9 +14,6 @@ infixl 5 >>=
1414class Applicative m => Monad (m : Type -> Type) where
1515 (>>=) : m a -> (a -> m b) -> m b
1616
17−instance Monad id where
18− a >>= f = f a
19−
2017||| Also called `join` or mu
2118flatten : Monad m => m (m a) -> m a
2219flatten a = a >>= id
rts/idris_gc.c+3−14
@@ -112,19 +112,8 @@ void idris_gc(VM* vm) {
112112 if (vm->heap.old != NULL)
113113 free(vm->heap.old);
114114
115− char* newheap = malloc(vm->heap.size);
116− char* oldheap = vm->heap.heap;
117−
118− vm->heap.heap = newheap;
119−#ifdef FORCE_ALIGNMENT
120− if (((i_int)(vm->heap.heap)&1) == 1) {
121− vm->heap.next = newheap + 1;
122− } else
123−#endif
124− {
125− vm->heap.next = newheap;
126− }
127− vm->heap.end = newheap + vm->heap.size;
115+ /* Allocate swap heap. */
116+ alloc_heap(&vm->heap, vm->heap.size, vm->heap.growth, vm->heap.heap);
128117
129118 VAL* root;
130119
@@ -139,6 +128,7 @@ void idris_gc(VM* vm) {
139128 msg->msg = copy(vm, msg->msg);
140129 }
141130#endif
131+
142132 vm->ret = copy(vm, vm->ret);
143133 vm->reg1 = copy(vm, vm->reg1);
144134
@@ -150,7 +140,6 @@ void idris_gc(VM* vm) {
150140 if ((vm->heap.next - vm->heap.heap) > vm->heap.size >> 1) {
151141 vm->heap.size += vm->heap.growth;
152142 }
153− vm->heap.old = oldheap;
154143
155144 STATS_LEAVE_GC(vm->stats, vm->heap.size, vm->heap.next - vm->heap.heap)
156145 HEAP_CHECK(vm)
rts/idris_heap.c+6−3
@@ -5,7 +5,9 @@
55#include <stddef.h>
66#include <stdio.h>
77
8−void alloc_heap(Heap * h, size_t heap_size)
8+
9+/* Used for initializing the heap. */
10+void alloc_heap(Heap * h, size_t heap_size, size_t growth, char * old)
911{
1012 char * mem = malloc(heap_size);
1113 if (mem == NULL) {
@@ -27,9 +29,9 @@ void alloc_heap(Heap * h, size_t heap_size)
2729 h->end = h->heap + heap_size;
2830
2931 h->size = heap_size;
30− h->growth = heap_size;
32+ h->growth = growth;
3133
32− h->old = NULL;
34+ h->old = old;
3335}
3436
3537void free_heap(Heap * h) {
@@ -40,6 +42,7 @@ void free_heap(Heap * h) {
4042 }
4143}
4244
45+
4346// TODO: more testing
4447/******************** Heap testing ********************************************/
4548void heap_check_underflow(Heap * heap) {
rts/idris_heap.h+1−1
@@ -14,7 +14,7 @@ typedef struct {
1414} Heap;
1515
1616
17−void alloc_heap(Heap * heap, size_t heap_size);
17+void alloc_heap(Heap * heap, size_t heap_size, size_t growth, char * old);
1818void free_heap(Heap * heap);
1919
2020
rts/idris_rts.c+11−3
@@ -29,7 +29,7 @@ VM* init_vm(int stack_size, size_t heap_size,
2929 vm->valstack_base = valstack;
3030 vm->stack_max = valstack + stack_size;
3131
32− alloc_heap(&(vm->heap), heap_size);
32+ alloc_heap(&(vm->heap), heap_size, heap_size, NULL);
3333
3434 vm->ret = NULL;
3535 vm->reg1 = NULL;
@@ -621,8 +621,16 @@ VAL idris_readStr(VM* vm, FILE* h) {
621621 {
622622 /* Make the buffer bigger and read more of the line */
623623 line_buf_size += BUFSIZE;
624− line_buf = (char *) realloc (line_buf, line_buf_size);
625−
624+ { /* limit the scope of new_line_buf to where it's needed for errors*/
625+ char *new_line_buf = realloc (line_buf, line_buf_size);
626+ if (new_line_buf == NULL)
627+ {
628+ fprintf(stderr, "Fatal Error: couldn't allocate a larger line buffer.");
629+ exit(EXIT_FAILURE);
630+ } else {
631+ line_buf = new_line_buf;
632+ }
633+ }
626634 /* points to last byte again */
627635 line_ptr = line_buf + line_buf_size - 1;
628636 /* so we can see if fgets put a 0 there */
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
src/Idris/AbsSyntax.hs−6
@@ -606,12 +606,6 @@ setWidth :: ConsoleWidth -> Idris ()
606606setWidth w = do ist <- getIState
607607 put ist { idris_consolewidth = w }
608608
609−renderWidth :: Idris Int
610−renderWidth = do iw <- getWidth
611− case iw of
612− InfinitelyWide -> return 100000000
613− ColsWide n -> return (max n 1)
614− AutomaticWidth -> runIO getScreenWidth
615609
616610
617611
src/Idris/AbsSyntaxTree.hs+24−21
@@ -66,27 +66,27 @@ toplevel = EInfo [] emptyContext id Nothing Nothing (\_ _ _ -> fail "Not impleme
6666eInfoNames :: ElabInfo -> [Name]
6767eInfoNames info = map fst (params info) ++ M.keys (inblock info)
6868
69−data IOption = IOption { opt_logLevel :: Int,
70− opt_typecase :: Bool,
71− opt_typeintype :: Bool,
72− opt_coverage :: Bool,
73− opt_showimp :: Bool, -- ^^ show implicits
74− opt_errContext :: Bool,
75− opt_repl :: Bool,
76− opt_verbose :: Bool,
77− opt_nobanner :: Bool,
78− opt_quiet :: Bool,
79− opt_codegen :: Codegen,
80− opt_outputTy :: OutputType,
81− opt_ibcsubdir :: FilePath,
82− opt_importdirs :: [FilePath],
83− opt_triple :: String,
84− opt_cpu :: String,
85− opt_cmdline :: [Opt], -- remember whole command line
86− opt_origerr :: Bool,
87− opt_autoSolve :: Bool, -- ^ automatically apply "solve" tactic in prover
88− opt_autoImport :: [FilePath], -- ^ e.g. Builtins+Prelude
89− opt_optimise :: [Optimisation]
69+data IOption = IOption { opt_logLevel :: Int,
70+ opt_typecase :: Bool,
71+ opt_typeintype :: Bool,
72+ opt_coverage :: Bool,
73+ opt_showimp :: Bool, -- ^^ show implicits
74+ opt_errContext :: Bool,
75+ opt_repl :: Bool,
76+ opt_verbose :: Bool,
77+ opt_nobanner :: Bool,
78+ opt_quiet :: Bool,
79+ opt_codegen :: Codegen,
80+ opt_outputTy :: OutputType,
81+ opt_ibcsubdir :: FilePath,
82+ opt_importdirs :: [FilePath],
83+ opt_triple :: String,
84+ opt_cpu :: String,
85+ opt_cmdline :: [Opt], -- remember whole command line
86+ opt_origerr :: Bool,
87+ opt_autoSolve :: Bool, -- ^ automatically apply "solve" tactic in prover
88+ opt_autoImport :: [FilePath], -- ^ e.g. Builtins+Prelude
89+ opt_optimise :: [Optimisation]
9090 }
9191 deriving (Show, Eq)
9292
@@ -151,6 +151,8 @@ data OutputMode = RawOutput Handle -- ^ Print user output directly to the handle
151151data ConsoleWidth = InfinitelyWide -- ^ Have pretty-printer assume that lines should not be broken
152152 | ColsWide Int -- ^ Manually specified - must be positive
153153 | AutomaticWidth -- ^ Attempt to determine width, or 80 otherwise
154+ deriving (Show, Eq)
155+
154156
155157-- | The global state used in the Idris monad
156158data IState = IState {
@@ -467,6 +469,7 @@ data Opt = Filename String
467469 | ShowOrigErr
468470 | AutoWidth -- ^ Automatically adjust terminal width
469471 | AutoSolve -- ^ Automatically issue "solve" tactic in interactive prover
472+ | UseConsoleWidth ConsoleWidth
470473 deriving (Show, Eq)
471474
472475-- Parsed declarations
src/Idris/CmdOptions.hs+30
@@ -11,6 +11,12 @@ import Options.Applicative.Arrows
1111import Data.Char
1212import Data.Maybe
1313
14+import Text.ParserCombinators.ReadP hiding (many, option)
15+
16+import Safe (lastMay)
17+
18+
19+
1420import qualified Text.PrettyPrint.ANSI.Leijen as PP
1521
1622runArgParser :: IO [Opt]
@@ -67,6 +73,7 @@ parser = runA $ proc () -> do
6773 files <- asA (many $ argument (fmap Filename str) (metavar "FILES")) -< ()
6874 A parseVersion >>> A helper -< (flags ++ files)
6975
76+
7077parseFlags :: Parser [Opt]
7178parseFlags = many $
7279 flag' NoBanner (long "nobanner" <> help "Suppress the banner")
@@ -132,6 +139,10 @@ parseFlags = many $
132139 <|> (TargetCPU <$> strOption (long "cpu" <> metavar "CPU" <> help "Select target CPU e.g. corei7 or cortex-m3 (for LLVM codegen)"))
133140 <|> flag' (ColourREPL True) (long "colour" <> long "color" <> help "Force coloured output")
134141 <|> flag' (ColourREPL False) (long "nocolour" <> long "nocolor" <> help "Disable coloured output")
142+
143+ <|> (UseConsoleWidth <$> option (str >>= parseConsoleWidth) (long "consolewidth" <> metavar "WIDTH" <> help "Select console width: auto, infinite, nat"))
144+
145+
135146 where
136147 getExt s = case maybeRead s of
137148 Just ext -> ext
@@ -151,3 +162,22 @@ preProcOpts (x:xs) ys = preProcOpts xs (x:ys)
151162parseCodegen :: String -> Codegen
152163parseCodegen "bytecode" = Bytecode
153164parseCodegen cg = Via (map toLower cg)
165+
166+
167+
168+
169+parseConsoleWidth :: Monad m => String -> m ConsoleWidth
170+parseConsoleWidth "auto" = return AutomaticWidth
171+parseConsoleWidth "infinite" = return InfinitelyWide
172+parseConsoleWidth s =
173+ case lastMay (readP_to_S (integerReader) s) of
174+ Just (r, _) -> return $ ColsWide r
175+ _ -> fail $ "Cannot parse: " ++ s
176+
177+
178+
179+integerReader :: ReadP Int
180+integerReader = do
181+ digits <- many1 $ satisfy isDigit
182+ return $ read digits
183+
src/Idris/Core/Binary.hs+6
@@ -149,6 +149,9 @@ instance Binary a => Binary (Err' a) where
149149 put (NoEliminator s t) = do putWord8 37
150150 put s
151151 put t
152+ put (InvalidTCArg n t) = do putWord8 38
153+ put n
154+ put t
152155
153156 get = do i <- getWord8
154157 case i of
@@ -211,6 +214,9 @@ instance Binary a => Binary (Err' a) where
211214 37 -> do x1 <- get
212215 x2 <- get
213216 return (NoEliminator x1 x2)
217+ 38 -> do x1 <- get
218+ x2 <- get
219+ return (InvalidTCArg x1 x2)
214220 _ -> error "Corrupted binary data for Err'"
215221----- Generated by 'derive'
216222
src/Idris/Core/DeepSeq.hs+1
@@ -81,6 +81,7 @@ instance NFData Err where
8181 rnf (NotInjective x1 x2 x3)
8282 = rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` ()
8383 rnf (CantResolve x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
84+ rnf (InvalidTCArg x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
8485 rnf (CantResolveAlts x1) = rnf x1 `seq` ()
8586 rnf (IncompleteTerm x1) = rnf x1 `seq` ()
8687 rnf (NoEliminator x1 x2) = rnf x1 `seq` rnf x2 `seq` ()
src/Idris/Core/Execute.hs+10−13
@@ -1,4 +1,5 @@
11{-# LANGUAGE PatternGuards, ExistentialQuantification, CPP #-}
2+{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
23module Idris.Core.Execute (execute) where
34
45import Idris.AbsSyntax
@@ -111,7 +112,8 @@ toTT (EThunk ctxt env tm) = do env' <- mapM toBinder env
111112 return $ normalise ctxt env' tm
112113 where toBinder (n, v) = do v' <- toTT v
113114 return (n, Let Erased v')
114−toTT (EHandle _) = return Erased
115+toTT (EHandle _) = execFail $ Msg "Can't convert handles back to TT after execution."
116+toTT (EPtr ptr) = execFail $ Msg "Can't convert pointers back to TT after execution."
115117
116118unApplyV :: ExecVal -> (ExecVal, [ExecVal])
117119unApplyV tm = ua [] tm
@@ -387,8 +389,8 @@ execForeign env ctxt arity ty fn xs onfail
387389 Nothing -> fail $ "Could not call foreign function \"" ++ f ++
388390 "\" with args " ++ show (map snd argTs)
389391 Just r -> return (mkEApp r xs')
390− Nothing -> return onfail
391−
392+ _ -> return onfail
393+
392394
393395splitArg tm | (_, [_,_,l,r]) <- unApplyV tm -- pair, two implicits
394396 = Just (toFDesc l, r)
@@ -443,6 +445,9 @@ getOp fn [_, EHandle h]
443445 | fn == prf =
444446 Just $ do contents <- execIO $ hGetLine h
445447 return (EConstant (Str (contents ++ "\n")))
448+getOp fn [_, arg]
449+ | fn == prf =
450+ Just $ execFail (Msg "Can't use prim__readFile on a raw pointer in the executor.")
446451getOp n args = getPrim n primitives >>= flip applyPrim args
447452 where getPrim :: Name -> [Prim] -> Maybe ([ExecVal] -> Maybe ExecVal)
448453 getPrim n [] = Nothing
@@ -486,6 +491,7 @@ execCase' env ctxt amap (Case sh n alts) | Just tm <- lookup n amap =
486491 let amap' = newBindings ++ (filter (\(x,_) -> not (elem x (map fst newBindings))) amap) in
487492 execCase' env ctxt amap' newCase
488493 Nothing -> return Nothing
494+execCase' _ _ _ cse = fail $ "The impossible happened: tried to exec " ++ show cse
489495
490496chooseAlt :: ExecVal -> [CaseAlt] -> Maybe (SC, [(Name, ExecVal)])
491497chooseAlt tm (DefaultCase sc : alts) | ok tm = Just (sc, [])
@@ -505,15 +511,6 @@ chooseAlt tm (_:alts) = chooseAlt tm alts
505511chooseAlt _ [] = Nothing
506512
507513
508−
509−
510−idrisType :: FType -> ExecVal
511−idrisType FUnit = EP Ref unitTy EErased
512−idrisType ft = EConstant (idr ft)
513− where idr (FArith ty) = AType ty
514− idr FString = StrType
515− idr FPtr = PtrType
516−
517514data Foreign = FFun String [(FDesc, ExecVal)] FDesc deriving Show
518515
519516toFType :: FDesc -> FType
@@ -574,7 +571,7 @@ call (FFun name argTypes retType) args =
574571 call' (Fun _ h) args FPtr = EPtr <$> (execIO $ callFFI h (retPtr retVoid) (prepArgs args))
575572 call' (Fun _ h) args FUnit = do _ <- execIO $ callFFI h retVoid (prepArgs args)
576573 return $ EP Ref unitCon EErased
577−
574+ call' _ _ _ = fail "the impossible happened in call' in Execute.hs"
578575
579576 prepArgs = map prepArg
580577 prepArg (EConstant (I i)) = argCInt (fromIntegral i)
src/Idris/Core/TT.hs+27−10
@@ -157,6 +157,7 @@ data Err' t
157157 | NotInjective t t t
158158 | CantResolve Bool -- True if postponed, False if fatal
159159 t
160+ | InvalidTCArg Name t
160161 | CantResolveAlts [Name]
161162 | IncompleteTerm t
162163 | NoEliminator String t
@@ -1170,17 +1171,33 @@ unList tm = case unApply tm of
11701171forget :: TT Name -> Raw
11711172forget tm = forgetEnv [] tm
11721173
1174+safeForget :: TT Name -> Maybe Raw
1175+safeForget tm = safeForgetEnv [] tm
1176+
11731177forgetEnv :: [Name] -> TT Name -> Raw
1174−forgetEnv env (P _ n _) = Var n
1175−forgetEnv env (V i) = Var (env !! i)
1176−forgetEnv env (Bind n b sc) = let n' = uniqueName n env in
1177− RBind n' (fmap (forgetEnv env) b)
1178− (forgetEnv (n':env) sc)
1179−forgetEnv env (App f a) = RApp (forgetEnv env f) (forgetEnv env a)
1180−forgetEnv env (Constant c) = RConstant c
1181−forgetEnv env (TType i) = RType
1182−forgetEnv env (UType u) = RUType u
1183−forgetEnv env Erased = RConstant Forgot
1178+forgetEnv env tm = case safeForgetEnv env tm of
1179+ Just t' -> t'
1180+ Nothing -> error $ "Scope error in " ++ show tm
1181+
1182+
1183+safeForgetEnv :: [Name] -> TT Name -> Maybe Raw
1184+safeForgetEnv env (P _ n _) = Just $ Var n
1185+safeForgetEnv env (V i) | i < length env = Just $ Var (env !! i)
1186+ | otherwise = Nothing
1187+safeForgetEnv env (Bind n b sc)
1188+ = do let n' = uniqueName n env
1189+ b' <- safeForgetEnvB env b
1190+ sc' <- safeForgetEnv (n':env) sc
1191+ Just $ RBind n' b' sc'
1192+ where safeForgetEnvB env (Let t v) = liftM2 Let (safeForgetEnv env t)
1193+ (safeForgetEnv env v)
1194+ safeForgetEnvB env b = do ty' <- safeForgetEnv env (binderTy b)
1195+ Just $ fmap (\_ -> ty') b
1196+safeForgetEnv env (App f a) = liftM2 RApp (safeForgetEnv env f) (safeForgetEnv env a)
1197+safeForgetEnv env (Constant c) = Just $ RConstant c
1198+safeForgetEnv env (TType i) = Just RType
1199+safeForgetEnv env (UType u) = Just $ RUType u
1200+safeForgetEnv env Erased = Just $ RConstant Forgot
11841201
11851202-- | Introduce a 'Bind' into the given term for each element of the
11861203-- given list of (name, binder) pairs.
src/Idris/Delaborate.hs+4
@@ -290,6 +290,10 @@ pprintErr' i (NotInjective p x y) =
290290 text " when unifying" <+> annTm x (pprintTerm i (delab i x)) <+> text "and" <+>
291291 annTm y (pprintTerm i (delab i y))
292292pprintErr' i (CantResolve _ c) = text "Can't resolve type class" <+> pprintTerm i (delab i c)
293+pprintErr' i (InvalidTCArg n t)
294+ = annTm t (pprintTerm i (delab i t)) <+> text " cannot be a parameter of "
295+ <> annName n <$>
296+ text "(Type class arguments must be injective)"
293297pprintErr' i (CantResolveAlts as) = text "Can't disambiguate name:" <+>
294298 align (cat (punctuate (comma <> space) (map (fmap (fancifyAnnots i) . annName) as)))
295299pprintErr' i (NoTypeDecl n) = text "No type declaration for" <+> annName n
src/Idris/Elab/Clause.hs+9−9
@@ -603,7 +603,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
603603 -- If we're inferring metavariables in the type, don't recheck,
604604 -- because we're only doing this to try to work out those metavariables
605605 (clhs_c, clhsty) <- if not inf
606− then recheckC fc [] lhs_tm
606+ then recheckC fc id [] lhs_tm
607607 else return (lhs_tm, lhs_ty)
608608 let clhs = normalise ctxt [] clhs_c
609609 let borrowed = borrowedNames [] clhs
@@ -681,7 +681,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
681681 logLvl 4 $ "---> " ++ show rhs'
682682 when (not (null defer)) $ iLOG $ "DEFERRED " ++
683683 show (map (\ (n, (_,_,t)) -> (n, t)) defer)
684− def' <- checkDef fc defer
684+ def' <- checkDef fc (Elaborating "deferred type of ") defer
685685 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
686686 addDeferred def''
687687 mapM_ (\(n, _) -> addIBC (IBCDef n)) def''
@@ -700,7 +700,7 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
700700 logLvl 6 $ " ==> " ++ show (forget rhs')
701701
702702 (crhs, crhsty) <- if not inf
703− then recheckC_borrowing True borrowed fc [] rhs'
703+ then recheckC_borrowing True borrowed fc id [] rhs'
704704 else return (rhs', clhsty)
705705 logLvl 6 $ " ==> " ++ show crhsty ++ " against " ++ show clhsty
706706 ctxt <- getContext
@@ -828,7 +828,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
828828 let ret_ty = getRetTy (explicitNames (normalise ctxt [] lhs_ty))
829829 let static_names = getStaticNames i lhs_tm
830830 logLvl 5 (show lhs_tm ++ "\n" ++ show static_names)
831− (clhs, clhsty) <- recheckC fc [] lhs_tm
831+ (clhs, clhsty) <- recheckC fc id [] lhs_tm
832832 logLvl 5 ("Checked " ++ show clhs)
833833 let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
834834 let wval = addImplBound i (map fst bargs) wval_in
@@ -847,12 +847,12 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
847847 return (tt, d, is, ctxt', newDecls))
848848 setContext ctxt'
849849 processTacticDecls newDecls
850− def' <- checkDef fc defer
850+ def' <- checkDef fc iderr defer
851851 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
852852 addDeferred def''
853853 mapM_ (elabCaseBlock info opts) is
854854 logLvl 5 ("Checked wval " ++ show wval')
855− (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
855+ (cwval, cwvalty) <- recheckC fc id [] (getInferTerm wval')
856856 let cwvaltyN = explicitNames (normalise ctxt [] cwvalty)
857857 let cwvalN = explicitNames (normalise ctxt [] cwval)
858858 logLvl 3 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
@@ -907,7 +907,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
907907 addIBC (IBCImp wname)
908908 addIBC (IBCStatic wname)
909909
910− def' <- checkDef fc [(wname, (-1, Nothing, wtype))]
910+ def' <- checkDef fc iderr [(wname, (-1, Nothing, wtype))]
911911 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
912912 addDeferred def''
913913
@@ -943,12 +943,12 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
943943 setContext ctxt'
944944 processTacticDecls newDecls
945945
946− def' <- checkDef fc defer
946+ def' <- checkDef fc iderr defer
947947 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, False))) def'
948948 addDeferred def''
949949 mapM_ (elabCaseBlock info opts) is
950950 logLvl 5 ("Checked RHS " ++ show rhs')
951− (crhs, crhsty) <- recheckC fc [] rhs'
951+ (crhs, crhsty) <- recheckC fc id [] rhs'
952952 return $ (Right (clhs, crhs), lhs)
953953 where
954954 getImps (Bind n (Pi _ _ _) t) = pexp Placeholder : getImps t
src/Idris/Elab/Instance.hs+28−1
@@ -135,6 +135,8 @@ elabInstance info syn doc argDocs what fc cs n ps t expn ds = do
135135 [PClause fc iname lhs [] rhs wb]]
136136 iLOG (show idecls)
137137 mapM_ (rec_elabDecl info EAll info) idecls
138+ ist <- getIState
139+ checkInjectiveArgs fc n (class_determiners ci) (lookupTyExact iname (tt_ctxt ist))
138140 addIBC (IBCInstance intInst n iname)
139141
140142 where
@@ -175,7 +177,7 @@ elabInstance info syn doc argDocs what fc cs n ps t expn ds = do
175177 setContext ctxt'
176178 processTacticDecls newDecls
177179 ctxt <- getContext
178− (cty, _) <- recheckC fc [] tyT
180+ (cty, _) <- recheckC fc id [] tyT
179181 let nty = normalise ctxt [] cty
180182 return $ any (isJust . findOverlapping i (class_determiners ci) (delab i nty)) (class_instances ci)
181183
@@ -276,3 +278,28 @@ elabInstance info syn doc argDocs what fc cs n ps t expn ds = do
276278 clauseFor m iname ns (PClauses _ _ m' _)
277279 = decorate ns iname m == decorate ns iname m'
278280 clauseFor m iname ns _ = False
281+
282+checkInjectiveArgs :: FC -> Name -> [Int] -> Maybe Type -> Idris ()
283+checkInjectiveArgs fc n ds Nothing = return ()
284+checkInjectiveArgs fc n ds (Just ty)
285+ = do ist <- getIState
286+ let (_, args) = unApply (instantiateRetTy ty)
287+ ci 0 ist args
288+ where
289+ ci i ist (a : as) | i `elem` ds
290+ = if isInj ist a then ci (i + 1) ist as
291+ else tclift $ tfail (At fc (InvalidTCArg n a))
292+ ci i ist (a : as) = ci (i + 1) ist as
293+ ci i ist [] = return ()
294+
295+ isInj i (P Bound n _) = True
296+ isInj i (P _ n _) = isConName n (tt_ctxt i)
297+ isInj i (App f a) = isInj i f && isInj i a
298+ isInj i (V _) = True
299+ isInj i (Bind n b sc) = isInj i sc
300+ isInj _ _ = True
301+
302+ instantiateRetTy (Bind n (Pi _ _ _) sc)
303+ = substV (P Bound n Erased) (instantiateRetTy sc)
304+ instantiateRetTy t = t
305+
src/Idris/Elab/Transform.hs+2−2
@@ -63,7 +63,7 @@ elabTransform info fc safe lhs_in@(PApp _ (PRef _ tf) _) rhs_in
6363 let lhs_ty = getInferType lhs'
6464 let newargs = pvars i lhs_tm
6565
66− (clhs_tm_in, clhs_ty) <- recheckC fc [] lhs_tm
66+ (clhs_tm_in, clhs_ty) <- recheckC fc id [] lhs_tm
6767 let clhs_tm = renamepats pnames clhs_tm_in
6868 logLvl 3 ("Transform LHS " ++ show clhs_tm)
6969
@@ -80,7 +80,7 @@ elabTransform info fc safe lhs_in@(PApp _ (PRef _ tf) _) rhs_in
8080 setContext ctxt'
8181 processTacticDecls newDecls
8282
83− (crhs_tm_in, crhs_ty) <- recheckC fc [] rhs'
83+ (crhs_tm_in, crhs_ty) <- recheckC fc id [] rhs'
8484 let crhs_tm = renamepats pnames crhs_tm_in
8585 logLvl 3 ("Transform RHS " ++ show crhs_tm)
8686
src/Idris/Elab/Type.hs+3−3
@@ -75,7 +75,7 @@ buildType info syn fc opts n ty' = do
7575
7676 logLvl 3 $ show ty ++ "\nElaborated: " ++ show tyT'
7777
78− ds <- checkAddDef True False fc defer
78+ ds <- checkAddDef True False fc iderr defer
7979 -- if the type is not complete, note that we'll need to infer
8080 -- things later (for solving metavariables)
8181 when (not (null ds)) $ addTyInferred n
@@ -85,7 +85,7 @@ buildType info syn fc opts n ty' = do
8585 logLvl 5 $ "Rechecking"
8686 logLvl 6 $ show tyT
8787 logLvl 10 $ "Elaborated to " ++ showEnvDbg [] tyT
88− (cty, ckind) <- recheckC fc [] tyT
88+ (cty, ckind) <- recheckC fc id [] tyT
8989
9090 -- record the implicit and inaccessible arguments
9191 i <- getIState
@@ -154,7 +154,7 @@ elabType' norm info syn doc argDocs fc opts n ty' = {- let ty' = piBind (params
154154 -- Productivity checking now via checking for guarded 'Delay'
155155 let opts' = opts -- if corec then (Coinductive : opts) else opts
156156 let usety = if norm then nty' else nty
157− ds <- checkDef fc [(n, (-1, Nothing, usety))]
157+ ds <- checkDef fc iderr [(n, (-1, Nothing, usety))]
158158 addIBC (IBCDef n)
159159 let ds' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) ds
160160 addDeferred ds'
src/Idris/Elab/Utils.hs+16−10
@@ -24,30 +24,36 @@ import qualified Data.Map as Map
2424
2525recheckC = recheckC_borrowing False []
2626
27−recheckC_borrowing uniq_check bs fc env t
27+recheckC_borrowing uniq_check bs fc mkerr env t
2828 = do -- t' <- applyOpts (forget t) (doesn't work, or speed things up...)
2929 ctxt <- getContext
30− (tm, ty, cs) <- tclift $ case recheck_borrowing uniq_check bs ctxt env (forget t) t of
31− Error e -> tfail (At fc e)
30+ t' <- case safeForget t of
31+ Just ft -> return ft
32+ Nothing -> tclift $ tfail $ mkerr (At fc (IncompleteTerm t))
33+ (tm, ty, cs) <- tclift $ case recheck_borrowing uniq_check bs ctxt env t' t of
34+ Error e -> tfail (At fc (mkerr e))
3235 OK x -> return x
3336 logLvl 6 $ "CONSTRAINTS ADDED: " ++ show cs
3437 addConstraints fc cs
3538 return (tm, ty)
3639
37−checkDef :: FC -> [(Name, (Int, Maybe Name, Type))]
40+iderr :: Name -> Err -> Err
41+iderr _ e = e
42+
43+checkDef :: FC -> (Name -> Err -> Err) -> [(Name, (Int, Maybe Name, Type))]
3844 -> Idris [(Name, (Int, Maybe Name, Type))]
39−checkDef fc ns = checkAddDef False True fc ns
45+checkDef fc mkerr ns = checkAddDef False True fc mkerr ns
4046
41−checkAddDef :: Bool -> Bool -> FC
47+checkAddDef :: Bool -> Bool -> FC -> (Name -> Err -> Err)
4248 -> [(Name, (Int, Maybe Name, Type))]
4349 -> Idris [(Name, (Int, Maybe Name, Type))]
44−checkAddDef add toplvl fc [] = return []
45−checkAddDef add toplvl fc ((n, (i, top, t)) : ns)
50+checkAddDef add toplvl fc mkerr [] = return []
51+checkAddDef add toplvl fc mkerr ((n, (i, top, t)) : ns)
4652 = do ctxt <- getContext
47− (t', _) <- recheckC fc [] t
53+ (t', _) <- recheckC fc (mkerr n) [] t
4854 when add $ do addDeferred [(n, (i, top, t, toplvl))]
4955 addIBC (IBCDef n)
50− ns' <- checkAddDef add toplvl fc ns
56+ ns' <- checkAddDef add toplvl fc mkerr ns
5157 return ((n, (i, top, t')) : ns')
5258
5359-- | Get the list of (index, name) of inaccessible arguments from an elaborated
src/Idris/Elab/Value.hs+2−2
@@ -73,13 +73,13 @@ elabValBind info aspat norm tm_in
7373
7474 let vtm = orderPats (getInferTerm tm')
7575
76− def' <- checkDef (fileFC "(input)") defer
76+ def' <- checkDef (fileFC "(input)") iderr defer
7777 let def'' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) def'
7878 addDeferred def''
7979 mapM_ (elabCaseBlock info []) is
8080
8181 logLvl 3 ("Value: " ++ show vtm)
82− (vtm_in, vty) <- recheckC (fileFC "(input)") [] vtm
82+ (vtm_in, vty) <- recheckC (fileFC "(input)") id [] vtm
8383
8484 let vtm = if norm then normalise (tt_ctxt i) [] vtm_in
8585 else vtm_in
src/Idris/ElabTerm.hs+6−2
@@ -57,7 +57,7 @@ processTacticDecls info =
5757 updateIState $ \i -> i { idris_implicits =
5858 addDef n impls (idris_implicits i) }
5959 addIBC (IBCImp n)
60− ds <- checkDef fc [(n, (-1, Nothing, ty))]
60+ ds <- checkDef fc iderr [(n, (-1, Nothing, ty))]
6161 addIBC (IBCDef n)
6262 let ds' = map (\(n, (i, top, t)) -> (n, (i, top, t, True))) ds
6363 addDeferred ds'
@@ -1375,9 +1375,12 @@ findInstances :: IState -> Term -> [Name]
13751375findInstances ist t
13761376 | (P _ n _, _) <- unApply t
13771377 = case lookupCtxt n (idris_classes ist) of
1378− [CI _ _ _ _ _ ins _] -> ins
1378+ [CI _ _ _ _ _ ins _] -> filter accessible ins
13791379 _ -> []
13801380 | otherwise = []
1381+ where accessible n = case lookupDefAccExact n False (tt_ctxt ist) of
1382+ Just (_, Hidden) -> False
1383+ _ -> True
13811384
13821385-- Try again to solve auto implicits
13831386solveAuto :: IState -> Name -> Bool -> Name -> ElabD ()
@@ -2708,6 +2711,7 @@ reflectErr (NotInjective t1 t2 t3) =
27082711 , reflect t3
27092712 ]
27102713reflectErr (CantResolve _ t) = raw_apply (Var $ reflErrName "CantResolve") [reflect t]
2714+reflectErr (InvalidTCArg n t) = raw_apply (Var $ reflErrName "InvalidTCArg") [reflectName n, reflect t]
27112715reflectErr (CantResolveAlts ss) =
27122716 raw_apply (Var $ reflErrName "CantResolveAlts")
27132717 [rawList (Var $ reflm "TTName") (map reflectName ss)]
src/Idris/Prover.hs+1−1
@@ -78,7 +78,7 @@ prove opt ctxt lit n ty
7878 putIState (i { proof_list = (n, prf) : proofs })
7979 let tree = simpleCase False (STerm Erased) False CompileTime (fileFC "proof") [] [] [([], P Ref n ty, tm)]
8080 logLvl 3 (show tree)
81− (ptm, pty) <- recheckC (fileFC "proof") [] tm
81+ (ptm, pty) <- recheckC (fileFC "proof") id [] tm
8282 logLvl 5 ("Proof type: " ++ show pty ++ "\n" ++
8383 "Expected type:" ++ show ty)
8484 case converts ctxt [] ty pty of
src/Idris/REPL.hs+12−2
@@ -1518,7 +1518,8 @@ loadInputs inputs toline -- furthest line to read in input source files
15181518
15191519idrisMain :: [Opt] -> Idris ()
15201520idrisMain opts =
1521− do let inputs = opt getFile opts
1521+ do mapM_ setWidth (opt getConsoleWidth opts)
1522+ let inputs = opt getFile opts
15221523 let quiet = Quiet `elem` opts
15231524 let nobanner = NoBanner `elem` opts
15241525 let idesl = Idemode `elem` opts || IdemodeSocket `elem` opts
@@ -1533,6 +1534,7 @@ idrisMain opts =
15331534 let optimise = case opt getOptLevel opts of
15341535 [] -> 2
15351536 xs -> last xs
1537+
15361538 setOptLevel optimise
15371539 let outty = case opt getOutputTy opts of
15381540 [] -> if Interface `elem` opts then
@@ -1554,7 +1556,9 @@ idrisMain opts =
15541556 when (DefaultTotal `elem` opts) $ do i <- getIState
15551557 putIState (i { default_total = True })
15561558 setColourise $ not quiet && last (True : opt getColour opts)
1557− when (not runrepl) $ setWidth InfinitelyWide
1559+
1560+
1561+
15581562 mapM_ addLangExt (opt getLanguageExt opts)
15591563 setREPL runrepl
15601564 setQuiet (quiet || isJust script || not (null immediate))
@@ -1777,6 +1781,12 @@ getCodegen :: Opt -> Maybe Codegen
17771781getCodegen (UseCodegen x) = Just x
17781782getCodegen _ = Nothing
17791783
1784+
1785+getConsoleWidth :: Opt -> Maybe ConsoleWidth
1786+getConsoleWidth (UseConsoleWidth x) = Just x
1787+getConsoleWidth _ = Nothing
1788+
1789+
17801790getExecScript :: Opt -> Maybe String
17811791getExecScript (InterpretScript expr) = Just expr
17821792getExecScript _ = Nothing
test/basic006/run+3−2
@@ -1,5 +1,6 @@
11#!/usr/bin/env bash
2−idris $@ test020.idr -o test020
3−idris $@ test020a.idr --check --nocolor
2+
3+idris --consolewidth 80 $@ test020.idr -o test020
4+idris --consolewidth 80 $@ test020a.idr --check --nocolor
45./test020
56rm -f test020 *.ibc
test/basic009/run+6−3
@@ -1,5 +1,8 @@
11#!/usr/bin/env bash
2−idris $@ Main.idr --nocolour --check && echo MAIN-PASS
3−idris $@ Faulty.idr --nocolour --check && echo FAULTY-PASS
4−idris $@ Multiple.idr --nocolour --check && echo MULTIPLE-PASS
2+
3+idris --consolewidth 80 $@ Main.idr --nocolour --check && echo MAIN-PASS
4+idris --consolewidth 80 $@ Faulty.idr --nocolour --check && echo FAULTY-PASS
5+idris --consolewidth 80 $@ Multiple.idr --nocolour --check && echo MULTIPLE-PASS
6+
7+
58rm -f *.ibc B/*.ibc
test/docs001/expected+1−2
@@ -1,5 +1,5 @@
11Type checking ./docs001.idr
2−*docs001> Type class C
2+Type class C
33 class
44
55Parameters:
@@ -15,4 +15,3 @@ Instances:
1515 C (D a b)
1616 another instance of class
1717 a -- parameter type
18−*docs001> Bye bye
test/docs001/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris --nobanner --nocolor docs001.idr < input
2+idris --quiet --nocolor --consolewidth 80 docs001.idr < input
33rm *.ibc
test/docs002/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris --nobanner --nocolor docs002.idr < input
2+idris --consolewidth 80 --nobanner --nocolor docs002.idr < input
33rm *.ibc
test/error003/expected+2−1
@@ -1,2 +1,3 @@
1−ErrorReflection.idr:68:5:When elaborating right hand side of bad:
1+ErrorReflection.idr:68:5:
2+When elaborating right hand side of bad:
23DSL type error: (t(503) => t'(504)) doesn't match ()
test/error003/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ ErrorReflection.idr --nocolour --check
2+idris --consolewidth 80 $@ ErrorReflection.idr --nocolour --check
33rm -f *.ibc
test/error004/expected+6−3
@@ -1,6 +1,9 @@
1−FunErrTest.idr:35:10:When elaborating right hand side of badCadr1:
1+FunErrTest.idr:35:10:
2+When elaborating right hand side of badCadr1:
23When elaborating argument cons1 to function FunErrTest.cadr:
34 Could not prove that [] has at least two elements.
4−FunErrTest.idr:38:10:When elaborating right hand side of badCadr2:
5+FunErrTest.idr:38:10:
6+When elaborating right hand side of badCadr2:
57When elaborating argument cons2 to function FunErrTest.cadr:
6− Could not prove that tail [(fromInteger 1)] has at least two elements.
8+ Could not prove that tail [(fromInteger 1)] has at least two
9+ elements.
test/error004/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ FunErrTest.idr --nocolour --check
2+idris --consolewidth 80 $@ FunErrTest.idr --nocolour --check
33rm -f *.ibc
test/error005/expected+2−1
@@ -13,7 +13,8 @@ When elaborating argument prf to function Data.Fin.fromInteger:
1313error005.idr:23:24:When elaborating right hand side of b0rken:
1414When elaborating argument prf to function Data.Fin.fromInteger:
1515 When using n as a literal for a Fin 3
16− Could not show that n is less than 3 because n is a bound variable instead of a constant Integer
16+ Could not show that n is less than 3 because n is a bound
17+ variable instead of a constant Integer
1718error005.idr:28:1:When elaborating right hand side of x:
1819When elaborating argument prf to function Data.Fin.fromInteger:
1920 When using 5 as a literal for a Fin 4
test/error005/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ --check --nocolour error005.idr
2+idris --consolewidth 80 $@ --check --nocolour error005.idr
33rm -f *.ibc
test/ffi002/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris --quiet test023.idr -o test023
2+idris --consolewidth 80 --quiet test023.idr -o test023
33rm -f test023 *.ibc
test/literate001/run+2−2
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris $@ test003a.lidr --check
3−idris $@ test003.lidr -o test003
2+idris --consolewidth 80 $@ test003a.lidr --check
3+idris --consolewidth 80 $@ test003.lidr -o test003
44./test003
55rm -f test003 test003.ibc Lit.ibc
test/proof002/expected+2−1
@@ -1,4 +1,5 @@
1−Reflect.idr:208:38:When elaborating right hand side of testReflect1:
1+Reflect.idr:208:38:
2+When elaborating right hand side of testReflect1:
23When elaborating an application of function Reflect.getJust:
34 Can't unify
45 IsJust (Just x1) (Type of ItIsJust)
test/proof002/run+2−2
@@ -1,4 +1,4 @@
11#!/usr/bin/env bash
2−idris $@ test030.idr --check --nocolour
3−idris $@ test030a.idr --check --nocolour
2+idris --consolewidth 80 $@ test030.idr --check --nocolour
3+idris --consolewidth 80 $@ test030a.idr --check --nocolour
44rm -f *.ibc
test/proof007/expected+2−1
@@ -1,3 +1,4 @@
1−DefaultArgUnknownName.idr:9:6:When elaborating right hand side of test:
1+DefaultArgUnknownName.idr:9:6:
2+When elaborating right hand side of test:
23When elaborating argument arg to function DefaultArgUnknownName.funWithBadDefArg:
34 No such variable sadgjhsag
test/proof007/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris --check $@ DefaultArgUnknownName.idr
2+idris --consolewidth 80 --check $@ DefaultArgUnknownName.idr
33rm -f *.ibc
test/quasiquote001/expected+2−2
@@ -1,5 +1,5 @@
11(App (App (App (P (DCon 1 3) (NS (UN ::) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (Bind (MN 0 "_t") (Pi (V 0)) (Bind (MN 2 "_t") (Pi (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 2)))))) (P (TCon 8 0) (UN Unit) (TType (UVar -1)))) (P (DCon 0 0) (UN MkUnit) (P (TCon 0 0) (UN Unit) Erased))) (App (App (App (P (DCon 1 3) (NS (UN ::) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (Bind (MN 0 "_t") (Pi (V 0)) (Bind (MN 2 "_t") (Pi (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 2)))))) (P (TCon 8 0) (UN Unit) (TType (UVar -1)))) (P (DCon 0 0) (UN MkUnit) (P (TCon 0 0) (UN Unit) Erased))) (App (P (DCon 0 1) (NS (UN Nil) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 0)))) (P (TCon 8 0) (UN Unit) (TType (UVar -1))))))
22--------------
3−(App (App (App (P (DCon 1 3) (NS (UN ::) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (Bind (MN 0 "_t") (Pi (V 0)) (Bind (MN 2 "_t") (Pi (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 2)))))) (TType (UVar 48))) (TType (UVar 50))) (App (App (App (P (DCon 1 3) (NS (UN ::) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (Bind (MN 0 "_t") (Pi (V 0)) (Bind (MN 2 "_t") (Pi (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 2)))))) (TType (UVar 52))) (App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 42))) (TType (UVar 44))) (P (TCon 8 0) (NS (UN Nat) ["Nat", "Prelude"]) (TType (UVar -1)))) (P (TCon 8 0) (NS (UN Nat) ["Nat", "Prelude"]) (TType (UVar -1))))) (App (P (DCon 0 1) (NS (UN Nil) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 0)))) (TType (UVar 54)))))
3+(App (App (App (P (DCon 1 3) (NS (UN ::) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (Bind (MN 0 "_t") (Pi (V 0)) (Bind (MN 2 "_t") (Pi (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 2)))))) (TType (UVar 32))) (TType (UVar 34))) (App (App (App (P (DCon 1 3) (NS (UN ::) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (Bind (MN 0 "_t") (Pi (V 0)) (Bind (MN 2 "_t") (Pi (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 2)))))) (TType (UVar 36))) (App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 30))) (TType (UVar 32))) (P (TCon 8 0) (NS (UN Nat) ["Nat", "Prelude"]) (TType (UVar -1)))) (P (TCon 8 0) (NS (UN Nat) ["Nat", "Prelude"]) (TType (UVar -1))))) (App (P (DCon 0 1) (NS (UN Nil) ["List", "Prelude"]) (Bind (UN a) (Pi (TType (UVar -1))) (App (P (TCon 0 0) (NS (UN List) ["List", "Prelude"]) Erased) (V 0)))) (TType (UVar 38)))))
44--------------
5−(App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 42))) (TType (UVar 44))) (App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 42))) (TType (UVar 44))) (TType (UVar 48))) (TType (UVar 48)))) (App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 42))) (TType (UVar 44))) (TType (UVar 48))) (TType (UVar 48))))
5+(App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 30))) (TType (UVar 32))) (App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 30))) (TType (UVar 32))) (TType (UVar 32))) (TType (UVar 32)))) (App (App (App (App (P (DCon 0 4) (NS (UN MkPair) ["Builtins"]) (Bind (UN A) (Pi (TType (UVar -1))) (Bind (UN B) (Pi (TType (UVar -1))) (Bind (UN a) (Pi (V 1)) (Bind (UN b) (Pi (V 1)) (App (App (P (TCon 0 0) (NS (UN Pair) ["Builtins"]) Erased) (V 3)) (V 2))))))) (TType (UVar 30))) (TType (UVar 32))) (TType (UVar 32))) (TType (UVar 32))))
test/quasiquote003/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ --check NoInfer.idr
2+idris --consolewidth 80 $@ --check NoInfer.idr
33rm -f *.ibc
test/quasiquote004/expected+2−1
@@ -1,2 +1,3 @@
1−Quasiquote004.idr:50:25:When elaborating right hand side of Quasiquote004.getMeNat':
1+Quasiquote004.idr:50:25:
2+When elaborating right hand side of Quasiquote004.getMeNat':
23Not a Nat goal
test/quasiquote004/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ --check --nocolour Quasiquote004.idr
2+idris --consolewidth 80 $@ --check --nocolour Quasiquote004.idr
33rm -f *.ibc
test/reg003/run+2−2
@@ -1,4 +1,4 @@
11#!/usr/bin/env bash
2−idris --check reg003.idr
3−idris --check reg003a.idr
2+idris --consolewidth 80 --check reg003.idr
3+idris --consolewidth 80 --check reg003a.idr
44rm -f *.ibc
test/reg006/expected+2−1
@@ -1 +1,2 @@
1−reg006.idr:17:1:RBTree.lookup is possibly not total due to: RBTree.case block in lookup
1+reg006.idr:17:1:
2+RBTree.lookup is possibly not total due to: RBTree.case block in lookup
test/reg006/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ reg006.idr --check
2+idris --consolewidth 80 $@ reg006.idr --check
33rm -f *.ibc
test/reg007/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris --nocolour --check $@ reg007.lidr
2+idris --consolewidth 80 --nocolour --check $@ reg007.lidr
33rm -f *.ibc
test/reg010/expected+2−1
@@ -1,2 +1,3 @@
1−reg010.idr:5:15:When elaborating left hand side of with block in usubst.unsafeSubst:
1+reg010.idr:5:15:
2+When elaborating left hand side of with block in usubst.unsafeSubst:
23Can't match on with block in usubst.unsafeSubst warg a P x x px
test/reg010/run+1−1
@@ -1,2 +1,2 @@
11#!/usr/bin/env bash
2−idris $@ reg010.idr --check --nocolour
2+idris --consolewidth 80 $@ reg010.idr --check --nocolour
test/reg018/expected+10−5
@@ -1,5 +1,10 @@
1−reg018a.idr:16:1:conat.minusCoNat is possibly not total due to recursive path conat.minusCoNat
2−reg018a.idr:21:1:conat.loopForever is possibly not total due to: conat.minusCoNat
3−reg018b.idr:8:1:A.showB is possibly not total due to recursive path A.showB
4−reg018c.idr:21:1:CodataTest.inf is possibly not total due to: with block in CodataTest.inf
5−reg018d.idr:8:1:Main.pull is not total as there are missing cases
1+reg018a.idr:16:1:
2+conat.minusCoNat is possibly not total due to recursive path conat.minusCoNat
3+reg018a.idr:21:1:
4+conat.loopForever is possibly not total due to: conat.minusCoNat
5+reg018b.idr:8:1:
6+A.showB is possibly not total due to recursive path A.showB
7+reg018c.idr:21:1:
8+CodataTest.inf is possibly not total due to: with block in CodataTest.inf
9+reg018d.idr:8:1:
10+Main.pull is not total as there are missing cases
test/reg018/run+4−4
@@ -1,6 +1,6 @@
11#!/usr/bin/env bash
2−idris $@ reg018a.idr --check
3−idris $@ reg018b.idr --check
4−idris $@ reg018c.idr --check
5−idris $@ reg018d.idr --check
2+idris --consolewidth 80 $@ reg018a.idr --check
3+idris --consolewidth 80 $@ reg018b.idr --check
4+idris --consolewidth 80 $@ reg018c.idr --check
5+idris --consolewidth 80 $@ reg018d.idr --check
66rm *.ibc
test/reg023/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ reg023.idr --check
2+idris --consolewidth 80 $@ reg023.idr --check
33rm -f *.ibc
test/reg027/expected+2−1
@@ -1,3 +1,4 @@
11<<int fn>>
226
3−reg027a.idr:9:10:Overlapping instance: Show (Int -> a) already defined
3+reg027a.idr:9:10:
4+Overlapping instance: Show (Int -> a) already defined
test/reg027/run+2−2
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris $@ reg027.idr -o reg027
2+idris --consolewidth 80 $@ reg027.idr -o reg027
33./reg027
4−idris $@ reg027a.idr --check
4+idris --consolewidth 80 $@ reg027a.idr --check
55rm -f reg027 *.ibc
test/reg028/expected+4−2
@@ -1,2 +1,4 @@
1−reg028.idr:5:1:tbad.bad is possibly not total due to: with block in tbad.bad
2−reg028a.idr:11:1:tbad.qsort' is possibly not total due to: with block in tbad.qsort'
1+reg028.idr:5:1:
2+tbad.bad is possibly not total due to: with block in tbad.bad
3+reg028a.idr:11:1:
4+tbad.qsort' is possibly not total due to: with block in tbad.qsort'
test/reg028/run+2−2
@@ -1,4 +1,4 @@
11#!/usr/bin/env bash
2−idris $@ reg028.idr --check
3−idris $@ reg028a.idr --check
2+idris --consolewidth 80 $@ reg028.idr --check
3+idris --consolewidth 80 $@ reg028a.idr --check
44rm -f *.ibc
test/reg034/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris --check reg034.idr
2+idris --consolewidth 80 --check reg034.idr
33rm -f reg034 *.ibc
test/reg035/run+3−3
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris --check reg035.idr
3−idris --check reg035a.lidr
4−idris --check reg035b.idr
2+idris --consolewidth 80 --check reg035.idr
3+idris --consolewidth 80 --check reg035a.lidr
4+idris --consolewidth 80 --check reg035b.idr
55rm -f *.ibc
test/reg044/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris reg044.idr --check
2+idris --consolewidth 80 reg044.idr --check
33rm -f *.ibc
test/reg049/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris --nocolour --check $@ reg049.idr
2+idris --consolewidth 80 --nocolour --check $@ reg049.idr
33rm -f *.ibc
test/reg054/run+1−1
@@ -1,2 +1,2 @@
11#!/usr/bin/env bash
2−idris $@ reg054.idr --check
2+idris --consolewidth 80 $@ reg054.idr --check
test/reg055/run+2−2
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris $@ reg055.idr --check
3−idris $@ reg055a.idr --check
2+idris --consolewidth 80 $@ reg055.idr --check
3+idris --consolewidth 80 $@ reg055a.idr --check
44rm -f *.ibc
55
test/reg056/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ reg056.idr -o reg056
2+idris --consolewidth 80 $@ reg056.idr -o reg056
33rm -f *.ibc
test/totality001/expected+6−3
@@ -1,3 +1,6 @@
1−test010.idr:15:1:Main.foo is possibly not total due to: Main.MkBad
2−test010a.idr:9:1:main.bar is possibly not total due to: main.MkBad
3−test010b.idr:9:1:main.bar is possibly not total due to: main.MkBad
1+test010.idr:15:1:
2+Main.foo is possibly not total due to: Main.MkBad
3+test010a.idr:9:1:
4+main.bar is possibly not total due to: main.MkBad
5+test010b.idr:9:1:
6+main.bar is possibly not total due to: main.MkBad
test/totality001/run+3−3
@@ -1,6 +1,6 @@
11#!/usr/bin/env bash
2−idris $@ --check test010.idr
3−idris $@ --check test010a.idr
4−idris $@ --check test010b.idr
2+idris --consolewidth 80 $@ --check test010.idr
3+idris --consolewidth 80 $@ --check test010a.idr
4+idris --consolewidth 80 $@ --check test010b.idr
55
66rm -f *.ibc
test/totality002/expected+4−2
@@ -1,2 +1,4 @@
1−test017a.idr:7:1:scg.vtrans is possibly not total due to recursive path scg.vtrans --> scg.vtrans
2−test017b.idr:4:1:foo.foo is possibly not total due to recursive path foo.foo
1+test017a.idr:7:1:
2+scg.vtrans is possibly not total due to recursive path scg.vtrans --> scg.vtrans
3+test017b.idr:4:1:
4+foo.foo is possibly not total due to recursive path foo.foo
test/totality002/run+3−3
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris $@ --check test017.idr
3−idris $@ --check test017a.idr
4−idris $@ --check test017b.idr
2+idris --consolewidth 80 $@ --check test017.idr
3+idris --consolewidth 80 $@ --check test017a.idr
4+idris --consolewidth 80 $@ --check test017b.idr
55rm -f *.ibc
test/totality003/expected+2−1
@@ -1 +1,2 @@
1−totality003a.idr:5:1:smaller.qsort is possibly not total due to recursive path smaller.qsort --> smaller.qsort --> smaller.qsort
1+totality003a.idr:5:1:
2+smaller.qsort is possibly not total due to recursive path smaller.qsort --> smaller.qsort --> smaller.qsort
test/totality003/run+2−2
@@ -1,4 +1,4 @@
11#!/usr/bin/env bash
2−idris $@ totality003.idr --check
3−idris $@ totality003a.idr --check
2+idris --consolewidth 80 $@ totality003.idr --check
3+idris --consolewidth 80 $@ totality003a.idr --check
44rm -f *.ibc
test/totality004/expected+4−2
@@ -1,3 +1,5 @@
11[1, 2, 2, 4, 3, 6, 4, 8, 5, 10]
2−totality004a.idr:13:1:Main.process is possibly not total due to recursive path Main.process --> Main.process --> Main.process
3−totality004a.idr:24:1:Main.main is possibly not total due to: Main.process
2+totality004a.idr:13:1:
3+Main.process is possibly not total due to recursive path Main.process --> Main.process --> Main.process
4+totality004a.idr:24:1:
5+Main.main is possibly not total due to: Main.process
test/totality004/run+2−2
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris $@ totality004.idr -o totality004
2+idris --consolewidth 80 $@ totality004.idr -o totality004
33./totality004
4−idris $@ --check totality004a.idr
4+idris --consolewidth 80 $@ --check totality004a.idr
55rm -f totality004 *.ibc
test/totality006/expected+4−2
@@ -1,3 +1,5 @@
1−totality006.idr:8:1:Main.prf is not total as there are missing cases
1+totality006.idr:8:1:
2+Main.prf is not total as there are missing cases
23totality006a.idr:11:6:prf' (S _) (S _) Oh is a valid case
3−totality006b.idr:10:1:totality006b.blargh is not total as there are missing cases
4+totality006b.idr:10:1:
5+totality006b.blargh is not total as there are missing cases
test/totality006/run+3−3
@@ -1,5 +1,5 @@
11#!/usr/bin/env bash
2−idris $@ totality006.idr --check
3−idris $@ totality006a.idr --check
4−idris $@ totality006b.idr --check
2+idris --consolewidth 80 $@ totality006.idr --check
3+idris --consolewidth 80 $@ totality006a.idr --check
4+idris --consolewidth 80 $@ totality006b.idr --check
55rm -f *.ibc
test/totality007/expected+2−1
@@ -1,3 +1,4 @@
11Type checking ./Totality.idr
2−Totality.idr:4:1:Totality.foo is not total as there are missing cases
2+Totality.idr:4:1:
3+Totality.foo is not total as there are missing cases
34Totality.idr:4:1:Could not build: Totality.foo is not total as there are missing cases
test/totality007/totality.ipkg+1−1
@@ -2,6 +2,6 @@ package totality
22
33-- totality007
44-- Test that the package builder doesn't allow totality errors in a build
5−opts = ""
5+opts = "--consolewidth 80"
66sourcedir = src
77modules = Totality
test/totality008/expected+2−1
@@ -1 +1,2 @@
1−totality008.idr:7:1:Main.ElimT is possibly not total due to: Main.c2
1+totality008.idr:7:1:
2+Main.ElimT is possibly not total due to: Main.c2
test/totality008/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ totality008.idr --check
2+idris --consolewidth 80 $@ totality008.idr --check
33rm -f *.ibc
test/tutorial006/expected+2−1
@@ -10,7 +10,8 @@ When elaborating argument xs to constructor Data.VectType.Vect.::
1010 plus n n
1111 with
1212 plus n m
13−tutorial006b.idr:10:10:When elaborating right hand side of with block in Main.parity:
13+tutorial006b.idr:10:10:
14+When elaborating right hand side of with block in Main.parity:
1415Can't unify
1516 Parity (plus (S j) (S j)) (Type of even)
1617with
test/tutorial006/run+2−2
@@ -1,4 +1,4 @@
11#!/usr/bin/env bash
2−idris $@ tutorial006a.idr --check
3−idris $@ tutorial006b.idr --check
2+idris --consolewidth 80 $@ tutorial006a.idr --check
3+idris --consolewidth 80 $@ tutorial006b.idr --check
44rm -f *.ibc
test/unique001/expected+2−1
@@ -17,4 +17,5 @@ with
1717unique001b.idr:16:7:Borrowed name xs must not be used on RHS
1818unique001c.idr:46:6:Unique name f is used more than once
1919unique001d.idr:3:7:Borrowed name x must not be used on RHS
20−unique001e.idr:4:11:Constructor Main.:: has a UniqueType, but the data type does not
20+unique001e.idr:3:10:
21+Constructor Main.Nil has a UniqueType, but the data type does not
test/unique001/run+6−6
@@ -1,9 +1,9 @@
11#!/usr/bin/env bash
2−idris $@ unique001.idr -o unique001
2+idris --consolewidth 80 $@ unique001.idr -o unique001
33./unique001
4−idris $@ unique001a.idr --check
5−idris $@ unique001b.idr --check
6−idris $@ unique001c.idr --check
7−idris $@ unique001d.idr --check
8−idris $@ unique001e.idr --check
4+idris --consolewidth 80 $@ unique001a.idr --check
5+idris --consolewidth 80 $@ unique001b.idr --check
6+idris --consolewidth 80 $@ unique001c.idr --check
7+idris --consolewidth 80 $@ unique001d.idr --check
8+idris --consolewidth 80 $@ unique001e.idr --check
99rm -f unique001 *.ibc
test/unique002/run+2−2
@@ -1,4 +1,4 @@
11#!/usr/bin/env bash
2−idris $@ unique002.idr --check
3−idris $@ unique002a.idr --check
2+idris --consolewidth 80 $@ unique002.idr --check
3+idris --consolewidth 80 $@ unique002a.idr --check
44rm -f *.ibc
test/unique003/run+1−1
@@ -1,3 +1,3 @@
11#!/usr/bin/env bash
2−idris $@ unique003.idr --check
2+idris --consolewidth 80 $@ unique003.idr --check
33rm -f *.ibc