├── .gitignore ├── CONTRIBUTING.md ├── Makefile ├── README.md ├── body.tex ├── conf.ltx ├── content ├── classes.tex ├── conclusions.tex ├── interactive.tex ├── interp.tex ├── intro.tex ├── misc │ ├── args.tex │ ├── codegen.tex │ ├── cumulativity.tex │ ├── ffi.tex │ ├── literate.tex │ └── type-providers.tex ├── miscellany.tex ├── modules.tex ├── provisional.tex ├── starting.tex ├── syntax.tex ├── syntax │ ├── dsl.tex │ └── rules.tex ├── theorems.tex ├── typesfuns.tex └── views.tex ├── examples ├── Makefile ├── binary.idr ├── bmain.idr ├── btree.idr ├── btreemod.idr ├── classes.idr ├── foo.idr ├── hello.idr ├── idiom.idr ├── interp.idr ├── letbind.idr ├── prims.idr ├── theorems.idr ├── universe.idr ├── usefultypes.idr ├── vbroken.idr ├── views.idr ├── viewsbroken.idr └── wheres.idr ├── fpmacros.sty ├── idris-tutorial.print.tex ├── idris-tutorial.screen.tex ├── idrislang.sty ├── imports.sty ├── library.ltx └── literature.bib /.gitignore: -------------------------------------------------------------------------------- 1 | idris-tutorial.*.pdf 2 | *.ibc 3 | *.acn 4 | *.acr 5 | *.alg 6 | *.aux 7 | *.bbl 8 | *.blg 9 | *.dvi 10 | *.fdb_latexmk 11 | *.fls 12 | *.glg 13 | *.glo 14 | *.gls 15 | *.idx 16 | *.ilg 17 | *.ind 18 | *.ist 19 | *.lof 20 | *.log 21 | *.lot 22 | *.maf 23 | *.mtc 24 | *.mtc0 25 | *.nav 26 | *.nlo 27 | *.out 28 | *.pdfsync 29 | *.ps 30 | *.snm 31 | *.synctex.gz 32 | *.tdo 33 | *.toc 34 | *.vrb 35 | *.xdy 36 | *~ 37 | ._DS_Store 38 | auto/ 39 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to 'The Idris Tutorial' 2 | 3 | ## Rules 4 | 5 | * One sentence per line, it makes merging contributions easier. 6 | * Please aim to make commits self contained. Ideally one thing at a time. 7 | * GitHub pull requests only. It might sound harsh but in future we aim to look at leveraging travis to provide CI testing of the tutorial. 8 | * Campfire Rules, try and leave the files you work on in a better state than when you found them. 9 | * We do not store binary builds of the tutorial here. 10 | 11 | ## Grammar and Spelling 12 | 13 | * Before submitting try and run your contribution through: [Style-Check.rb](http://www.cs.umd.edu/~nspring/software/style-check-readme.html). 14 | Style-Check.rb is a simple tool to check for _bad phrases_, and nominal _bad LaTeX_. 15 | The output is given in compiler format. 16 | * Version of English used...this has yet to be decided upon. 17 | 18 | ## idrislang.sty 19 | 20 | `idrislang.sty` is used to type set `idris` code within the tutorials. 21 | To keep things `DRY` this style file has been *hard* linked with the original kept in `idris-dev`. 22 | Normally, this file should live in the your local texmf tree, but if we want auto-generation of PDFs then the style file needs to be distributed alongside... 23 | 24 | ## Building 25 | 26 | The tutorial is written in `LaTeX` and the build tool `latexmk` will be used to manage the compilation process. 27 | `latexmk` comes with the default texlive installation. 28 | A nominal `Makefile` is provided that abstracts over the use of `latexmk`. 29 | `Emacs` with `AucTeX-mode` is used during writing. 30 | The `auto` generated by `AucTeX` should be taken care of with the `.gitignore`. 31 | Ditto goes with those pesky `.DS_Store` files generated by Mac OS X. 32 | However, do not be surprised to see several `AucTeX` related code in `LaTeX` comments at the bottom of several files. 33 | 34 | Useful bash aliases for working with LaTeXmk instead of a Makefile are: 35 | 36 | alias latexBuild='latexmk -gg -pdf -pvc -bibtex' 37 | alias latexQBuild='latexmk -gg -pdf -bibtex' 38 | alias latexClean='latexmk -c' 39 | alias latexClobber='latexmk -C' 40 | 41 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TUTORIAL = idris-tutorial 2 | DATE = ${shell date +%F} 3 | TUT_PDF = ${DATE}-${TUTORIAL} 4 | 5 | all: tutorial clean 6 | 7 | tutorial: tutorial-print tutorial-screen 8 | 9 | 10 | tutorial-print: 11 | latexmk -gg -pdf -bibtex-cond ${TUTORIAL}.print.tex 12 | 13 | tutorial-screen: 14 | latexmk -gg -pdf -bibtex-cond ${TUTORIAL}.screen.tex 15 | 16 | 17 | version: tutorial 18 | mv ${TUTORIAL}.print.pdf ${TUT_PDF}.print.pdf 19 | mv ${TUTORIAL}.screen.pdf ${TUT_PDF}.screen.pdf 20 | 21 | clean: 22 | latexmk -c 23 | 24 | cthulhu: 25 | latexmk -C 26 | rm -rf ${TUT_PDF} 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # An OLD Tutorial for Idris. 2 | 3 | This tutorial has become deprecated in favour of a Sphinx based, readthedocs integrated, solution hosted on the main idris repository. You can find this repository online: 4 | 5 | http://www.github.com/idris-lang/Idris-dev 6 | 7 | This repository is left here for archival purposes. 8 | -------------------------------------------------------------------------------- /body.tex: -------------------------------------------------------------------------------- 1 | 2 | \input{conf.ltx} 3 | \input{library.ltx} 4 | 5 | \newcommand{\version}{\gitVtagn} 6 | 7 | \title{Programming in \Idris{}: A Tutorial} 8 | \author{The \Idris{} Community} 9 | \date{\origdate\today} 10 | 11 | \begin{document} 12 | 13 | \maketitle% 14 | \tableofcontents 15 | \newpage 16 | 17 | \input{./content/intro.tex} 18 | \input{./content/starting.tex} 19 | \input{./content/typesfuns.tex} 20 | \input{./content/classes.tex} 21 | \input{./content/modules.tex} 22 | \input{./content/interp.tex} 23 | \input{./content/views.tex} 24 | \input{./content/theorems.tex} 25 | \input{./content/provisional.tex} 26 | \input{./content/interactive.tex} 27 | \input{./content/syntax.tex} 28 | \input{./content/miscellany.tex} 29 | \input{./content/conclusions.tex} 30 | 31 | \newpage 32 | \bibliographystyle{abbrv} 33 | \bibliography{literature} 34 | 35 | \end{document} 36 | -------------------------------------------------------------------------------- /conf.ltx: -------------------------------------------------------------------------------- 1 | %% This file contains configurations of used packages 2 | 3 | \lstset{% 4 | style=default, 5 | showstringspaces=false, 6 | breaklines=true 7 | } 8 | 9 | % Configuration of hyperref (to not use colors): 10 | \hypersetup{ 11 | colorlinks, 12 | linkcolor=black, 13 | citecolor=black, 14 | filecolor=black, 15 | urlcolor=black 16 | } 17 | 18 | % Enumitem Config 19 | \newlist{inparaenum}{enumerate*}{1} 20 | \setlist[inparaenum,1]{label=(\alph*)} 21 | 22 | \newlist{inparadesc}{description*}{1} 23 | \setlist[inparadesc,1]{font=\bfseries} 24 | 25 | % Compact Lists 26 | \newlist{compactitem}{itemize}{3} 27 | \setlist[compactitem]{topsep=0pt,partopsep=0pt,itemsep=0pt,parsep=0pt} 28 | \setlist[compactitem,1]{label=\textbullet} 29 | \setlist[compactitem,2]{label=--} 30 | \setlist[compactitem,3]{label=*} 31 | 32 | \newlist{compactdesc}{description}{3} 33 | \setlist[compactdesc]{topsep=0pt,partopsep=0pt,itemsep=0pt,parsep=0pt} 34 | 35 | \newlist{compactenum}{enumerate}{3} 36 | \setlist[compactenum]{topsep=0pt,partopsep=0pt,itemsep=0pt,parsep=0pt} 37 | \setlist[compactenum,1]{label=\arabic*} 38 | \setlist[compactenum,2]{label=\alph*} 39 | \setlist[compactenum,3]{label=\roman*} 40 | -------------------------------------------------------------------------------- /content/classes.tex: -------------------------------------------------------------------------------- 1 | \section{Type Classes} 2 | \label{sec:classes} 3 | 4 | We often want to define functions which work across several different data types. 5 | For example, we would like arithmetic operators to work on \texttt{Int}, \texttt{Integer} and \texttt{Float} at the very least. 6 | We would like \texttt{==} to work on the majority of data types. 7 | We would like to be able to display different types in a uniform way. 8 | 9 | To achieve this, we use a feature which has proved to be effective in Haskell, namely \emph{type classes}. 10 | To define a type class, we provide a collection of overloaded operations which describe the interface for \emph{instances} of that class. 11 | A simple example is the \texttt{Show} type class, which is defined in the prelude and provides an interface for converting values to \texttt{String}: 12 | 13 | \begin{code} 14 | class Show a where 15 | show : a -> String 16 | \end{code} 17 | 18 | \noindent 19 | This generates a function of the following type (which we call a \emph{method} of the \texttt{Show} class): 20 | 21 | \begin{code} 22 | show : Show a => a -> String 23 | \end{code} 24 | 25 | \noindent 26 | We can read this as: ``under the constraint that \texttt{a} is an instance of \texttt{Show}, take an input \texttt{a} and return a \texttt{String}.'' 27 | An instance of a class is defined with an \texttt{instance} declaration, which provides implementations of the function for a specific type. 28 | For example, the \texttt{Show} instance for \texttt{Nat} could be defined as: 29 | 30 | \begin{code} 31 | instance Show Nat where 32 | show Z = "Z" 33 | show (S k) = "s" ++ show k 34 | \end{code} 35 | 36 | \begin{lstlisting}[style=stdout] 37 | Idris> show (S (S (S Z))) 38 | "sssZ" : String 39 | \end{lstlisting} 40 | 41 | \noindent 42 | Only one instance of a class can be given for a type --- instances may not overlap. 43 | To help with resolution, the arguments of an instance must be constructors 44 | (either data or type constructors), variables or constants (i.e. you cannot 45 | give an instance for a function). 46 | Instance declarations can themselves have constraints. 47 | For example, to define a \texttt{Show} instance for vectors, we need to know that there is a \texttt{Show} instance for the element type, because we are going to use it to convert each element to a \texttt{String}: 48 | 49 | \begin{code} 50 | instance Show a => Show (Vect n a) where 51 | show xs = "[" ++ show' xs ++ "]" where 52 | show' : Vect n a -> String 53 | show' Nil = "" 54 | show' (x :: Nil) = show x 55 | show' (x :: xs) = show x ++ ", " ++ show' xs 56 | \end{code} 57 | 58 | %\noindent 59 | %\textbf{Remark: } The type of the auxiliary function \texttt{show'} is 60 | %important. The type variables \texttt{a} and \texttt{n} which are part of the 61 | %instance declaration for \texttt{Show (Vect a n)} are fixed across the entire 62 | %instance declaration. As a result, we do not have to constrain \texttt{a} 63 | %again. Furthermore, it means that if we use \texttt{n} in the type, it refers 64 | %to the (fixed) length of the outermost list \texttt{xs}. Therefore, 65 | %we use a different name for the length \texttt{n'} in \texttt{show'}. 66 | 67 | \subsection{Default Definitions} 68 | 69 | The library defines an \texttt{Eq} class which provides an interface for comparing values for equality or inequality, with instances for all of the built-in types: 70 | 71 | \begin{code} 72 | class Eq a where 73 | (==) : a -> a -> Bool 74 | (/=) : a -> a -> Bool 75 | \end{code} 76 | 77 | \noindent 78 | To declare an instance of a type, we have to give definitions of all of the methods. 79 | For example, for an instance of \texttt{Eq} for \texttt{Nat}: 80 | 81 | \begin{code} 82 | instance Eq Nat where 83 | Z == Z = True 84 | (S x) == (S y) = x == y 85 | Z == (S y) = False 86 | (S x) == Z = False 87 | 88 | x /= y = not (x == y) 89 | \end{code} 90 | 91 | \noindent 92 | It is hard to imagine many cases where the \texttt{/=} method will be anything other than the negation of the result of applying the \texttt{==} method. 93 | It is therefore convenient to give a default definition for each method in the class declaration, in terms of the other method: 94 | 95 | \begin{code} 96 | class Eq a where 97 | (==) : a -> a -> Bool 98 | (/=) : a -> a -> Bool 99 | 100 | x /= y = not (x == y) 101 | x == y = not (x /= y) 102 | \end{code} 103 | 104 | \noindent 105 | A minimal complete definition of an \texttt{Eq} instance requires either \texttt{==} or \texttt{/=} to be defined, but does not require both. 106 | If a method definition is missing, and there is a default definition for it, then the default is used instead. 107 | 108 | \subsection{Extending Classes} 109 | 110 | Classes can also be extended. 111 | A logical next step from an equality relation \texttt{Eq} is to define an ordering relation \texttt{Ord}. 112 | We can define an \texttt{Ord} class which inherits methods from \texttt{Eq} as well as defining some of its own: 113 | 114 | \begin{code} 115 | data Ordering = LT | EQ | GT 116 | \end{code} 117 | 118 | \begin{code} 119 | class Eq a => Ord a where 120 | compare : a -> a -> Ordering 121 | 122 | (<) : a -> a -> Bool 123 | (>) : a -> a -> Bool 124 | (<=) : a -> a -> Bool 125 | (>=) : a -> a -> Bool 126 | max : a -> a -> a 127 | min : a -> a -> a 128 | \end{code} 129 | 130 | \noindent 131 | The \texttt{Ord} class allows us to compare two values and determine their ordering. 132 | Only the \texttt{compare} method is required; every other method has a default definition. 133 | Using this we can write functions such as \texttt{sort}, a function which sorts a list into increasing order, provided that the element type of the list is in the \texttt{Ord} class. 134 | We give the constraints on the type variables left of the fat arrow \texttt{=>}, and the function type to the right of the fat arrow: 135 | 136 | \begin{code} 137 | sort : Ord a => List a -> List a 138 | \end{code} 139 | 140 | \noindent 141 | Functions, classes and instances can have multiple constraints. 142 | Multiple constaints are written in brackets in a comma separated list, for example: 143 | 144 | \begin{code} 145 | sortAndShow : (Ord a, Show a) => List a -> String 146 | sortAndShow xs = show (sort xs) 147 | \end{code} 148 | 149 | \subsection{Functors and Applicatives} 150 | 151 | \label{sec:functor} 152 | 153 | So far, we have seen single parameter type classes, where the parameter is of 154 | type \texttt{Type}. In general, there can be any number (greater than 0) of 155 | parameters, and the parameters can have \emph{any} type. If the type of the 156 | parameter is not \texttt{Type}, we need to give an explicit type declaration. 157 | For example, the \texttt{Functor} class is defined in the library: 158 | 159 | \begin{code} 160 | class Functor (f : Type -> Type) where 161 | map : (m : a -> b) -> f a -> f b 162 | \end{code} 163 | 164 | \noindent 165 | A functor allows a function to be applied across a structure, for example 166 | to apply a function to every element in a \texttt{List}: 167 | 168 | \begin{code} 169 | instance Functor List where 170 | map f [] = [] 171 | map f (x::xs) = f x :: map f xs 172 | \end{code} 173 | 174 | \begin{lstlisting}[style=stdout] 175 | Idris> map (*2) [1..10] 176 | [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] : List Integer 177 | \end{lstlisting} 178 | 179 | \noindent 180 | Having defined \texttt{Functor}, we can define \texttt{Applicative} 181 | which abstracts the notion of function application: 182 | 183 | \begin{code} 184 | infixl 2 <*> 185 | 186 | class Functor f => Applicative (f : Type -> Type) where 187 | pure : a -> f a 188 | (<*>) : f (a -> b) -> f a -> f b 189 | \end{code} 190 | 191 | \subsection{Monads and \texttt{do}-notation} 192 | 193 | \label{sec:monad} 194 | 195 | The \texttt{Monad} class allows us to encapsulate binding and computation, and 196 | is the basis of \texttt{do}-notation introduced in Section~\ref{sect:do}. 197 | It extends \texttt{Applicative} as defined above, and is defined as 198 | follows: 199 | 200 | \begin{code} 201 | class Applicative m => Monad (m : Type -> Type) where 202 | (>>=) : m a -> (a -> m b) -> m b 203 | \end{code} 204 | 205 | \noindent 206 | Inside a \texttt{do} block, the following syntactic transformations are 207 | applied: 208 | 209 | \begin{itemize} 210 | \item \texttt{x <- v; e} becomes \texttt{v >>= ($\backslash$x => e)} 211 | \item \texttt{v; e} becomes \texttt{v >>= ($\backslash$\_ => e)} 212 | \item \texttt{let x = v; e} becomes \texttt{let x = v in e} 213 | \end{itemize} 214 | 215 | \noindent 216 | \texttt{IO} is an instance of \texttt{Monad}, defined using primitive functions. 217 | We can also define an instance for \texttt{Maybe}, as follows: 218 | 219 | \begin{code} 220 | instance Monad Maybe where 221 | Nothing >>= k = Nothing 222 | (Just x) >>= k = k x 223 | \end{code} 224 | 225 | \noindent 226 | Using this we can, for example, define a function which adds two \texttt{Maybe Int}s, using the monad to encapsulate the error handling: 227 | 228 | \begin{code} 229 | m_add : Maybe Int -> Maybe Int -> Maybe Int 230 | m_add x y = do x' <- x -- Extract value from x 231 | y' <- y -- Extract value from y 232 | return (x' + y') -- Add them 233 | \end{code} 234 | 235 | \noindent 236 | This function will extract the values from \texttt{x} and \texttt{y}, if they are available, or return \texttt{Nothing} if they are not. 237 | Managing the \texttt{Nothing} cases is achieved by the \texttt{>>=} operator, hidden by the \texttt{do} notation. 238 | 239 | \begin{lstlisting}[style=stdout] 240 | *classes> m_add (Just 20) (Just 22) 241 | Just 42 : Maybe Int 242 | *classes> m_add (Just 20) Nothing 243 | Nothing : Maybe Int 244 | \end{lstlisting} 245 | 246 | \subsubsection*{\texttt{!}-notation} 247 | 248 | In many cases, using \texttt{do}-notation can make programs unnecessarily 249 | verbose, particularly in cases such as \texttt{m\_add} above where the value 250 | bound is used once, immediately. In these cases, we can use a shorthand 251 | version, as follows: 252 | 253 | \begin{code} 254 | m_add : Maybe Int -> Maybe Int -> Maybe Int 255 | m_add x y = return (!x + !y) 256 | \end{code} 257 | 258 | \noindent 259 | The notation \texttt{!expr} means that the expression \texttt{expr} should 260 | be evaluated and then implicitly bound. Conceptually, 261 | we can think of \texttt{!} as being a prefix function with the following type: 262 | 263 | \begin{code} 264 | (!) : m a -> a 265 | \end{code} 266 | 267 | \noindent 268 | Note, however, that it is not really a function, merely syntax! In practice, 269 | a subexpression \texttt{!expr} will lift \texttt{expr} as high as possible within 270 | its current scope, bind it to a fresh name \texttt{x}, and replace \texttt{!expr} 271 | with \texttt{x}. Expressions are lifted depth first, left to right. In 272 | practice, \texttt{!}-notation allows us to program in a more direct style, 273 | while still giving a notational clue as to which expressions are monadic. 274 | 275 | For example, the expression\ldots 276 | 277 | \begin{code} 278 | let y = 42 in f !(g !(print y) !x) 279 | \end{code} 280 | 281 | \ldots is lifted to: 282 | 283 | \begin{code} 284 | let y = 42 in do y' <- print y 285 | x' <- x 286 | g' <- g y' x' 287 | f g' 288 | \end{code} 289 | 290 | \subsubsection*{Monad comprehensions} 291 | 292 | The list comprehension notation we saw in Section~\ref{sec:listcomp} is more 293 | general, and applies to anything which is an instance of both \texttt{Monad} 294 | and \texttt{Alternative}: 295 | 296 | \begin{code} 297 | class Applicative f => Alternative (f : Type -> Type) where 298 | empty : f a 299 | (<|>) : f a -> f a -> f a 300 | \end{code} 301 | 302 | \noindent 303 | In general, a comprehension takes the form \texttt{[ exp | qual1, qual2, 304 | \ldots, qualn ]} where \texttt{quali} can be one of: 305 | 306 | \begin{itemize} 307 | \item A generator \texttt{x <- e} 308 | \item A \emph{guard}, which is an expression of type \texttt{Bool} 309 | \item A let binding \texttt{let x = e} 310 | \end{itemize} 311 | 312 | \noindent 313 | To translate a comprehension \texttt{[exp | qual1, qual2, \ldots, qualn]}, first any qualifier \texttt{qual} which is a \emph{guard} is translated to \texttt{guard qual}, using the following function: 314 | 315 | \begin{code} 316 | guard : Alternative f => Bool -> f () 317 | \end{code} 318 | 319 | \noindent 320 | Then the comprehension is converted to \texttt{do} notation: 321 | 322 | \begin{code} 323 | do { qual1; qual2; ...; qualn; return exp; } 324 | \end{code} 325 | 326 | \noindent 327 | Using monad comprehensions, an alternative definition for \texttt{m\_add} would be: 328 | 329 | \begin{code} 330 | m_add : Maybe Int -> Maybe Int -> Maybe Int 331 | m_add x y = [ x' + y' | x' <- x, y' <- y ] 332 | \end{code} 333 | 334 | \subsection{Idiom brackets} 335 | 336 | While \texttt{do} notation gives an alternative meaning to sequencing, idioms give an alternative meaning to \emph{application}. 337 | The notation and larger example in this section is inspired by Conor McBride and Ross Paterson's paper ``Applicative 338 | Programming with Effects''~\cite{idioms}. 339 | 340 | First, let us revisit \texttt{m\_add} above. All it is really doing is applying an operator to two values extracted from \texttt{Maybe Int}'s. 341 | We could abstract out the application: 342 | 343 | \begin{code} 344 | m_app : Maybe (a -> b) -> Maybe a -> Maybe b 345 | m_app (Just f) (Just a) = Just (f a) 346 | m_app _ _ = Nothing 347 | \end{code} 348 | 349 | \noindent 350 | Using this, we can write an alternative \texttt{m\_add} which uses this alternative notion of function application, with explicit calls to \texttt{m\_app}: 351 | 352 | \begin{code} 353 | m_add' : Maybe Int -> Maybe Int -> Maybe Int 354 | m_add' x y = m_app (m_app (Just (+)) x) y 355 | \end{code} 356 | 357 | \noindent 358 | Rather than having to insert \texttt{m\_app} everywhere there is an 359 | application, we can use \remph{idiom brackets} to do the job for us. To do 360 | this, we can make \texttt{Maybe} an instance of \texttt{Applicative} as 361 | follows, where \texttt{<\*>} is defined in the same way as \texttt{m\_app} 362 | above (this is defined in the \Idris{} library): 363 | 364 | \begin{code} 365 | instance Applicative Maybe where 366 | pure = Just 367 | 368 | (Just f) <*> (Just a) = Just (f a) 369 | _ <*> _ = Nothing 370 | \end{code} 371 | 372 | \noindent 373 | Using \remph{idiom brackets} we can use this instance as follows, where a 374 | function application \texttt{[| f a1 \dots an |]} is translated into 375 | \texttt{pure f <\*> a1 <\*> \dots <\*> an}: 376 | 377 | \begin{code} 378 | m_add' : Maybe Int -> Maybe Int -> Maybe Int 379 | m_add' x y = [| x + y |] 380 | \end{code} 381 | 382 | \subsubsection{An error-handling interpreter} 383 | 384 | Idiom notation is commonly useful when defining evaluators. 385 | McBride and Paterson describe such an evaluator~\cite{idioms}, for a language similar to the following: 386 | 387 | \begin{code} 388 | data Expr = Var String -- variables 389 | | Val Int -- values 390 | | Add Expr Expr -- addition 391 | \end{code} 392 | 393 | \noindent 394 | Evaluation will take place relative to a context mapping variables (represented as \texttt{String}s) to integer values, and can possibly fail. 395 | We define a data type \texttt{Eval} to wrap an evaluator: 396 | 397 | \begin{code} 398 | data Eval : Type -> Type where 399 | MkEval : (List (String, Int) -> Maybe a) -> Eval a 400 | \end{code} 401 | 402 | \noindent 403 | Wrapping the evaluator in a data type means we will be able to make it an instance of a type class later. We begin by defining a function to retrieve values from the context during evaluation: 404 | 405 | \begin{code} 406 | fetch : String -> Eval Int 407 | fetch x = MkEval (\e => fetchVal e) where 408 | fetchVal : List (String, Int) -> Maybe Int 409 | fetchVal [] = Nothing 410 | fetchVal ((v, val) :: xs) = if (x == v) 411 | then (Just val) 412 | else (fetchVal xs) 413 | \end{code} 414 | 415 | \noindent 416 | When defining an evaluator for the language, we will be applying functions in the context of an \texttt{Eval}, so it is natural to make \texttt{Eval} an instance of \texttt{Applicative}. 417 | Before \texttt{Eval} can be an instance of \texttt{Applicative} it is necessary to make \texttt{Eval} an instance of \texttt{Functor}: 418 | 419 | \begin{code} 420 | instance Functor Eval where 421 | map f (MkEval g) = MkEval (\e => map f (g e)) 422 | 423 | instance Applicative Eval where 424 | pure x = MkEval (\e => Just x) 425 | 426 | (<*>) (MkEval f) (MkEval g) = MkEval (\x => app (f x) (g x)) where 427 | app : Maybe (a -> b) -> Maybe a -> Maybe b 428 | app (Just fx) (Just gx) = Just (fx gx) 429 | app _ _ = Nothing 430 | \end{code} 431 | 432 | \noindent 433 | Evaluating an expression can now make use of the idiomatic application to handle errors: 434 | 435 | \begin{code} 436 | eval : Expr -> Eval Int 437 | eval (Var x) = fetch x 438 | eval (Val x) = [| x |] 439 | eval (Add x y) = [| eval x + eval y |] 440 | 441 | runEval : List (String, Int) -> Expr -> Maybe Int 442 | runEval env e = case eval e of 443 | MkEval envFn => envFn env 444 | \end{code} 445 | 446 | \subsection{Named Instances} 447 | 448 | It can be desirable to have multiple instances of a type class, for example to provide alternative methods for sorting or printing values. 449 | To achieve this, instances can be \remph{named} as follows: 450 | 451 | \begin{code} 452 | instance [myord] Ord Nat where 453 | compare Z (S n) = GT 454 | compare (S n) Z = LT 455 | compare Z Z = EQ 456 | compare (S x) (S y) = compare @{myord} x y 457 | \end{code} 458 | 459 | \noindent 460 | This declares an instance as normal, but with an explicit name, \texttt{myord}. 461 | The syntax \texttt{compare @\{myord\}} gives an explicit instance to \texttt{compare}, otherwise it would use the default instance for \texttt{Nat}. 462 | We can use this, for example, to sort a list of \texttt{Nat}s in reverse. 463 | Given the following list: 464 | 465 | \begin{code} 466 | testList : List Nat 467 | testList = [3,4,1] 468 | \end{code} 469 | 470 | \noindent 471 | \ldots we can sort it using the default \texttt{Ord} instance, then the named instance \texttt{myord} as follows, at the \Idris{} prompt: 472 | 473 | \begin{lstlisting}[style=stdout] 474 | *named_instance> show (sort testList) 475 | "[sO, sssO, ssssO]" : String 476 | *named_instance> show (sort @{myord} testList) 477 | "[ssssO, sssO, sO]" : String 478 | \end{lstlisting} 479 | 480 | \subsection{Determining Parameters} 481 | 482 | When a class has more than one parameter, it can help resolution if the 483 | parameters used to resolve the type class are restricted. For example: 484 | 485 | \begin{code} 486 | class Monad m => MonadState s (m : Type -> Type) | m where 487 | get : m s 488 | put : s -> m () 489 | \end{code} 490 | 491 | \noindent 492 | In this class, only \texttt{m} needs to be known to resolve this class, and 493 | \texttt{s} can then be determined from the instance. This is declared 494 | with the \texttt{| m} after the class declaration. We call \texttt{m} 495 | a \emph{determining parameter} of the \texttt{MonadState} class, because it 496 | is the parameter used to resolve an instance. 497 | 498 | When checking for overlapping instances, only the determining parameters 499 | are taken into account. For example, given a class: 500 | 501 | \begin{code} 502 | class Forget a b | a where 503 | forget : a -> b 504 | \end{code} 505 | 506 | \noindent 507 | The following instances are considered overlapping, because they have 508 | the same determining parameter: 509 | 510 | \begin{code} 511 | instance Forget Float Int 512 | instance Forget Float Integer 513 | \end{code} 514 | 515 | 516 | -------------------------------------------------------------------------------- /content/conclusions.tex: -------------------------------------------------------------------------------- 1 | \section{Further Reading} 2 | 3 | Further information about \Idris{} programming, and programming with dependent 4 | types in general, can be obtained from various sources: 5 | 6 | \begin{itemize} 7 | \item The \Idris{} web site (\url{http://idris-lang.org/}) and by asking questions on the mailing list. 8 | \item The IRC channel \texttt{\#idris}, on \url{chat.freenode.net}. 9 | \item The wiki (\url{https://github.com/idris-lang/Idris-dev/wiki/}) has 10 | further user provided information, in particular: 11 | \begin{itemize} 12 | \item \url{https://github.com/idris-lang/Idris-dev/wiki/Manual} 13 | \item \url{https://github.com/idris-lang/Idris-dev/wiki/Language-Features} 14 | \end{itemize} 15 | \item Examining the prelude and exploring the \texttt{samples} in the distribution. 16 | The \Idris{} source can be found online at: \url{https://github.com/idris-lang/Idris-dev}. 17 | \item Existing projects on the \texttt{Idris Hackers} web space: \url{http://idris-hackers.github.io}. 18 | \item Various papers (e.g. \cite{plpv11, scrap-engine,res-dsl-padl12}). 19 | Although these mostly describe older versions of \Idris{}. 20 | \end{itemize} 21 | 22 | -------------------------------------------------------------------------------- /content/interactive.tex: -------------------------------------------------------------------------------- 1 | \section{Interactive Editing} 2 | 3 | By now, we have seen several examples of how \Idris{}' dependent type system can give extra confidence in a function's correctness by giving a more precise description of its intended behaviour in its \emph{type}. 4 | We have also seen an example of how the type system can help with EDSL development by allowing a programmer to describe the type system of an object language. 5 | However, precise types give us more than verification of programs --- we can also exploit types to help write programs which are \emph{correct by construction}. 6 | 7 | The \Idris{} REPL provides several commands for inspecting and modifying parts of programs, based on their types, such as case splitting on a pattern variable, inspecting the type of a metavariable, and even a basic proof search mechanism. 8 | In this section, we explain how these features can be exploited by a text editor, and specifically how to do so in Vim\footnote{\url{https://github.com/idris-hackers/idris-vim}}. 9 | An interactive mode for 10 | Emacs\footnote{\url{https://github.com/idris-hackers/idris-emacs}} is also available. 11 | 12 | \subsection{Editing at the REPL} 13 | 14 | The REPL provides a number of commands, which we will describe shortly, which generate new program fragments based on the currently loaded module. These take the general form 15 | 16 | \begin{code} 17 | :command [line number] [name] 18 | \end{code} 19 | 20 | \noindent 21 | That is, each command acts on a specific source line, at a specific name, and outputs a new program fragment. Each command has an alternative form, which \emph{updates} the source file in-place: 22 | 23 | \begin{code} 24 | :command! [line number] [name] 25 | \end{code} 26 | 27 | \noindent 28 | When the REPL is loaded, it also starts a background process which accepts and responds to REPL commands, using \verb!idris --client!. 29 | For example, if we have a REPL running elsewhere, we can execute commands such as: 30 | 31 | \begin{lstlisting}[style=stdout] 32 | $ idris --client ':t plus' 33 | Prelude.Nat.plus : Nat -> Nat -> Nat 34 | $ idris --client '2+2' 35 | 4 : Integer 36 | \end{lstlisting} 37 | 38 | \noindent 39 | A text editor can take advantage of this, along with the editing commands, in order to provide interactive editing support. 40 | 41 | \subsection{Editing Commands} 42 | 43 | \subsubsection{:addclause} 44 | 45 | The \texttt{:addclause n f} command (abbreviated \texttt{:ac n f}) creates a template definition for the function named \texttt{f} declared on line \texttt{n}. 46 | For example, if the code beginning on line 94 contains: 47 | 48 | \begin{code} 49 | vzipWith : (a -> b -> c) -> 50 | Vect n a -> Vect n b -> Vect n c 51 | \end{code} 52 | 53 | \noindent 54 | then \texttt{:ac 94 vzipWith} will give: 55 | 56 | \begin{code} 57 | vzipWith f xs ys = ?vzipWith_rhs 58 | \end{code} 59 | 60 | \noindent 61 | The names are chosen according to hints which may be given by a programmer, and then made unique by the machine by adding a digit if necessary. 62 | Hints can be given as follows: 63 | 64 | \begin{code} 65 | %name Vect xs, ys, zs, ws 66 | \end{code} 67 | 68 | \noindent 69 | This declares that any names generated for types in the \texttt{Vect} family should be chosen in the order \texttt{xs}, \texttt{ys}, \texttt{zs}, \texttt{ws}. 70 | 71 | \subsubsection{:casesplit} 72 | 73 | The \texttt{:casesplit n x} command, abbreviated \texttt{:cs n x}, splits the pattern variable \texttt{x} on line \texttt{n} into the various pattern forms it may take, removing any cases which are impossible due to unification errors. 74 | For example, if the code beginning on line 94 is: 75 | 76 | \begin{code} 77 | vzipWith : (a -> b -> c) -> 78 | Vect n a -> Vect n b -> Vect n c 79 | vzipWith f xs ys = ?vzipWith_rhs 80 | \end{code} 81 | 82 | \noindent 83 | then \texttt{:cs 96 xs} will give: 84 | 85 | \begin{code} 86 | vzipWith f [] ys = ?vzipWith_rhs_1 87 | vzipWith f (x :: xs) ys = ?vzipWith_rhs_2 88 | \end{code} 89 | 90 | \noindent 91 | That is, the pattern variable \texttt{xs} has been split into the two possible cases \texttt{[]} and \texttt{x :: xs}. Again, the names are chosen according to the same heuristic. 92 | If we update the file (using \texttt{:cs!}) then case split on \texttt{ys} on the same line, we get: 93 | 94 | \begin{code} 95 | vzipWith f [] [] = ?vzipWith_rhs_3 96 | \end{code} 97 | 98 | \noindent 99 | That is, the pattern variable \texttt{ys} has been split into one case \texttt{[]}, \Idris{} having noticed that the other possible case \texttt{y :: ys} would lead to a unification error. 100 | 101 | \subsubsection{:addmissing} 102 | 103 | The \texttt{:addmissing n f} command, abbreviated \texttt{:am n f}, adds the clauses which are required to make the function \texttt{f} on line \texttt{n} cover all inputs. 104 | For example, if the code beginning on line 94 is\ldots 105 | 106 | \begin{code} 107 | vzipWith : (a -> b -> c) -> 108 | Vect n a -> Vect n b -> Vect n c 109 | vzipWith f [] [] = ?vzipWith_rhs_1 110 | \end{code} 111 | 112 | \noindent 113 | then \texttt{:am 96 vzipWith} gives: 114 | 115 | \begin{code} 116 | vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2 117 | \end{code} 118 | 119 | \noindent 120 | That is, it notices that there are no cases for non-empty vectors, generates the required clauses, and eliminates the clauses which would lead to unification errors. 121 | 122 | \subsubsection{:proofsearch} 123 | 124 | The \texttt{:proofsearch n f} command, abbreviated \texttt{:ps n f}, attempts to find a value for the metavariable \texttt{f} on line \texttt{n} by proof search, trying values of local variables, recursive calls and constructors of the required family. 125 | Optionally, it can take a list of \emph{hints}, which are functions it can try applying to solve the metavariable. 126 | % 127 | For example, if the code beginning on line 94 is: 128 | 129 | \begin{code} 130 | vzipWith : (a -> b -> c) -> 131 | Vect n a -> Vect n b -> Vect n c 132 | vzipWith f [] [] = ?vzipWith_rhs_1 133 | vzipWith f (x :: xs) (y :: ys) = ?vzipWith_rhs_2 134 | \end{code} 135 | 136 | \noindent 137 | then \texttt{:ps 96 vzipWith\_rhs\_1} will give 138 | 139 | \begin{code} 140 | [] 141 | \end{code} 142 | 143 | \noindent 144 | This works because it is searching for a \texttt{Vect} of length 0, of which the empty vector is the only possibiliy. 145 | Similarly, and perhaps surprisingly, there is only one possibility if we try to solve \texttt{:ps 97 vzipWith\_rhs\_2}: 146 | 147 | \begin{code} 148 | f x y :: (vzipWith f xs ys) 149 | \end{code} 150 | 151 | \noindent 152 | This works because \texttt{vzipWith} has a precise enough type: 153 | The resulting vector has to be non-empty (a \texttt{::}); the first element must have type \texttt{c} and the only way to get this is to apply \texttt{f} to \texttt{x} and \texttt{y}; finally, the tail of the vector can only be built recursively. 154 | 155 | \subsubsection{:makewith} 156 | 157 | The \texttt{:makewith n f} command, abbreviated \texttt{:mw n f}, adds a \texttt{with} to a pattern clause. 158 | For example, recall \texttt{parity}. 159 | If line 10 is: 160 | 161 | \begin{code} 162 | parity (S k) = ?parity_rhs 163 | \end{code} 164 | 165 | \noindent 166 | then \texttt{:mw 10 parity} will give: 167 | 168 | \begin{code} 169 | parity (S k) with (_) 170 | parity (S k) | with_pat = ?parity_rhs 171 | \end{code} 172 | 173 | \noindent 174 | If we then fill in the placeholder \verb!_! with \verb!parity k! and case split on \verb!with_pat! using \verb!:cs 11 with_pat! we get the following patterns: 175 | 176 | \begin{code} 177 | parity (S (plus n n)) | even = ?parity_rhs_1 178 | parity (S (S (plus n n))) | odd = ?parity_rhs_2 179 | \end{code} 180 | 181 | \noindent 182 | Note that case splitting has normalised the patterns here (giving \texttt{plus} rather than \texttt{+}). 183 | In any case, we see that using interactive editing significantly simplifies the implementation of dependent pattern matching by showing a programmer exactly what the valid patterns are. 184 | 185 | \subsection{Interactive Editing in Vim} 186 | 187 | The editor mode for Vim provides syntax highlighting, indentation and interactive editing support using the commands described above. 188 | Interactive editing is achieved using the following editor commands, each of which update the buffer directly: 189 | 190 | \begin{itemize} 191 | \item \verb!\d! adds a template definition for the name declared on the current line (using \texttt{:addclause}). 192 | \item \verb!\c! case splits the variable at the cursor (using \texttt{:casesplit}). 193 | \item \verb!\m! adds the missing cases for the name at the cursor (using \texttt{:addmissing}). 194 | \item \verb!\w! adds a \texttt{with} clause (using \texttt{:makewith}). 195 | \item \verb!\o! invokes a proof search to solve the metavariable under the cursor (using \texttt{:proofsearch}). 196 | \item \verb!\p! invokes a proof search with additional hints to solve the metavariable under the cursor (using \texttt{:proofsearch}). 197 | \end{itemize} 198 | 199 | \noindent 200 | There are also commands to invoke the type checker and evaluator: 201 | 202 | \begin{itemize} 203 | \item\verb!\t! displays the type of the (globally visible) name under the cursor. 204 | In the case of a metavariable, this displays the context and the expected type. 205 | \item\verb!\e! prompts for an expression to evaluate. 206 | \item\verb!\r! reloads and type checks the buffer. 207 | \end{itemize} 208 | 209 | \noindent 210 | Corresponding commands are also available in the Emacs mode. 211 | Support for other editors can be added in a relatively straighforward manner by using 212 | \texttt{idris --client}. 213 | 214 | 215 | -------------------------------------------------------------------------------- /content/interp.tex: -------------------------------------------------------------------------------- 1 | \section{Example: The Well-Typed Interpreter} 2 | \label{sect:interp} 3 | 4 | In this section, we'll use the features we've seen so far to write a larger example, an interpreter for a simple functional programming language, with variables, function application, binary operators and an \texttt{if...then...else} construct. 5 | We will use the dependent type system to ensure that any programs which can be represented are well-typed. 6 | 7 | \subsection{Representing Languages} 8 | \label{sect:interp:representation} 9 | 10 | First, let us define the types in the language. 11 | We have integers, booleans, and functions, represented by \texttt{Ty}: 12 | 13 | \begin{code} 14 | data Ty = TyInt | TyBool | TyFun Ty Ty 15 | \end{code} 16 | 17 | \noindent 18 | We can write a function to translate these representations to a concrete \Idris{} type --- remember that types are first class, so can be calculated just like any other value: 19 | 20 | \begin{code} 21 | interpTy : Ty -> Type 22 | interpTy TyInt = Int 23 | interpTy TyBool = Bool 24 | interpTy (TyFun A T) = interpTy A -> interpTy T 25 | \end{code} 26 | 27 | \noindent 28 | We're going to define a representation of our language in such a way that only well-typed programs can be represented. 29 | We'll index the representations of expressions by their type and the types of local variables (the context), which we'll be using regularly as an implicit argument, so we define everything in a \texttt{using} block: 30 | 31 | \begin{code} 32 | using (G:Vect n Ty) 33 | \end{code} 34 | 35 | \noindent 36 | The full representation of expressions is given in Listing~\ref{exprty}. 37 | They are indexed by the types of the local variables, and the type of the expression itself: 38 | 39 | \begin{code} 40 | data Expr : Vect n Ty -> Ty -> Type 41 | \end{code} 42 | 43 | \noindent 44 | Since expressions are indexed by their type, we can read the typing rules of the language from the definitions of the constructors. 45 | Let us look at each constructor in turn. 46 | 47 | \begin{code}[caption={Expression representation},label=exprty, float=htp] 48 | data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where 49 | Stop : HasType FZ (t :: G) t 50 | Pop : HasType k G t -> HasType (FS k) (u :: G) t 51 | 52 | data Expr : Vect n Ty -> Ty -> Type where 53 | Var : HasType i G t -> Expr G t 54 | Val : (x : Int) -> Expr G TyInt 55 | Lam : Expr (a :: G) t -> Expr G (TyFun a t) 56 | App : Expr G (TyFun a t) -> Expr G a -> Expr G t 57 | Op : (interpTy a -> interpTy b -> interpTy c) -> 58 | Expr G a -> Expr G b -> Expr G c 59 | If : Expr G TyBool -> 60 | Lazy (Expr G a) -> 61 | Lazy (Expr G a) -> Expr G a 62 | \end{code} 63 | 64 | \noindent 65 | We use a nameless representation for variables --- they are \emph{de Bruijn indexed}. 66 | Variables are represented by a proof of their membership in the context, \texttt{HasType i G T}, which is a proof that variable \texttt{i} in context \texttt{G} has type \texttt{T}. This is defined as follows: 67 | 68 | \begin{code} 69 | data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where 70 | Stop : HasType FZ (t :: G) t 71 | Pop : HasType k G t -> HasType (FS k) (u :: G) t 72 | \end{code} 73 | 74 | \noindent 75 | We can treat \emph{Stop} as a proof that the most recently defined variable is well-typed, and \emph{Pop n} as a proof that, if the \texttt{n}th most recently defined variable is well-typed, so is the \texttt{n+1}th. 76 | In practice, this means we use \texttt{Stop} to refer to the most recently defined variable, \texttt{Pop Stop} to refer to the next, and so on, via the \texttt{Var} constructor: 77 | 78 | \begin{code} 79 | Var : HasType i G t -> Expr G t 80 | \end{code} 81 | 82 | \noindent 83 | So, in an expression \verb!\x,\y. x y!, the variable \texttt{x} would have a de Bruijn index of 1, represented as \texttt{Pop Stop}, and \texttt{y 0}, represented as \texttt{Stop}. 84 | We find these by counting the number of lambdas between the definition and the use. 85 | 86 | \noindent 87 | A value carries a concrete representation of an integer: 88 | 89 | \begin{code} 90 | Val : (x : Int) -> Expr G TyInt 91 | \end{code} 92 | 93 | \noindent 94 | A lambda creates a function. 95 | In the scope of a function of type \texttt{a -> t}, there is a new local variable of type \texttt{a}, which is expressed by the context index: 96 | 97 | \begin{code} 98 | Lam : Expr (a :: G) t -> Expr G (TyFun a t) 99 | \end{code} 100 | 101 | \noindent 102 | Function application produces a value of type \texttt{t} given a function from \texttt{a} to \texttt{t} and a value of type \texttt{a}: 103 | 104 | \begin{code} 105 | App : Expr G (TyFun a t) -> Expr G a -> Expr G t 106 | \end{code} 107 | 108 | \noindent 109 | We allow arbitrary binary operators, where the type of the operator informs what the types of the arguments must be: 110 | 111 | \begin{code} 112 | Op : (interpTy a -> interpTy b -> interpTy c) -> 113 | Expr G a -> Expr G b -> Expr G c 114 | \end{code} 115 | 116 | \noindent 117 | Finally, if expressions make a choice given a boolean. 118 | Each branch must have the same type, and we will evaluate the branches 119 | lazily so that only the branch which is taken need be evaluated: 120 | 121 | \begin{code} 122 | If : Expr G TyBool -> 123 | Lazy (Expr G a) -> 124 | Lazy (Expr G a) -> 125 | Expr G a 126 | \end{code} 127 | 128 | \subsection{Writing the Interpreter} 129 | \label{sec:interp:eval} 130 | 131 | When we evaluate an \texttt{Expr}, we'll need to know the values in scope, as well as their types. 132 | \texttt{Env} is an environment, indexed over the types in scope. 133 | Since an environment is just another form of list, albeit with a strongly specified connection to the vector of local variable types, we use the usual \texttt{::} and \texttt{Nil} constructors so that we can use the usual list syntax. 134 | Given a proof that a variable is defined in the context, we can then produce a value from the environment: 135 | 136 | \begin{code} 137 | data Env : Vect n Ty -> Type where 138 | Nil : Env Nil 139 | (::) : interpTy a -> Env G -> Env (a :: G) 140 | 141 | lookup : HasType i G t -> Env G -> interpTy t 142 | lookup Stop (x :: xs) = x 143 | lookup (Pop k) (x :: xs) = lookup k xs 144 | \end{code} 145 | 146 | \begin{code}[caption={Intepreter definition},label=interpdef] 147 | interp : Env G -> Expr G t -> interpTy t 148 | interp env (Var i) = lookup i env 149 | interp env (Val x) = x 150 | interp env (Lam sc) = \x => interp (x :: env) sc 151 | interp env (App f s) = interp env f (interp env s) 152 | interp env (Op op x y) = op (interp env x) (interp env y) 153 | interp env (If x t e) = if interp env x then interp env t 154 | else interp env e 155 | \end{code} 156 | 157 | \noindent 158 | Given this, an interpreter (Listing~\ref{interpdef}) is a function which translates an \texttt{Expr} into a concrete \Idris{} value with respect to a specific environment: 159 | 160 | \begin{code} 161 | interp : Env G -> Expr G t -> interpTy t 162 | \end{code} 163 | 164 | \noindent 165 | To translate a variable, we simply look it up in the environment: 166 | 167 | \begin{code} 168 | interp env (Var i) = lookup i env 169 | \end{code} 170 | 171 | \noindent 172 | To translate a value, we just return the concrete representation of the value: 173 | 174 | \begin{code} 175 | interp env (Val x) = x 176 | \end{code} 177 | 178 | \noindent 179 | Lambdas are more interesting. 180 | In this case, we construct a function which interprets the scope of the lambda with a new value in the environment. 181 | So, a function in the object language is translated to an \Idris{} function: 182 | 183 | \begin{code} 184 | interp env (Lam sc) = \x => interp (x :: env) sc 185 | \end{code} 186 | 187 | \noindent 188 | For an application, we interpret the function and its argument and apply it directly. 189 | We know that interpreting \texttt{f} must produce a function, because of its type: 190 | 191 | \begin{code} 192 | interp env (App f s) = interp env f (interp env s) 193 | \end{code} 194 | 195 | \noindent 196 | Operators and interpreters are, again, direct translations into the equivalent \Idris{} constructs. 197 | For operators, we apply the function to its operands directly, and for \texttt{If}, we apply the \Idris{} \texttt{if...then...else} construct directly. 198 | 199 | \begin{code} 200 | interp env (Op op x y) = op (interp env x) (interp env y) 201 | interp env (If x t e) = if interp env x then interp env t 202 | else interp env e 203 | \end{code} 204 | 205 | \subsection{Testing} 206 | \label{sec:interp:testing} 207 | 208 | We can make some simple test functions. 209 | Firstly, adding two inputs \verb!\x. \y. y + x! is written as follows: 210 | 211 | \begin{code} 212 | add : Expr G (TyFun TyInt (TyFun TyInt TyInt)) 213 | add = Lam (Lam (Op (+) (Var Stop) (Var (Pop Stop)))) 214 | \end{code} 215 | 216 | \noindent 217 | More interestingly, a factorial function \texttt{fact} (e.g.\ \texttt{$\textbackslash$x. if (x == 0) then 1 else (fact (x-1) * x)}), can be written as: 218 | 219 | \begin{code} 220 | fact : Expr G (TyFun TyInt TyInt) 221 | fact = Lam (If (Op (==) (Var Stop) (Val 0)) 222 | (Val 1) 223 | (Op (*) (App fact (Op (-) (Var Stop) (Val 1))) 224 | (Var Stop))) 225 | \end{code} 226 | 227 | \subsection{Running} 228 | \label{sec:interp:running} 229 | 230 | To finish, we write a \texttt{main} program which interprets the factorial function on user input: 231 | 232 | \begin{code} 233 | main : IO () 234 | main = do putStr "Enter a number: " 235 | x <- getLine 236 | print (interp [] fact (cast x)) 237 | \end{code} 238 | 239 | \noindent 240 | Here, \texttt{cast} is an overloaded function which converts a value from one type to another if possible. 241 | Here, it converts a string to an integer, giving 0 if the input is invalid. 242 | An example run of this program at the \Idris{} interactive environment is shown in Listing~\ref{factrun}. 243 | 244 | \begin{lstlisting}[float=h,caption={Running the well-typed interpreter}, label=factrun, style=stdout] 245 | $ idris interp.idr 246 | ____ __ _ 247 | / _/___/ /____(_)____ 248 | / // __ / ___/ / ___/ Version ^\version{}^ 249 | _/ // /_/ / / / (__ ) http://www.idris-lang.org/ 250 | /___/\__,_/_/ /_/____/ Type :? for help 251 | 252 | Type checking ./interp.idr 253 | *interp> :exec 254 | Enter a number: 6 255 | 720 256 | *interp> 257 | \end{lstlisting} 258 | 259 | \subsubsection*{Aside: \texttt{cast}} 260 | 261 | The prelude defines a type class \texttt{Cast} which allows conversion between types: 262 | 263 | \begin{code} 264 | class Cast from to where 265 | cast : from -> to 266 | \end{code} 267 | 268 | \noindent 269 | It is a \emph{multi-parameter} type class, defining the source type and object type of the cast. 270 | It must be possible for the type checker to infer \emph{both} parameters at the point where the cast is applied. 271 | There are casts defined between all of the primitive types, as far as they make sense. 272 | 273 | %\subsection{Unit testing} 274 | 275 | %Recall the \texttt{so} data type: 276 | 277 | %\begin{code} 278 | %data so : Bool -> Type where 279 | % oh : so True 280 | %\end{code} 281 | 282 | %\noindent 283 | %This requires its parameter to be a \texttt{True} value. 284 | %One simple application of this is to perform unit testing of functions at compile time. 285 | %For example, we know that \texttt{4! = 24} so we can set up a test case as follows: 286 | 287 | %\begin{code} 288 | %unitTestFac : so (interp [] fact 4 == 24) 289 | %unitTestFac = oh 290 | %\end{code} 291 | 292 | %\noindent 293 | %For the program to compile, the test case must pass. If we change \texttt{24} to \texttt{25}, say, we will get an error message like the following: 294 | 295 | %\begin{lstlisting} 296 | %Type checking ./interp.idr 297 | %interp.idr:64:Can't unify so True with so False 298 | 299 | %Specifically: 300 | % Can't unify True with False 301 | %\end{lstlisting} 302 | -------------------------------------------------------------------------------- /content/intro.tex: -------------------------------------------------------------------------------- 1 | \section{Introduction} 2 | 3 | In conventional programming languages, there is a clear distinction between \emph{types} and \emph{values}. 4 | For example, in Haskell~\cite{haskell-report}, the following are types, representing integers, characters, lists of characters, and lists of any value respectively: 5 | 6 | \begin{itemize} 7 | \item \texttt{Int}, \texttt{Char}, \texttt{[Char]}, \texttt{[a]} 8 | \end{itemize} 9 | 10 | \noindent 11 | Correspondingly, the following values are examples of inhabitants of those types: 12 | 13 | \begin{itemize} 14 | \item \texttt{42}, \texttt{'a'}, \texttt{"Hello world!"}, \texttt{[2,3,4,5,6]} 15 | \end{itemize} 16 | 17 | \noindent 18 | In a language with \emph{dependent types}, however, the distinction is less clear. 19 | Dependent types allow types to ``depend'' on values --- in other words, types are a \emph{first class} language construct and can be manipulated like any other value. 20 | The standard example is the type of lists of a given length\footnote{Typically, and perhaps confusingly, referred to in the dependently typed programming literature as ``vectors''}, \texttt{Vect n a}, where \texttt{a} is the element type and \texttt{n} is the length of the list and can be an arbitrary term. 21 | 22 | When types can contain values, and where those values describe properties (e.g.\ the length of a list) the type of a function can begin to describe its own properties. 23 | For example, concatenating two lists has the property that the resulting list's length is the sum of the lengths of the two input lists. 24 | We can therefore give the following type to the \texttt{app} function, which concatenates vectors: 25 | 26 | \begin{code} 27 | app : Vect n a -> Vect m a -> Vect (n + m) a 28 | \end{code} 29 | 30 | \noindent 31 | This tutorial introduces \Idris{}, a general purpose functional programming language with dependent types. 32 | The goal of the \Idris{} project is to build a dependently typed language suitable for verifiable \emph{systems} programming. 33 | To this end, \Idris{} is a compiled language which aims to generate efficient executable code. 34 | It also has a lightweight foreign function interface which allows easy interaction with external C libraries. 35 | 36 | \subsection{Intended Audience} 37 | 38 | This tutorial is intended as a brief introduction to the language, and is aimed at readers already familiar with a functional language such as Haskell\footnote{\url{http://www.haskell.org}} or OCaml\footnote{\url{http://ocaml.org}}. 39 | In particular, a certain amount of familiarity with Haskell syntax is assumed, although most concepts will at least be explained briefly. 40 | The reader is also assumed to have some interest in using dependent types for writing and verifying systems software. 41 | 42 | \subsection{Example Code} 43 | 44 | This tutorial includes some example code, which has been tested with \Idris{} version \version{}. 45 | The files are available in the \Idris{} distribution, and provided along side the tutorial source, so that you can try them out easily, under \texttt{tutorial/examples}. 46 | However, it is strongly recommended that you can type them in yourself, rather than simply loading and reading them. 47 | 48 | -------------------------------------------------------------------------------- /content/misc/args.tex: -------------------------------------------------------------------------------- 1 | \subsection{Auto implicit arguments} 2 | 3 | We have already seen implicit arguments, which allows arguments to be omitted when they can be inferred by the type checker, e.g.\ 4 | 5 | \begin{code} 6 | index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a 7 | \end{code} 8 | 9 | \noindent 10 | In other situations, it may be possible to infer arguments not by type checking but by searching the context for an appropriate value, or constructing a proof. 11 | For example, the following definition of \texttt{head} which requires a proof that the list is non-empty: 12 | 13 | \begin{code} 14 | isCons : List a -> Bool 15 | isCons [] = False 16 | isCons (x :: xs) = True 17 | 18 | head : (xs : List a) -> (isCons xs = True) -> a 19 | head (x :: xs) _ = x 20 | \end{code} 21 | 22 | \noindent 23 | If the list is statically known to be non-empty, either because its value is known or because a proof already exists in the context, the proof can be constructed automatically. 24 | Auto implicit arguments allow this to happen silently. 25 | We define \texttt{head} as follows: 26 | 27 | \begin{code} 28 | head : (xs : List a) -> {auto p : isCons xs = True} -> a 29 | head (x :: xs) = x 30 | \end{code} 31 | 32 | \noindent 33 | The \texttt{auto} annotation on the implicit argument means that \Idris{} will attempt to fill in the implicit argument using the \texttt{trivial} tactic, which searches through the context for a proof, and tries to solve with \texttt{refl} if a proof is not found. 34 | Now when \texttt{head} is applied, the proof can be omitted. 35 | In the case that a proof is not found, it can be provided explicitly as normal: 36 | 37 | \begin{code} 38 | head xs {p = ?headProof} 39 | \end{code} 40 | 41 | \noindent 42 | More generally, we can fill in implicit arguments with a default value by annotating them with \texttt{default}. 43 | The definition above is equivalent to: 44 | 45 | \begin{code} 46 | head : (xs : List a) -> 47 | {default proof { trivial; } p : isCons xs = True} -> a 48 | head (x :: xs) = x 49 | \end{code} 50 | 51 | \subsection{Implicit conversions} 52 | 53 | \Idris{} supports the creation of \emph{implicit conversions}, which allow automatic conversion of values from one type to another when required to make a term type correct. 54 | This is intended to increase convenience and reduce verbosity. A contrived but simple example is the following: 55 | 56 | \begin{code} 57 | implicit intString : Int -> String 58 | intString = show 59 | 60 | test : Int -> String 61 | test x = "Number " ++ x 62 | \end{code} 63 | 64 | \noindent 65 | In general, we cannot append an \texttt{Int} to a \texttt{String}, but the implicit conversion function \texttt{intString} can convert \texttt{x} to a \texttt{String}, so the definition of \texttt{test} is type correct. 66 | An implicit conversion is implemented just like any other function, but given the \texttt{implicit} modifier, and restricted to one explicit argument. 67 | 68 | Only one implicit conversion will be applied at a time. 69 | That is, implicit conversions cannot be chained. 70 | Implicit conversions of simple types, as above, are however discouraged! 71 | More commonly, an implicit conversion would be used to reduce verbosity in an embedded domain specific language, or to hide details of a proof. 72 | Such examples are beyond the scope of this tutorial. 73 | -------------------------------------------------------------------------------- /content/misc/codegen.tex: -------------------------------------------------------------------------------- 1 | \subsection{C Target} 2 | 3 | The default target of \Idris{} is C. Compiling via : 4 | 5 | \begin{lstlisting}[style=stdout] 6 | $ idris hello.idr -o hello 7 | \end{lstlisting} 8 | 9 | \noindent 10 | is equivalent to : 11 | 12 | \begin{lstlisting}[style=stdout] 13 | $ idris --codegen C hello.idr -o hello 14 | \end{lstlisting} 15 | 16 | \noindent 17 | When the command above is used, a temporary C 18 | source is generated, which is then compiled into 19 | an executable named \texttt{hello}. 20 | 21 | \noindent 22 | In order to view the generated C code, compile 23 | via : 24 | 25 | \begin{lstlisting}[style=stdout] 26 | $ idris hello.idr -S -o hello.c 27 | \end{lstlisting} 28 | 29 | \noindent 30 | To turn optimisations on, use the \texttt{\%flag C} 31 | pragma within the code, as is shown below : 32 | 33 | \begin{code} 34 | module Main 35 | %flag C "-O3" 36 | 37 | factorial : Int -> Int 38 | factorial 0 = 1 39 | factorial n = n * (factorial (n-1)) 40 | 41 | main : IO () 42 | main = do 43 | putStrLn $ show $ factorial 3 44 | \end{code} 45 | 46 | \subsection{JavaScript Target} 47 | 48 | \Idris{} is capable of producing \emph{JavaScript} code that can be run in a browser as well as in the \emph{NodeJS} environment or alike. 49 | One can use the FFI to communicate with the \emph{JavaScript} ecosystem. 50 | 51 | \subsubsection*{Code Generation} 52 | 53 | \noindent 54 | Code generation is split into two separate targets. 55 | To generate code that is tailored for running in the browser issue the following command: 56 | 57 | \begin{lstlisting}[style=stdout] 58 | $ idris --codegen javascript hello.idr -o hello.js 59 | \end{lstlisting} 60 | 61 | \noindent 62 | The resulting file can be embedded into your HTML just like any other \emph{JavaScript} code. 63 | 64 | \noindent 65 | Generating code for \emph{NodeJS} is slightly different. 66 | \Idris{} outputs a \emph{JavaScript} file that can be directly executed via \texttt{node}. 67 | 68 | \begin{lstlisting}[style=stdout] 69 | $ idris --codegen node hello.idr -o hello 70 | $ ./hello 71 | Hello world 72 | \end{lstlisting} 73 | 74 | \noindent 75 | Take into consideration that the \emph{JavaScript} code generator is using \texttt{console.log} to write text to \texttt{stdout}, this means that it will automatically add a newline to the end of each string. 76 | This behaviour does not show up in the \emph{NodeJS} code generator. 77 | 78 | \subsubsection*{Using the FFI} 79 | 80 | \noindent 81 | To write a useful application we need to communicate with the outside world. 82 | Maybe we want to manipulate the DOM or send an Ajax request. 83 | For this task we can use the FFI. 84 | Since most \emph{JavaScript} APIs demand callbacks we need to extend the FFI so we can pass functions as arguments. 85 | 86 | \noindent 87 | The \emph{JavaScript} FFI works a little bit differently than the regular FFI. 88 | It uses positional arguments to directly insert our arguments into a piece of \emph{JavaScript} code. 89 | 90 | \noindent 91 | One could use the primitive addition of \emph{JavaScript} like so: 92 | 93 | \begin{code} 94 | module Main 95 | 96 | primPlus : Int -> Int -> IO Int 97 | primPlus a b = mkForeign (FFun "%0 + %1" [FInt, FInt] FInt) a b 98 | 99 | main : IO () 100 | main = do 101 | a <- primPlus 1 1 102 | b <- primPlus 1 2 103 | print (a, b) 104 | \end{code} 105 | 106 | \noindent 107 | Notice that the \texttt{\%n} notation qualifies the position of the \texttt{n}-th argument given to our foreign function starting from 0. 108 | When you need a percent sign rather than a position simply use \texttt{\%\%} instead. 109 | 110 | \noindent 111 | Passing functions to a foreign function is very similar. 112 | Let's assume that we want to call the following function from the \emph{JavaScript} world: 113 | 114 | \begin{code}[language=c] 115 | function twice(f, x) { 116 | return f(f(x)); 117 | } 118 | \end{code} 119 | 120 | \noindent 121 | We obviously need to pass a function \texttt{f} here (we can infer it from the way we use \texttt{f} in \texttt{twice}, it would be more obvious if \emph{JavaScript} had types). 122 | 123 | \noindent 124 | The \emph{JavaScript} FFI is able to understand functions as arguments when you give it something of type \texttt{FFunction}. 125 | The following example code calls \texttt{twice} in \emph{JavaScript} and returns the result to our \Idris{} program: 126 | 127 | \begin{code} 128 | module Main 129 | 130 | twice : (Int -> Int) -> Int -> IO Int 131 | twice f x = mkForeign ( 132 | FFun "twice(%0,%1)" [FFunction FInt FInt, FInt] FInt 133 | ) f x 134 | 135 | main : IO () 136 | main = do 137 | a <- twice (+1) 1 138 | print a 139 | \end{code} 140 | 141 | \noindent 142 | The program outputs \texttt{3}, just like we expected. 143 | 144 | \subsubsection*{Including external \emph{JavaScript} files} 145 | 146 | \noindent 147 | Whenever one is working with \emph{JavaScript} one might want to include 148 | external libraries or just some functions that she or he wants to call via 149 | FFI which are stored in external files. The \emph{JavaScript} and \emph{NodeJS} code generators 150 | understand the \texttt{\%include} directive. Keep in mind that \emph{JavaScript} and \emph{NodeJS} 151 | are handled as different code generators, therefore you will have to state which one you want to target. 152 | This means that you can include different files for \emph{JavaScript} and \emph{NodeJS} in the same 153 | \Idris{} source file. 154 | 155 | \noindent 156 | So whenever you want to add an external \emph{JavaScript} file 157 | you can do this like so: 158 | 159 | \noindent 160 | For \emph{NodeJS}: 161 | 162 | \begin{code} 163 | %include Node "path/to/external.js" 164 | \end{code} 165 | 166 | \noindent 167 | And for use in the browser: 168 | 169 | \begin{code} 170 | %include JavaScript "path/to/external.js" 171 | \end{code} 172 | 173 | \noindent 174 | The given files will be added to the top of the generated code. 175 | 176 | \subsubsection*{Including \emph{NodeJS} modules} 177 | 178 | \noindent 179 | The \emph{NodeJS} code generator can also include modules with the \texttt{\%lib} 180 | directive. 181 | 182 | \begin{code} 183 | %lib Node "fs" 184 | \end{code} 185 | 186 | \noindent 187 | This directive compiles into the following \emph{JavaScript} 188 | 189 | \begin{code} 190 | var fs = require("fs"); 191 | \end{code} 192 | 193 | \subsubsection*{Shrinking down generated \emph{JavaScript}} 194 | 195 | \Idris{} can produce very big chunks of \emph{JavaScript} code. 196 | However, the generated code can be minified using the \texttt{closure-compiler} from Google. 197 | Any other minifier is also suitable but \texttt{closure-compiler} offers advanced compilation that does some aggressive inlining and code elimination. 198 | \Idris{} can take full advantage of this compilation mode and it's highly recommended to use it when shipping a \emph{JavaScript} application written in \Idris{}. 199 | 200 | -------------------------------------------------------------------------------- /content/misc/cumulativity.tex: -------------------------------------------------------------------------------- 1 | \subsection{Cumulativity} 2 | 3 | Since values can appear in types and \emph{vice versa}, it is natural that types themselves have types. 4 | For example: 5 | 6 | \begin{lstlisting}[style=stdout] 7 | *universe> :t Nat 8 | Nat : Type 9 | *universe> :t Vect 10 | Vect : Nat -> Type -> Type 11 | \end{lstlisting} 12 | 13 | \noindent 14 | But what about the type of \texttt{Type}? If we ask \Idris{} it reports 15 | 16 | \begin{lstlisting}[style=stdout] 17 | *universe> :t Type 18 | Type : Type 1 19 | \end{lstlisting} 20 | 21 | \noindent 22 | If \texttt{Type} were its own type, it would lead to an inconsistency due to Girard's paradox~\cite{girard-thesis}, so internally there is a \emph{hierarchy} of types (or \emph{universes}): 23 | 24 | \begin{code} 25 | Type : Type 1 : Type 2 : Type 3 : ... 26 | \end{code} 27 | 28 | \noindent 29 | Universes are \emph{cumulative}, that is, if \texttt{x : Type n} we can also have that \texttt{x : Type m}, as long as \texttt{n < m}. 30 | The typechecker generates such universe constraints and reports an error if any inconsistencies are found. 31 | Ordinarily, a programmer does not need to worry about this, but it does prevent (contrived) programs such as the following: 32 | 33 | \begin{code} 34 | myid : (a : Type) -> a -> a 35 | myid _ x = x 36 | 37 | idid : (a : Type) -> a -> a 38 | idid = myid _ myid 39 | \end{code} 40 | 41 | \noindent 42 | The application of \texttt{myid} to itself leads to a cycle in the universe hierarchy --- \texttt{myid}'s first argument is a \texttt{Type}, which cannot be at a lower level than required if it is applied to itself. 43 | 44 | %\subsection{Comparison} 45 | 46 | %How does \Idris{} compare with other dependently typed languages and proof 47 | %assistants, such as Coq, Agda and Epigram? 48 | -------------------------------------------------------------------------------- /content/misc/ffi.tex: -------------------------------------------------------------------------------- 1 | \subsection{Foreign function calls} 2 | 3 | For practical programming, it is often necessary to be able to use external libraries, particularly for interfacing with the operating system, file system, networking, \emph{et cetera}. 4 | \Idris{} provides a lightweight foreign function interface for achieving this, as part of the prelude. 5 | For this, we assume a certain amount of knowledge of C and the \texttt{gcc} compiler. 6 | First, we define a datatype which describes the external types we can handle: 7 | 8 | \begin{code} 9 | data FTy = FInt | FFloat | FChar | FString | FPtr | FUnit 10 | \end{code} 11 | 12 | \noindent 13 | Each of these corresponds directly to a C type. 14 | Respectively: \texttt{int}, \texttt{double}, \texttt{char}, \texttt{char*}, \texttt{void*} and \texttt{void}. 15 | There is also a translation to a concrete \Idris{} type, described by the following function: 16 | 17 | \begin{code} 18 | interpFTy : FTy -> Type 19 | interpFTy FInt = Int 20 | interpFTy FFloat = Float 21 | interpFTy FChar = Char 22 | interpFTy FString = String 23 | interpFTy FPtr = Ptr 24 | interpFTy FUnit = () 25 | \end{code} 26 | 27 | \noindent 28 | A foreign function is described by a list of input types and a return type, which can then be converted to an \Idris{} type: 29 | 30 | \begin{code} 31 | ForeignTy : (xs:List FTy) -> (t:FTy) -> Type 32 | \end{code} 33 | 34 | \noindent 35 | A foreign function is assumed to be impure, so \texttt{ForeignTy} builds an \texttt{IO} type, for example: 36 | 37 | \begin{lstlisting}[style=stdout] 38 | Idris> ForeignTy [FInt, FString] FString 39 | Int -> String -> IO String : Type 40 | 41 | Idris> ForeignTy [FInt, FString] FUnit 42 | Int -> String -> IO () : Type 43 | \end{lstlisting} 44 | 45 | \noindent 46 | We build a call to a foreign function by giving the name of the function, a list of argument types and the return type. 47 | The built in construct \texttt{mkForeign} converts this description to a function callable by \Idris{}: 48 | 49 | \begin{code} 50 | data Foreign : Type -> Type where 51 | FFun : String -> (xs:List FTy) -> (t:FTy) -> 52 | Foreign (ForeignTy xs t) 53 | 54 | mkForeign : Foreign x -> x 55 | \end{code} 56 | 57 | \noindent 58 | Note that the compiler expects \texttt{mkForeign} to be fully applied to 59 | build a complete foreign function call. 60 | For example, the \texttt{putStr} function is implemented as follows, as a call to an external function \texttt{putStr} defined in the run-time system: 61 | 62 | \begin{code} 63 | putStr : String -> IO () 64 | putStr x = mkForeign (FFun "putStr" [FString] FUnit) x 65 | \end{code} 66 | 67 | \subsubsection*{Include and linker directives} 68 | 69 | Foreign function calls are translated directly to calls to C functions, with appropriate conversion between the \Idris{} representation of a value and the C representation. 70 | Often this will require extra libraries to be linked in, or extra header and object files. 71 | This is made possible through the following directives: 72 | 73 | \begin{itemize} 74 | \item \texttt{\%lib \emph{target} "x"} --- include the \texttt{libx} library. 75 | If the target is \texttt{C} this is equivalent to passing the \texttt{-lx} option to \texttt{gcc}. 76 | If the target is Java the library will be interpreted as a \texttt{groupId\-:artifactId\-:packaging:version} dependency coordinate for maven. 77 | \item \texttt{\%include \emph{target} "x"} --- use the header file or import \texttt{x} for the given back end target. 78 | \item \texttt{\%link \emph{target} "x.o"} --- link with the object file \texttt{x.o} when using the given back end target. 79 | \item \texttt{\%dynamic "x.so"} --- dynamically link the interpreter with the shared object \texttt{x.so}. 80 | \end{itemize} 81 | 82 | \subsubsection*{Testing foreign function calls} 83 | Normally, the Idris interpreter (used for typechecking and at the REPL) will not perform IO actions. 84 | Additionally, as it neither generates C code nor compiles to machine code, the \texttt{\%lib}, \texttt{\%include} and \texttt{\%link} directives have no effect. 85 | IO actions and FFI calls can be tested using the special REPL command \texttt{:x EXPR}, and C libraries can be dynamically loaded in the interpreter by using the \texttt{:dynamic} command or the \texttt{\%dynamic} directive. 86 | For example: 87 | 88 | \begin{lstlisting}[style=stdout] 89 | Idris> :dynamic libm.so 90 | Idris> :x unsafePerformIO ((mkForeign (FFun "sin" [FFloat] FFloat)) 1.6) 91 | 0.9995736030415051 : Float 92 | \end{lstlisting} 93 | 94 | -------------------------------------------------------------------------------- /content/misc/literate.tex: -------------------------------------------------------------------------------- 1 | \subsection{Literate programming} 2 | 3 | Like Haskell, \Idris{} supports \emph{literate} programming. 4 | If a file has an extension of \texttt{.lidr} then it is assumed to be a literate file. 5 | In literate programs, everything is assumed to be a comment unless the line begins with a greater than sign \texttt{>}, for example: 6 | 7 | \begin{lstlisting} 8 | > module literate 9 | 10 | This is a comment. The main program is below 11 | 12 | > main : IO () 13 | > main = putStrLn "Hello literate world!\n" 14 | \end{lstlisting} 15 | 16 | \noindent 17 | An additional restriction is that there must be a blank line between a program line (beginning with \texttt{>}) and a comment line (beginning with any other character). 18 | 19 | -------------------------------------------------------------------------------- /content/misc/type-providers.tex: -------------------------------------------------------------------------------- 1 | \subsection{Type Providers} 2 | 3 | Idris type providers, inspired by F\#'s type providers, are a means of making our types be ``about'' something in the world outside of Idris. 4 | For example, given a type that represents a database schema and a query that is checked against it, a type provider could read the schema of a real database during type checking. 5 | 6 | Idris type providers use the ordinary execution semantics of Idris to run an IO action and extract the result. 7 | This result is then saved as a constant in the compiled code. 8 | It can be a type, in which case it is used like any other type, or it can be a value, in which case it can be used as any other value, including as an index in types. 9 | 10 | Type providers are still an experimental extension. To enable the extension, use the \texttt{\%language} directive: 11 | 12 | \begin{code} 13 | %language TypeProviders 14 | \end{code} 15 | 16 | A provider \texttt{p} for some type \texttt{t} is simply an expression of type \texttt{IO (Provider t)}. 17 | The \texttt{\%provide} directive causes the type checker to execute the action and bind the result to a name. 18 | This is perhaps best illustrated with a simple example. 19 | The type provider \texttt{fromFile} reads a text file. 20 | If the file consists of the string \texttt{"Int"}, then the type \texttt{Int} will be provided. 21 | Otherwise, it will provide the type \texttt{Nat}. 22 | 23 | \begin{code} 24 | strToType : String -> Type 25 | strToType "Int" = Int 26 | strToType _ = Nat 27 | 28 | fromFile : String -> IO (Provider Type) 29 | fromFile fname = do str <- readFile fname 30 | return (Provide (strToType (trim str))) 31 | \end{code} 32 | 33 | We then use the \texttt{\%provide} directive: 34 | 35 | \begin{code} 36 | %provide (T1 : Type) with fromFile "theType" 37 | 38 | foo : T1 39 | foo = 2 40 | \end{code} 41 | 42 | \noindent 43 | If the file named \texttt{theType} consists of the word \texttt{Int}, then \texttt{foo} will be an \texttt{Int}. 44 | Otherwise, it will be a \texttt{Nat}. 45 | When Idris encounters the directive, it first checks that the provider expression \texttt{fromFile "theType"} has type \texttt{IO (Provider Type)}. 46 | Next, it executes the provider. If the result is \texttt{Provide t}, then \texttt{T1} is defined as \texttt{t}. 47 | Otherwise, the result is an error. 48 | 49 | Our datatype \texttt{Provider t} has the following definition: 50 | 51 | \begin{code} 52 | data Provider a = Error String 53 | | Provide a 54 | \end{code} 55 | 56 | \noindent 57 | We have already seen the \texttt{Provide} constructor. 58 | The \texttt{Error} constructor allows type providers to return useful error messages. 59 | The example in this section was purposefully simple. 60 | More complex type provider implementations, including a statically-checked SQLite binding, are available in an external collection\footnote{\url{https://github.com/david-christiansen/idris-type-providers}}. 61 | 62 | -------------------------------------------------------------------------------- /content/miscellany.tex: -------------------------------------------------------------------------------- 1 | \section{Miscellany} 2 | 3 | In this section we discuss a variety of additional features: 4 | 5 | \begin{multicols}{2} 6 | \begin{compactitem} 7 | \item auto, implicit, and default arguments; 8 | \item literate programming; 9 | \item interfacing with external libraries through the foreign function interface; 10 | \item type providers; 11 | \item code generation; and 12 | \item the universe hierarchy. 13 | \end{compactitem} 14 | \end{multicols} 15 | 16 | \input{./content/misc/args.tex} 17 | \input{./content/misc/literate.tex} 18 | \input{./content/misc/ffi.tex} 19 | \input{./content/misc/type-providers.tex} 20 | \input{./content/misc/codegen.tex} 21 | \input{./content/misc/cumulativity.tex} 22 | 23 | -------------------------------------------------------------------------------- /content/modules.tex: -------------------------------------------------------------------------------- 1 | \section{Modules and Namespaces} 2 | \label{sect:namespaces} 3 | 4 | An \Idris{} program consists of a collection of modules. 5 | Each module includes an optional \texttt{module} declaration giving the name of the module, a list of \texttt{import} statements giving the other modules which are to be imported, and a collection of declarations and definitions of types, classes and functions. 6 | For example, Listing~\ref{bstmod} gives a module which defines a binary tree type \texttt{BTree} (in a file \texttt{btree.idr}) and Listing~\ref{bstmain} gives a main program (in a file \texttt{bmain.idr} which uses the \texttt{bst} module to sort a list. 7 | 8 | \inputIdrisListing[caption={Binary Tree Module}, label=bstmod, float=htp]{./examples/btree.idr} 9 | 10 | \inputIdrisListing[caption={Binary Tree Main Program}, label=bstmain, float=htp]{./examples/bmain.idr} 11 | 12 | The same names can be defined in multiple modules. 13 | This is possible because in practice names are \emph{qualified} with the name of the module. 14 | The names defined in the \texttt{btree} module are, in full: 15 | 16 | \begin{multicols}{2} 17 | \begin{compactitem} 18 | \item \texttt{btree.BTree}, 19 | \item \texttt{btree.Leaf}, 20 | \item \texttt{btree.Node}, 21 | \columnbreak 22 | \item \texttt{btree.insert}, 23 | \item \texttt{btree.toList}, 24 | \item \texttt{btree.toTree}. 25 | \end{compactitem} 26 | \end{multicols} 27 | 28 | \noindent 29 | If names are otherwise unambiguous, there is no need to give the fully qualified name. 30 | Names can be disambiguated either by giving an explicit qualification, or according to their type. 31 | 32 | There is no formal link between the module name and its filename, although it is generally advisable to use the same name for each. 33 | An \texttt{import} statement refers to a filename, using dots to separate directories. 34 | For example, \texttt{import foo.bar} would import the file \texttt{foo/bar.idr}, which would conventionally have the module declaration \texttt{module foo.bar}. 35 | The only requirement for module names is that the main module, with the \texttt{main} function, must be called \texttt{Main}---although its filename need not be \texttt{Main.idr}. 36 | 37 | \subsection{Export Modifiers} 38 | 39 | By default, all names defined in a module are exported for use by other modules. 40 | However, it is good practice only to export a minimal interface and keep internal details abstract. 41 | \Idris{} allows functions, types, and classes to be marked as: \texttt{public}, \texttt{abstract} or \texttt{private}: 42 | 43 | \begin{itemize} 44 | \item\texttt{public} means that both the name and definition are exported. 45 | For functions, this means that the implementation is exported (which means, for example, it can be used in a dependent type). 46 | For data types, this means that the type name and the constructors are exported. 47 | For classes, this means that the class name and method names are exported. 48 | 49 | \item\texttt{abstract} means that only the name is exported. 50 | For functions, this means that the implementation is not exported. 51 | For data types, this means that the type name is exported but not the constructors. 52 | For classes, this means that the class name is exported but not the method names. 53 | 54 | \item\texttt{private} means that neither the name nor the definition is exported. 55 | \end{itemize} 56 | 57 | \noindent 58 | \textbf{Note:} If any definition is given an export modifier, then all names with no modifier are assumed to be \texttt{private}. 59 | 60 | For our \texttt{btree} module, it makes sense for the tree data type and the functions to be exported as \texttt{abstract}, as we see in Listing~\ref{bstmodp}. 61 | 62 | \inputIdrisListing[caption={Binary Tree Module, with export modifiers}, label=bstmodp]{./examples/btreemod.idr} 63 | 64 | \noindent 65 | Finally, the default export mode can be changed with the \texttt{\%access} directive, for example: 66 | 67 | \begin{code} 68 | %access abstract 69 | \end{code} 70 | 71 | \noindent 72 | In this case, any function with no access modifier will be exported as \texttt{abstract}, rather than left \texttt{private}. 73 | 74 | Additionally, a module can re-export a module it has imported, by using the 75 | \texttt{public} modifier on an \texttt{import}. For example: 76 | 77 | \begin{code} 78 | module A 79 | 80 | import B 81 | import public C 82 | 83 | public a : AType 84 | a = ... 85 | \end{code} 86 | 87 | \noindent 88 | The module \texttt{A} will export the name \texttt{a}, as well as any 89 | public or abstract names in module \texttt{C}, but will not re-export 90 | anything from module \texttt{B}. 91 | 92 | \subsection{Explicit Namespaces} 93 | 94 | Defining a module also defines a namespace implicitly. 95 | However, namespaces can also be given \emph{explicitly}. 96 | This is most useful if you wish to overload names within the same module: 97 | 98 | \inputIdrisListing{./examples/foo.idr} 99 | 100 | \noindent 101 | This (admittedly contrived) module defines two functions with fully qualified names 102 | \texttt{foo.x.test} and \texttt{foo.y.test}, which can be disambiguated by their types: 103 | 104 | \begin{lstlisting}[style=stdout] 105 | *foo> test 3 106 | 6 : Int 107 | *foo> test "foo" 108 | "foofoo" : String 109 | \end{lstlisting} 110 | 111 | \subsection{Parameterised blocks} 112 | 113 | Groups of functions can be parameterised over a number of arguments using a \texttt{parameters} declaration, for example: 114 | 115 | \begin{code} 116 | parameters (x : Nat, y : Nat) 117 | addAll : Nat -> Nat 118 | addAll z = x + y + z 119 | \end{code} 120 | 121 | \noindent 122 | The effect of a \texttt{parameters} block is to add the declared parameters to every function, type and data constructor within the block. 123 | Outside the block, the parameters must be given explicitly: 124 | 125 | \begin{lstlisting}[style=stdout] 126 | *params> :t addAll 127 | addAll : Nat -> Nat -> Nat -> Nat 128 | \end{lstlisting} 129 | 130 | \noindent 131 | Parameters blocks can be nested, and can also include data declarations, in which case the parameters are added explicitly to all type and data constructors. 132 | They may also be dependent types with implicit arguments: 133 | 134 | \begin{code} 135 | parameters (y : Nat, xs : Vect x a) 136 | data Vects : Type -> Type where 137 | MkVects : Vect y a -> Vects a 138 | 139 | append : Vects a -> Vect (x + y) a 140 | append (MkVects ys) = xs ++ ys 141 | \end{code} 142 | 143 | \noindent 144 | To use \texttt{Vects} or \texttt{append} outside the block, we must also give the \texttt{xs} and \texttt{y} arguments. 145 | Here, we can use placeholders for the values which can be inferred by the type checker: 146 | 147 | \begin{lstlisting}[style=stdout] 148 | *params> show (append _ _ (MkVects _ [1,2,3] [4,5,6])) 149 | "[1, 2, 3, 4, 5, 6]" : String 150 | \end{lstlisting} 151 | -------------------------------------------------------------------------------- /content/provisional.tex: -------------------------------------------------------------------------------- 1 | \section{Provisional Definitions} 2 | \label{sect:provisional} 3 | 4 | Sometimes when programming with dependent types, the type required by the type checker and the type of the program we have written will be different (in that they do not have the same normal form), but nevertheless provably equal. 5 | For example, recall the \texttt{parity} function: 6 | 7 | \inputIdrisListing[lastline=6]{./examples/viewsbroken.idr} 8 | 9 | \noindent 10 | We'd like to implement this as follows: 11 | 12 | \inputIdrisListing[firstline=6]{./examples/viewsbroken.idr} 13 | 14 | \noindent 15 | This simply states that zero is even, one is odd, and recursively, the parity of \texttt{k+2} is the same as the parity of \texttt{k}. 16 | Explicitly marking the value of \texttt{n} is even and odd is necessary to help type inference. 17 | Unfortunately, the type checker rejects this: 18 | 19 | \begin{lstlisting}[style=stdout] 20 | viewsbroken.idr:12:10:When elaborating right hand side of ViewsBroken.parity: 21 | Can't unify 22 | Parity (plus (S j) (S j)) 23 | with 24 | Parity (S (S (plus j j))) 25 | 26 | Specifically: 27 | Can't unify 28 | plus (S j) (S j) 29 | with 30 | S (S (plus j j)) 31 | \end{lstlisting} 32 | 33 | \noindent 34 | The type checker is telling us that \texttt{(j+1)+(j+1)} and \texttt{2+j+j} do not normalise to the same value. 35 | This is because \texttt{plus} is defined by recursion on its first argument, and in the second value, there is a successor symbol on the second argument, so this will not help with reduction. 36 | These values are obviously equal --- how can we rewrite the program to fix this problem? 37 | 38 | \subsection{Provisional definitions} 39 | 40 | \emph{Provisional definitions} help with this problem by allowing us to defer the proof details until a later point. 41 | There are two main reasons why they are useful. 42 | 43 | \begin{itemize} 44 | \item When \emph{prototyping}, it is useful to be able to test programs before finishing all the details of proofs. 45 | \item When \emph{reading} a program, it is often much clearer to defer the proof details so that they do not distract the reader from the underlying algorithm. 46 | \end{itemize} 47 | 48 | \noindent 49 | Provisional definitions are written in the same way as ordinary definitions, except that they introduce the right hand side with a \texttt{?=} rather than \texttt{=}. 50 | We define \texttt{parity} as follows: 51 | 52 | \inputIdrisListing[firstline=7, lastline=12]{./examples/views.idr} 53 | 54 | \noindent 55 | When written in this form, instead of reporting a type error, \Idris{} will insert a metavariable standing for a theorem which will correct the type error. 56 | \Idris{} tells us we have two proof obligations, with names generated from the module and function names: 57 | 58 | \begin{lstlisting}[style=stdout] 59 | *views> :m 60 | Global metavariables: 61 | [views.parity_lemma_2,views.parity_lemma_1] 62 | \end{lstlisting} 63 | 64 | \noindent 65 | The first of these has the following type: 66 | 67 | \begin{lstlisting}[style=stdout] 68 | *views> :p views.parity_lemma_1 69 | 70 | ---------------------------------- (views.parity_lemma_1) -------- 71 | {hole0} : (j : Nat) -> (Parity (plus (S j) (S j))) -> Parity (S (S (plus j j))) 72 | 73 | -views.parity_lemma_1> 74 | \end{lstlisting} 75 | 76 | \noindent 77 | The two arguments are \texttt{j}, the variable in scope from the pattern match, and \texttt{value}, which is the value we gave in the right hand side of the provisional definition. 78 | Our goal is to rewrite the type so that we can use this value. 79 | We can achieve this using the following theorem from the prelude: 80 | 81 | \begin{code} 82 | plusSuccRightSucc : (left : Nat) -> (right : Nat) -> 83 | S (left + right) = left + (S right) 84 | \end{code} 85 | 86 | \noindent 87 | We need to use \texttt{compute} again to unfold the definition of \texttt{plus}: 88 | 89 | \begin{lstlisting}[style=stdout] 90 | -views.parity_lemma_1> compute 91 | 92 | 93 | ---------------------------------- (views.parity_lemma_1) -------- 94 | {hole0} : (j : Nat) -> (Parity (S (plus j (S j)))) -> Parity (S (S (plus j j))) 95 | \end{lstlisting} 96 | 97 | \noindent 98 | After applying \texttt{intros} we have: 99 | 100 | \begin{lstlisting}[style=stdout] 101 | -views.parity_lemma_1> intros 102 | 103 | j : Nat 104 | value : Parity (S (plus j (S j))) 105 | ---------------------------------- (views.parity_lemma_1) -------- 106 | {hole2} : Parity (S (S (plus j j))) 107 | \end{lstlisting} 108 | 109 | \noindent 110 | Then we apply the \texttt{plusSuccRightSucc} rewrite rule, symmetrically, to \texttt{j} and \texttt{j}, giving: 111 | 112 | \begin{lstlisting}[style=stdout] 113 | -views.parity_lemma_1> rewrite sym (plusSuccRightSucc j j) 114 | 115 | j : Nat 116 | value : Parity (S (plus j (S j))) 117 | ---------------------------------- (views.parity_lemma_1) -------- 118 | {hole3} : Parity (S (plus j (S j))) 119 | \end{lstlisting} 120 | 121 | \noindent 122 | \texttt{sym} is a function, defined in the library, which reverses the order of the rewrite: 123 | 124 | \begin{lstlisting}[style=stdout] 125 | sym : l = r -> r = l 126 | sym Refl = Refl 127 | \end{lstlisting} 128 | 129 | \noindent 130 | We can complete this proof using the \texttt{trivial} tactic, which finds \texttt{value} in the premises. 131 | The proof of the second lemma proceeds in exactly the same way. 132 | 133 | We can now test the \texttt{natToBin} function from Section~\ref{sect:nattobin} at the prompt. 134 | The number 42 is 101010 in binary. 135 | The binary digits are reversed: 136 | 137 | \begin{lstlisting}[style=stdout] 138 | *views> show (natToBin 42) 139 | "[False, True, False, True, False, True]" : String 140 | \end{lstlisting} 141 | 142 | 143 | \subsection{Suspension of Disbelief} 144 | 145 | \Idris{} requires that proofs be complete before compiling programs (although evaluation at the prompt is possible without proof details). 146 | Sometimes, especially when prototyping, it is easier not to have to do this. 147 | It might even be beneficial to test programs before attempting to prove things about them --- if testing finds an error, you know you had better not waste your time proving something! 148 | 149 | Therefore, \Idris{} provides a built-in coercion function, which allows you to use a value of the incorrect types: 150 | 151 | \begin{code} 152 | believe_me : a -> b 153 | \end{code} 154 | 155 | \noindent 156 | Obviously, this should be used with extreme caution. 157 | It is useful when prototyping, and can also be appropriate when asserting properties of external code (perhaps in an external C library). The ``proof'' of \texttt{views.parity\_lemma\_1} using this is: 158 | 159 | \begin{lstlisting}[style=stdout] 160 | views.parity_lemma_2 = proof { 161 | intro; 162 | intro; 163 | exact believe_me value; 164 | } 165 | \end{lstlisting} 166 | 167 | \noindent 168 | The \texttt{exact} tactic allows us to provide an exact value for the proof. 169 | In this case, we assert that the value we gave was correct. 170 | 171 | \subsection{Example: Binary numbers} 172 | 173 | Previously, we implemented conversion to binary numbers using the \texttt{Parity} view. 174 | Here, we show how to use the same view to implement a verified conversion to binary. 175 | We begin by indexing binary numbers over their \texttt{Nat} equivalent. 176 | This is a common pattern, linking a representation (in this case \texttt{Binary}) with a meaning (in this case \texttt{Nat}): 177 | 178 | \begin{code} 179 | data Binary : Nat -> Type where 180 | bEnd : Binary Z 181 | bO : Binary n -> Binary (n + n) 182 | bI : Binary n -> Binary (S (n + n)) 183 | \end{code} 184 | 185 | \noindent 186 | \texttt{bO} and \texttt{bI} take a binary number as an argument and effectively shift it one bit left, adding either a zero or one as the new least significant bit. 187 | The index, \texttt{n + n} or \texttt{S (n + n)} states the result that this left shift then add will have to the meaning of the number. 188 | This will result in a representation with the least significant bit at the front. 189 | 190 | Now a function which converts a Nat to binary will state, in the type, that the resulting binary number is a faithful representation of the original Nat: 191 | 192 | \begin{code} 193 | natToBin : (n:Nat) -> Binary n 194 | \end{code} 195 | 196 | \noindent 197 | The \texttt{Parity} view makes the definition fairly simple --- halving the number is effectively a right shift after all --- although we need to use a provisional definition in the odd case: 198 | 199 | \begin{code} 200 | natToBin : (n:Nat) -> Binary n 201 | natToBin Z = bEnd 202 | natToBin (S k) with (parity k) 203 | natToBin (S (j + j)) | even = bI (natToBin j) 204 | natToBin (S (S (j + j))) | odd ?= bO (natToBin (S j)) 205 | \end{code} 206 | 207 | \noindent 208 | The problem with the odd case is the same as in the definition of \texttt{parity}, and the proof proceeds in the same way: 209 | 210 | \begin{code} 211 | natToBin_lemma_1 = proof { 212 | intro; 213 | intro; 214 | rewrite sym (plusSuccRightSucc j j); 215 | trivial; 216 | } 217 | \end{code} 218 | 219 | \noindent 220 | To finish, we'll implement a main program which reads an integer from the user and outputs it in binary. 221 | 222 | \begin{code} 223 | main : IO () 224 | main = do putStr "Enter a number: " 225 | x <- getLine 226 | print (natToBin (fromInteger (cast x))) 227 | \end{code} 228 | 229 | \noindent 230 | For this to work, of course, we need a \texttt{Show} instance for \texttt{Binary n}: 231 | 232 | \begin{code} 233 | instance Show (Binary n) where 234 | show (bO x) = show x ++ "0" 235 | show (bI x) = show x ++ "1" 236 | show bEnd = "" 237 | \end{code} 238 | 239 | -------------------------------------------------------------------------------- /content/starting.tex: -------------------------------------------------------------------------------- 1 | \section{Getting Started} 2 | 3 | \subsection{Prerequisites} 4 | 5 | Before installing \Idris{}, you will need to make sure you have all of the necessary libraries and tools. 6 | You will need: 7 | 8 | \begin{itemize} 9 | \item A fairly recent Haskell platform. Version 2013.2.0.0 10 | should be sufficiently recent, though it is better to be completely up to 11 | date. 12 | \item The \emph{GNU Multiple Precision Arithmetic Library} (GMP) is available from MacPorts and all major Linux distributions. 13 | \end{itemize} 14 | 15 | \subsection{Downloading and Installing} 16 | 17 | The easiest way to install \Idris{}, if you have all of the prerequisites, is to type: 18 | 19 | \begin{lstlisting}[style=stdout] 20 | cabal update; cabal install idris 21 | \end{lstlisting} 22 | 23 | \noindent 24 | This will install the latest version released on Hackage, along with any dependencies. 25 | If, however, you would like the most up to date development version you can find it, as well as build intructions, on GitHub at: \url{https://github.com/edwinb/Idris-dev}. 26 | 27 | To check that installation has succeeded, and to write your first \Idris{} program, create a file called ``\texttt{hello.idr}'' containing the following text: 28 | 29 | \inputIdrisListing{./examples/hello.idr} 30 | 31 | \noindent 32 | If you are familiar with Haskell, it should be fairly clear what the program is doing and how it works, but if not, we will explain the details later. 33 | You can compile the program to an executable by entering \texttt{idris hello.idr -o hello} at the shell prompt. 34 | This will create an executable called \texttt{hello}, which you can run: 35 | 36 | \begin{lstlisting}[style=stdout] 37 | $ idris hello.idr -o hello 38 | $ ./hello 39 | Hello world 40 | \end{lstlisting} 41 | 42 | \noindent 43 | Note that the \texttt{\$} indicates the shell prompt! 44 | Should the \Idris{} executable not be found please ensure that you have added \verb!~/.cabal/bin! to your \verb!$PATH! environment variable. 45 | Mac OS X users may find they need to use \verb!~/Library/Haskell/bin! instead. 46 | Some useful options to the \Idris{} command are: 47 | 48 | \begin{itemize} 49 | \item \verb!-o prog! to compile to an executable called \texttt{prog}. 50 | \item \verb!--check! type check the file and its dependencies without starting the 51 | interactive environment. 52 | \item \verb!--help! display usage summary and command line options 53 | \end{itemize} 54 | 55 | \subsection{The Interactive Environment} 56 | 57 | Entering \texttt{idris} at the shell prompt starts up the interactive environment. 58 | You should see something like the following: 59 | 60 | \begin{lstlisting}[style=stdout] 61 | $ idris 62 | ____ __ _ 63 | / _/___/ /____(_)____ 64 | / // __ / ___/ / ___/ Version ^\version{}^ 65 | _/ // /_/ / / / (__ ) http://www.idris-lang.org/ 66 | /___/\__,_/_/ /_/____/ Type :? for help 67 | 68 | Idris> 69 | \end{lstlisting} 70 | 71 | \noindent 72 | This gives a \texttt{ghci}-style interface which allows evaluation of, as well as type checking of, expressions; theorem proving, compilation; editing; and various other operations. 73 | The command \texttt{:?} gives a list of supported commands. 74 | Listing~\ref{run1} shows an example run in which \texttt{hello.idr} is loaded, the type of \texttt{main} is checked and then the program is compiled to the executable \texttt{hello}. 75 | Type checking a file, if successful, creates a bytecode version of the file (in this case \texttt{hello.ibc}) to speed up loading in future. 76 | The bytecode is regenerated if the source file changes. 77 | 78 | \begin{lstlisting}[caption={Sample Interactive Run}, label=run1, style=stdout, float=htp] 79 | $ idris hello.idr 80 | ____ __ _ 81 | / _/___/ /____(_)____ 82 | / // __ / ___/ / ___/ Version ^\version{}^ 83 | _/ // /_/ / / / (__ ) http://www.idris-lang.org/ 84 | /___/\__,_/_/ /_/____/ Type :? for help 85 | 86 | Type checking ./hello.idr 87 | *hello> :t main 88 | Main.main : IO () 89 | *hello> :c hello 90 | *hello> :q 91 | Bye bye 92 | $ ./hello 93 | Hello world 94 | \end{lstlisting} 95 | 96 | -------------------------------------------------------------------------------- /content/syntax.tex: -------------------------------------------------------------------------------- 1 | \section{Syntax Extensions} 2 | 3 | \Idris{} supports the implementation of \emph{Embedded Domain Specific Languages} (EDSLs) in several ways~\cite{res-dsl-padl12}. 4 | One way, as we have already seen, is through extending \texttt{do} notation. 5 | Another important way is to allow extension of the core syntax. 6 | In this section we describe two ways of extending the syntax: \texttt{syntax} rules and \texttt{dsl} notation. 7 | 8 | \input{./content/syntax/rules.tex} 9 | \input{./content/syntax/dsl.tex} 10 | 11 | -------------------------------------------------------------------------------- /content/syntax/dsl.tex: -------------------------------------------------------------------------------- 1 | \subsection{\texttt{dsl} notation} 2 | 3 | The well-typed interpreter in Section~\ref{sect:interp} is a simple example of a common programming pattern with dependent types. 4 | Namely: describe an \emph{object language} and its type system with dependent types to guarantee that only well-typed programs can be represented, then program using that representation. 5 | Using this approach we can, for example, write programs for serialising binary data~\cite{plpv11} or running concurrent processes safely~\cite{cbconc-fi}. 6 | 7 | Unfortunately, the form of object language programs makes it rather hard to program this way in practice. 8 | Recall the factorial program in \texttt{Expr} for example: 9 | 10 | \begin{code} 11 | fact : Expr G (TyFun TyInt TyInt) 12 | fact = Lam (If (Op (==) (Var Stop) (Val 0)) 13 | (Val 1) (Op (*) (app fact (Op (-) (Var Stop) (Val 1))) 14 | (Var Stop))) 15 | \end{code} 16 | 17 | \noindent 18 | Since this is a particularly useful pattern, \Idris{} provides syntax overloading~\cite{res-dsl-padl12} to make it easier to program in such object languages: 19 | 20 | \begin{code} 21 | mkLam : TTName -> Expr (t::g) t' -> Expr g (TyFun t t') 22 | mkLam _ body = Lam body 23 | 24 | dsl expr 25 | variable = Var 26 | index_first = Stop 27 | index_next = Pop 28 | lambda = mkLam 29 | \end{code} 30 | 31 | \noindent 32 | A \texttt{dsl} block describes how each syntactic construct is represented in an object language. 33 | Here, in the \texttt{expr} language, any variable is translated to the \texttt{Var} constructor, using \texttt{Pop} and \texttt{Stop} to construct the de Bruijn index (i.e., to count how many bindings since the variable itself was bound); and any \Idris{} lambda is translated to a \texttt{Lam} constructor. 34 | The \texttt{mkLam} function simply ignores its first argument, which is the name that the user chose for the variable. 35 | It is also possible to overload \texttt{let} and dependent function syntax (\texttt{pi}) in this way. 36 | We can now write \texttt{fact} as follows: 37 | 38 | \begin{code} 39 | fact : Expr G (TyFun TyInt TyInt) 40 | fact = expr (\x => If (Op (==) x (Val 0)) 41 | (Val 1) (Op (*) (app fact (Op (-) x (Val 1))) x)) 42 | \end{code} 43 | 44 | \noindent 45 | In this new version, \texttt{expr} declares that the next expression will be overloaded. 46 | We can take this further, using idiom brackets, by declaring: 47 | 48 | \begin{code} 49 | (<$>) : (f : Lazy (Expr G (TyFun a t))) -> Expr G a -> Expr G t 50 | (<$>) f a = App f a 51 | 52 | pure : Expr G a -> Expr G a 53 | pure = id 54 | \end{code} 55 | 56 | \noindent 57 | Note that there is no need for these to be part of an instance of \texttt{Applicative}, since idiom bracket notation translates directly to the names \texttt{<*>} and \texttt{pure}, and ad-hoc type-directed overloading is allowed. 58 | We can now say: 59 | 60 | \begin{code} 61 | fact : Expr G (TyFun TyInt TyInt) 62 | fact = expr (\x => If (Op (==) x (Val 0)) 63 | (Val 1) (Op (*) [| fact (Op (-) x (Val 1)) |] x)) 64 | \end{code} 65 | 66 | \noindent 67 | With some more ad-hoc overloading and type class instances, and a new syntax rule, we can even go as far as: 68 | 69 | \begin{code} 70 | syntax "IF" [x] "THEN" [t] "ELSE" [e] = If x t e 71 | 72 | fact : Expr G (TyFun TyInt TyInt) 73 | fact = expr (\x => IF x == 0 THEN 1 ELSE [| fact (x - 1) |] * x) 74 | \end{code} 75 | -------------------------------------------------------------------------------- /content/syntax/rules.tex: -------------------------------------------------------------------------------- 1 | \subsection{\texttt{syntax} rules} 2 | 3 | We have seen \texttt{if...then...else} expressions, but these are not built in. 4 | Instead, we can define a function in the prelude as follows (we have already 5 | seen this function in Section~\ref{sect:lazy}: 6 | 7 | \begin{code} 8 | boolCase : (x:Bool) -> Lazy a -> Lazy a -> a; 9 | boolCase True t e = t; 10 | boolCase False t e = e; 11 | \end{code} 12 | 13 | \noindent 14 | and then extend the core syntax with a \texttt{syntax} declaration: 15 | 16 | \begin{code} 17 | syntax "if" [test] "then" [t] "else" [e] = boolCase test t e; 18 | \end{code} 19 | 20 | \noindent 21 | The left hand side of a \texttt{syntax} declaration describes the syntax rule, and the right hand side describes its expansion. 22 | The syntax rule itself consists of: 23 | 24 | \begin{itemize} 25 | \item \textbf{Keywords} --- here, \texttt{if}, \texttt{then} and \texttt{else}, which must be valid identifiers 26 | \item \textbf{Non-terminals} --- included in square brackets, \texttt{[test]}, \texttt{[t]} and \texttt{[e]} here, which stand for arbitrary expressions. 27 | To avoid parsing ambiguities, these expressions cannot use syntax extensions at the top level (though they can be used in parentheses). 28 | \item \textbf{Names} --- included in braces, which stand for names which may be bound on the right hand side. 29 | \item \textbf{Symbols} --- included in quotations marks, e.g. \texttt{":="}. 30 | This can also be used to include reserved words in syntax rules, such as \texttt{"let"} or \texttt{"in"}. 31 | \end{itemize} 32 | 33 | \noindent 34 | The limitations on the form of a syntax rule are that it must include at least one symbol or keyword, and there must be no repeated variables standing for non-terminals. 35 | Any expression can be used, but if there are two non-terminals in a row in a rule, only simple expressions may be used (that is, variables, constants, or bracketed expressions). 36 | Rules can use previously defined rules, but may not be recursive. 37 | The following syntax extensions would therefore be valid: 38 | 39 | \begin{code} 40 | syntax [var] ":=" [val] = Assign var val; 41 | syntax [test] "?" [t] ":" [e] = if test then t else e; 42 | syntax "select" [x] "from" [t] "where" [w] = SelectWhere x t w; 43 | syntax "select" [x] "from" [t] = Select x t; 44 | \end{code} 45 | 46 | \noindent 47 | Syntax macros can be further restricted to apply only in patterns (i.e., only on the left hand side of a pattern match clause) or only in terms (i.e.\ everywhere but the left hand side of a pattern match clause) by being marked as \texttt{pattern} or \texttt{term} syntax rules. 48 | For example, we might define an interval as follows, with a static check that the lower bound is below the upper bound using \texttt{so}: 49 | 50 | \begin{code} 51 | data Interval : Type where 52 | MkInterval : (lower : Float) -> (upper : Float) -> 53 | so (lower < upper) -> Interval 54 | \end{code} 55 | 56 | \noindent 57 | We can define a syntax which, in patterns, always matches \texttt{oh} for the proof argument, and in terms requires a proof term to be provided: 58 | 59 | \begin{code} 60 | pattern syntax "[" [x] "..." [y] "]" = MkInterval x y oh 61 | term syntax "[" [x] "..." [y] "]" = MkInterval x y ?bounds_lemma 62 | \end{code} 63 | 64 | \noindent 65 | In terms, the syntax \texttt{[x...y]} will generate a proof obligation \texttt{bounds\_lemma} (possibly renamed). 66 | 67 | Finally, syntax rules may be used to introduce alternative binding forms. 68 | For example, a \texttt{for} loop binds a variable on each iteration: 69 | 70 | \begin{code} 71 | syntax "for" {x} "in" [xs] ":" [body] = forLoop xs (\x => body) 72 | 73 | main : IO () 74 | main = do for x in [1..10]: 75 | putStrLn ("Number " ++ show x) 76 | putStrLn "Done!" 77 | \end{code} 78 | 79 | \noindent 80 | Note that we have used the \texttt{\{x\}} form to state that \texttt{x} represents a bound variable, substituted on the right hand side. 81 | We have also put \texttt{"in"} in quotation marks since it is already a reserved word. 82 | 83 | -------------------------------------------------------------------------------- /content/theorems.tex: -------------------------------------------------------------------------------- 1 | \section{Theorem Proving} 2 | 3 | \subsection{Equality} 4 | 5 | \Idris{} allows propositional equalities to be declared, allowing theorems about 6 | programs to be stated and proved. 7 | Equality is built in, but conceptually has the following definition: 8 | 9 | \begin{code} 10 | data (=) : a -> b -> Type where 11 | Refl : x = x 12 | \end{code} 13 | 14 | \noindent 15 | Equalities can be proposed between any values of any types, but the only way to construct a proof of equality is if values actually are equal. 16 | For example: 17 | 18 | \begin{code} 19 | fiveIsFive : 5 = 5 20 | fiveIsFive = Refl 21 | 22 | twoPlusTwo : 2 + 2 = 4 23 | twoPlusTwo = Refl 24 | \end{code} 25 | 26 | \subsection{The Empty Type} 27 | 28 | \label{sect:empty} 29 | 30 | There is an empty type, $\bot$, which has no constructors. 31 | It is therefore impossible to construct an element of the empty type, at least without using a partially defined or general recursive function (see Section~\ref{sect:totality} for more details). 32 | We can therefore use the empty type to prove that something is impossible, for example zero is never equal to a successor: 33 | 34 | \begin{code} 35 | disjoint : (n : Nat) -> Z = S n -> Void 36 | disjoint n p = replace {P = disjointTy} p () 37 | where 38 | disjointTy : Nat -> Type 39 | disjointTy Z = () 40 | disjointTy (S k) = Void 41 | \end{code} 42 | 43 | \noindent 44 | There is no need to worry too much about how this function works --- essentially, it applies the library function \texttt{replace}, which uses an equality proof to transform a predicate. 45 | Here we use it to transform a value of a type which can exist, the empty tuple, to a value of a type which can't, by using a proof of something which can't exist. 46 | 47 | Once we have an element of the empty type, we can prove anything. 48 | \texttt{void} is defined in the library, to assist with proofs by contradiction. 49 | 50 | \begin{code} 51 | void : Void -> a 52 | \end{code} 53 | 54 | \subsection{Simple Theorems} 55 | 56 | When type checking dependent types, the type itself gets \emph{normalised}. 57 | So imagine we want to prove the following theorem about the reduction behaviour of \texttt{plus}: 58 | 59 | \begin{code} 60 | plusReduces : (n:Nat) -> plus Z n = n 61 | \end{code} 62 | 63 | \noindent 64 | We've written down the statement of the theorem as a type, in just the same way as we would write the type of a program. 65 | In fact there is no real distinction between proofs and programs. 66 | A proof, as far as we are concerned here, is merely a program with a precise enough type to guarantee a particular property of interest. 67 | 68 | We won't go into details here, but the Curry-Howard correspondence~\cite{howard} explains this relationship. 69 | The proof itself is trivial, because \texttt{plus Z n} normalises to \texttt{n} by the definition of \texttt{plus}: 70 | 71 | \begin{code} 72 | plusReduces n = Refl 73 | \end{code} 74 | 75 | \noindent 76 | It is slightly harder if we try the arguments the other way, because plus is defined by recursion on its first argument. 77 | The proof also works by recursion on the first argument to \texttt{plus}, namely \texttt{n}. 78 | 79 | \begin{code} 80 | plusReducesZ : (n:Nat) -> n = plus n Z 81 | plusReducesZ Z = Refl 82 | plusReducesZ (S k) = cong (plusReducesZ k) 83 | \end{code} 84 | 85 | \noindent 86 | \texttt{cong} is a function defined in the library which states that equality respects function application: 87 | 88 | \begin{code} 89 | cong : {f : t -> u} -> a = b -> f a = f b 90 | \end{code} 91 | 92 | \noindent 93 | We can do the same for the reduction behaviour of plus on successors: 94 | 95 | \begin{code} 96 | plusReducesS : (n:Nat) -> (m:Nat) -> S (plus n m) = plus n (S m) 97 | plusReducesS Z m = Refl 98 | plusReducesS (S k) m = cong (plusReducesS k m) 99 | \end{code} 100 | 101 | \noindent 102 | Even for trival theorems like these, the proofs are a little tricky to construct in one go. 103 | When things get even slightly more complicated, it becomes too much to think about to construct proofs in this `batch mode'. 104 | \Idris{} therefore provides an interactive proof mode. 105 | 106 | \subsection{Interactive theorem proving} 107 | 108 | Instead of writing the proof in one go, we can use \Idris{}'s interactive proof mode. To do this, we write the general \emph{structure} of the proof, and use the interactive mode to complete the details. 109 | We'll be constructing the proof by \emph{induction}, so we write the cases for \texttt{Z} and \texttt{S}, with a recursive call in the \texttt{S} case giving the inductive hypothesis, and insert \emph{metavariables} for the rest of the definition: 110 | 111 | \begin{code} 112 | plusReducesZ' : (n:Nat) -> n = plus n Z 113 | plusReducesZ' Z = ?plusredZ_Z 114 | plusReducesZ' (S k) = let ih = plusReducesZ' k in 115 | ?plusredZ_S 116 | \end{code} 117 | 118 | \noindent 119 | On running \Idris{}, two global names are created, \texttt{plusredZ\_Z} and \texttt{plusredZ\_S}, with no definition. 120 | We can use the \texttt{:m} command at the prompt to find out which metavariables are still to be solved (or, more precisely, which functions exist but have no definitions), then the \texttt{:t} command to see their types: 121 | 122 | \begin{lstlisting}[style=stdout] 123 | *theorems> :m 124 | Global metavariables: 125 | [plusredZ_S,plusredZ_Z] 126 | 127 | \end{lstlisting} 128 | 129 | \begin{lstlisting}[style=stdout] 130 | *theorems> :t plusredZ_Z 131 | plusredZ_Z : Z = plus Z Z 132 | 133 | *theorems> :t plusredZ_S 134 | plusredZ_S : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z 135 | \end{lstlisting} 136 | 137 | \noindent 138 | The \texttt{:p} command enters interactive proof mode, which can be used to complete the missing definitions. 139 | 140 | \begin{lstlisting}[style=stdout] 141 | *theorems> :p plusredZ_Z 142 | 143 | ---------------------------------- (plusredZ_Z) -------- 144 | {hole0} : Z = plus Z Z 145 | \end{lstlisting} 146 | 147 | \noindent 148 | This gives us a list of premises (above the line; there are none here) and the current goal (below the line; named \texttt{\{hole0\}} here). 149 | At the prompt we can enter tactics to direct the construction of the proof. 150 | In this case, we can normalise the goal with the \texttt{compute} tactic: 151 | 152 | \begin{lstlisting}[style=stdout] 153 | -plusredZ_Z> compute 154 | 155 | ---------------------------------- (plusredZ_Z) -------- 156 | {hole0} : Z = Z 157 | \end{lstlisting} 158 | 159 | \noindent 160 | Now we have to prove that \texttt{Z} equals \texttt{Z}, which is easy to prove by \texttt{Refl}. 161 | To apply a function, such as \texttt{Refl}, we use \texttt{refine} which introduces subgoals for each of the function's explicit arguments (\texttt{Refl} has none): 162 | 163 | \begin{lstlisting}[style=stdout] 164 | -plusredZ_Z> refine Refl 165 | plusredZ_Z: no more goals 166 | \end{lstlisting} 167 | 168 | \noindent 169 | Here, we could also have used the \texttt{trivial} tactic, which tries to refine by \texttt{Refl}, and if that fails, tries to refine by each name in the local context. 170 | When a proof is complete, we use the \texttt{qed} tactic to add the proof to the global context, and remove the metavariable from the unsolved metavariables list. 171 | This also outputs a trace of the proof: 172 | 173 | \begin{code} 174 | -plusredZ_Z> qed 175 | plusredZ_Z = proof 176 | compute 177 | refine Refl 178 | \end{code} 179 | 180 | \begin{lstlisting}[style=stdout] 181 | *theorems> :m 182 | Global metavariables: 183 | [plusredZ_S] 184 | \end{lstlisting} 185 | 186 | \noindent 187 | The \texttt{:addproof} command, at the interactive prompt, will add the proof to the source file (effectively in an appendix). 188 | Let us now prove the other required lemma, \texttt{plusredZ\_S}: 189 | 190 | \begin{lstlisting}[style=stdout] 191 | *theorems> :p plusredZ_S 192 | 193 | ---------------------------------- (plusredZ_S) -------- 194 | {hole0} : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z 195 | \end{lstlisting} 196 | 197 | \noindent 198 | In this case, the goal is a function type, using \texttt{k} (the argument accessible by pattern matching) and \texttt{ih} --- the local variable containing the result of the recursive call. 199 | We can introduce these as premisses using the \texttt{intro} tactic twice (or \texttt{intros}, which introduces all arguments as premisses). 200 | This gives: 201 | 202 | \begin{lstlisting}[style=stdout] 203 | k : Nat 204 | ih : k = plus k Z 205 | ---------------------------------- (plusredZ_S) -------- 206 | {hole2} : S k = plus (S k) Z 207 | \end{lstlisting} 208 | 209 | \noindent 210 | Since plus is defined by recursion on its first argument, the term \texttt{plus (S k) Z} in the goal can be simplified, so we use \texttt{compute}. 211 | 212 | \begin{lstlisting}[style=stdout] 213 | k : Nat 214 | ih : k = plus k Z 215 | ---------------------------------- (plusredZ_S) -------- 216 | {hole2} : S k = S (plus k Z) 217 | \end{lstlisting} 218 | 219 | \noindent 220 | We know, from the type of \texttt{ih}, that \texttt{k = plus k Z}, so we would like to use this knowledge to replace \texttt{plus k Z} in the goal with \texttt{k}. 221 | We can achieve this with the \texttt{rewrite} tactic: 222 | 223 | \begin{lstlisting}[style=stdout] 224 | -plusredZ_S> rewrite ih 225 | 226 | k : Nat 227 | ih : k = plus k Z 228 | ---------------------------------- (plusredZ_S) -------- 229 | {hole3} : S k = S k 230 | 231 | -plusredZ_S> 232 | \end{lstlisting} 233 | 234 | \noindent 235 | The \texttt{rewrite} tactic takes an equality proof as an argument, and tries to rewrite the goal using that proof. Here, it results in an equality which is trivially provable: 236 | 237 | \begin{lstlisting}[style=stdout] 238 | -plusredZ_S> trivial 239 | plusredZ_S: no more goals 240 | -plusredZ_S> qed 241 | plusredZ_S = proof { 242 | intros; 243 | rewrite ih; 244 | trivial; 245 | } 246 | \end{lstlisting} 247 | 248 | \noindent 249 | Again, we can add this proof to the end of our source file using the \texttt{:addproof} command at the interactive prompt. 250 | 251 | \subsection{Totality Checking} 252 | \label{sect:totality} 253 | 254 | If we really want to trust our proofs, it is important that they are defined by \emph{total} functions --- that is, a function which is defined for all possible inputs and is guaranteed to terminate. 255 | Otherwise we could construct an element of the empty type, from which we could prove anything: 256 | 257 | \begin{code} 258 | -- making use of 'hd' being partially defined 259 | empty1 : Void 260 | empty1 = hd [] where 261 | hd : List a -> a 262 | hd (x :: xs) = x 263 | 264 | -- not terminating 265 | empty2 : Void 266 | empty2 = empty2 267 | \end{code} 268 | 269 | \noindent 270 | Internally, \Idris{} checks every definition for totality, and we can check at the prompt with the \texttt{:total} command. 271 | We see that neither of the above definitions is total: 272 | 273 | \begin{lstlisting}[style=stdout] 274 | *theorems> :total empty1 275 | possibly not total due to: empty1#hd 276 | not total as there are missing cases 277 | *theorems> :total empty2 278 | possibly not total due to recursive path empty2 279 | \end{lstlisting} 280 | 281 | \noindent 282 | Note the use of the word ``possibly'' --- a totality check can, of course, never be certain due to the undecidability of the halting problem. 283 | The check is, therefore, conservative. 284 | It is also possible (and indeed advisable, in the case of proofs) to mark functions as total so that it will be a compile time error for the totality check to fail: 285 | 286 | \begin{lstlisting}[style=stdout] 287 | total empty2 : Void 288 | empty2 = empty2 289 | 290 | Type checking ./theorems.idr 291 | theorems.idr:25:empty2 is possibly not total due to recursive path empty2 292 | \end{lstlisting} 293 | 294 | \noindent 295 | Reassuringly, our proof in Section~\ref{sect:empty} that the zero and successor constructors are disjoint is total: 296 | 297 | \begin{lstlisting}[style=stdout] 298 | *theorems> :total disjoint 299 | Total 300 | \end{lstlisting} 301 | 302 | \noindent 303 | The totality check is, necessarily, conservative. 304 | To be recorded as total, a function \texttt{f} must: 305 | 306 | \begin{itemize} 307 | \item Cover all possible inputs 308 | \item Be \emph{well-founded} --- i.e. by the time a sequence of (possibly mutually) recursive calls reaches \texttt{f} again, it must be possible to show that one of its arguments has decreased. 309 | \item Not use any data types which are not \emph{strictly positive} 310 | \item Not call any non-total functions 311 | \end{itemize} 312 | 313 | \subsubsection{Directives and Compiler Flags for Totality} 314 | 315 | By default, \Idris{} allows all definitions, whether total or not. 316 | However, it is desirable for functions to be total as far as possible, as this provides a guarantee that they provide a result for all possible inputs, in finite time. It is possible to make total functions a requirement, either: 317 | 318 | \begin{itemize} 319 | \item By using the \verb!--total! compiler flag. 320 | \item By adding a \texttt{\%default total} directive to a source file. 321 | All definitions after this will be required to be total, unless explicitly flagged as \texttt{partial}. 322 | \end{itemize} 323 | 324 | \noindent 325 | All functions \emph{after} a \texttt{\%default total} declaration are required to be total. 326 | Correspondingly, after a \texttt{\%default partial} declaration, the requirement is relaxed. 327 | 328 | Finally, the compiler flag \verb!--warnpartial! causes \Idris{} to print a warning for any undeclared partial function. 329 | 330 | \subsubsection{Totality checking issues} 331 | 332 | Please note that the totality checker is not perfect! Firstly, it is necessarily 333 | conservative due to the undecidability of the halting problem, so many programs 334 | which \emph{are} total will not be detected as such. Secondly, the current 335 | implementation has had limited effort put into it so far, so there may still 336 | be cases where it believes a function is total which is not. Do not rely on it 337 | for your proofs yet! 338 | 339 | \subsubsection{Hints for totality} 340 | 341 | In cases where you believe a program is total, but \Idris{} does not agree, 342 | it is possible to give hints to the checker to give more detail for a 343 | termination argument. The checker works by ensuring that all chains of 344 | recursive calls eventually lead to one of the arguments decreasing towards 345 | a base case, but sometimes this is hard to spot. For example, the following 346 | definition cannot be checked as \texttt{total} because the checker cannot 347 | decide that \texttt{filter (<= x) xs} will always be smaller than \texttt{(x :: xs)}: 348 | 349 | \begin{code} 350 | qsort : Ord a => List a -> List a 351 | qsort [] = [] 352 | qsort (x :: xs) 353 | = qsort (filter (< x) xs) ++ 354 | (x :: qsort (filter (>= x) xs)) 355 | \end{code} 356 | 357 | \noindent 358 | The function \texttt{assert\_smaller}, defined in the Prelude, 359 | is intended to address this problem: 360 | 361 | \begin{code} 362 | assert_smaller : a -> a -> a 363 | assert_smaller x y = y 364 | \end{code} 365 | 366 | \noindent 367 | It simply evaluates to its second argument, but also asserts to the totality 368 | checker that \texttt{y} is structurally smaller than \texttt{x}. This can be 369 | used to explain the reasoning for totality if the checker cannot work it out 370 | itself. The above example can now be written as: 371 | 372 | \begin{code} 373 | total 374 | qsort : Ord a => List a -> List a 375 | qsort [] = [] 376 | qsort (x :: xs) 377 | = qsort (assert_smaller (x :: xs) (filter (< x) xs)) ++ 378 | (x :: qsort (assert_smaller (x :: xs) (filter (>= x) xs))) 379 | \end{code} 380 | 381 | \noindent 382 | The expression \texttt{assert\_smaller (x :: xs) (filter (<= x) xs)} asserts 383 | that the result of the filter will always be smaller than the pattern 384 | \texttt{(x :: xs)}. 385 | 386 | In more extreme cases, the function \texttt{assert\_total} marks a 387 | subexpression as always being total: 388 | 389 | \begin{code} 390 | assert_total : a -> a 391 | assert_total x = x 392 | \end{code} 393 | 394 | \noindent 395 | In general, this function should be avoided, but it can be very useful when 396 | reasoning about primitives or externally defined functions (for example from 397 | a C library) where totality can be shown by an external argument. 398 | -------------------------------------------------------------------------------- /content/typesfuns.tex: -------------------------------------------------------------------------------- 1 | \section{Types and Functions} 2 | 3 | \subsection{Primitive Types} 4 | 5 | \Idris{} defines several primitive types: \tTC{Int}, \tTC{Integer} and \tTC{Float} for numeric operations, \tTC{Char} and \tTC{String} for text manipulation, and \tTC{Ptr} which represents foreign pointers. 6 | There are also several data types declared in the library, including \tTC{Bool}, with values \tDC{True} and \tDC{False}. 7 | We can declare some constants with these types. 8 | Enter the following into a file \texttt{prims.idr} and load it into the \Idris{} interactive environment by typing \texttt{idris prims.idr}: 9 | 10 | \inputIdrisListing{./examples/prims.idr} 11 | 12 | \noindent 13 | An \Idris{} file consists of an optional module declaration (here \texttt{module prims}) followed by an optional list of imports (none here, however \Idris{} programs can consist of several modules, and the definitions in each module each have their own namespace, as we will discuss in Section~\ref{sect:namespaces}) and a collection of declarations and definitions. 14 | The order of definitions is significant --- functions and data types must be defined before use. 15 | Each definition must have a type declaration, for example see \texttt{x : Int}, \texttt{foo : String}, from the above listing. 16 | Indentation is significant --- a new declaration begins at the same level of indentation as the preceding declaration. 17 | Alternatively, declarations may be terminated with a semicolon. 18 | 19 | A library module \texttt{prelude} is automatically imported by every \Idris{} program, including facilities for IO, arithmetic, data structures and various common functions. 20 | The prelude defines several arithmetic and comparison operators, which we can use at the prompt. Evaluating things at the prompt gives an answer, and the type of the answer. 21 | For example: 22 | 23 | \begin{lstlisting}[style=stdout] 24 | *prims> 6*6+6 25 | 42 : Int 26 | *prims> x == 6*6+6 27 | True : Bool 28 | \end{lstlisting} 29 | 30 | \noindent 31 | All of the usual arithmetic and comparison operators are defined for the primitive types. 32 | They are overloaded using type classes, as we will discuss in Section~\ref{sec:classes} and can be extended to work on user defined types. 33 | Boolean expressions can be tested with the \texttt{if...then...else} construct: 34 | 35 | \begin{lstlisting}[style=stdout] 36 | *prims> if x == 6 * 6 + 6 then "The answer!" else "Not the answer" 37 | "The answer!" : String 38 | \end{lstlisting} 39 | 40 | \subsection{Data Types} 41 | 42 | Data types are declared in a similar way to Haskell data types, with a similar syntax. 43 | Natural numbers and lists, for example, can be declared as follows: 44 | 45 | \begin{code} 46 | data Nat = Z | S Nat -- Natural numbers 47 | -- (zero and successor) 48 | data List a = Nil | (::) a (List a) -- Polymorphic lists 49 | \end{code} 50 | 51 | \noindent 52 | The above declarations are taken from the standard library. 53 | Unary natural numbers can be either zero (\texttt{Z}), or the successor of another natural number (\texttt{S k}). 54 | Lists can either be empty (\texttt{Nil}) or a value added to the front of another list (\texttt{x :: xs}). 55 | In the declaration for \tTC{List}, we used an infix operator \tDC{::}. 56 | New operators such as this can be added using a fixity declaration, as follows: 57 | 58 | \begin{code} 59 | infixr 10 :: 60 | \end{code} 61 | 62 | \noindent 63 | Functions, data constructors and type constructors may all be given infix operators as names. 64 | They may be used in prefix form if enclosed in brackets, e.g.\ \tDC{(::)}. 65 | Infix operators can use any of the symbols: 66 | 67 | \begin{lstlisting}[style=stdout] 68 | :+-*/=_.?|&> Nat -> Nat 80 | plus Z y = y 81 | plus (S k) y = S (plus k y) 82 | 83 | -- Unary multiplication 84 | mult : Nat -> Nat -> Nat 85 | mult Z y = Z 86 | mult (S k) y = plus y (mult k y) 87 | \end{code} 88 | 89 | \noindent 90 | The standard arithmetic operators \texttt{+} and \texttt{*} are also overloaded for use by \texttt{Nat}, and are implemented using the above functions. 91 | Unlike Haskell, there is no restriction on whether types and function names must begin with a capital letter or not. 92 | Function names (\tFN{plus} and \tFN{mult} above), data constructors (\tDC{Z}, \tDC{S}, \tDC{Nil} and \tDC{::}) and type constructors (\tTC{Nat} and \tTC{List}) are all part of the same namespace. 93 | We can test these functions at the \Idris{} prompt: 94 | 95 | \begin{lstlisting}[style=stdout] 96 | Idris> plus (S (S Z)) (S (S Z)) 97 | 4 : Nat 98 | Idris> mult (S (S (S Z))) (plus (S (S Z)) (S (S Z))) 99 | 12 : Nat 100 | \end{lstlisting} 101 | 102 | \noindent 103 | \textbf{Note:} \Idris{} automatically desugars the \texttt{Nat} representation into a more human readable format. The result of \verb!plus (S (S Z)) (S (S Z))! is actually \verb!(S (S (S (S Z))))! which is the Integer 4. This can be checked at the \Idris{} prompt: 104 | 105 | \begin{lstlisting}[style=stdout] 106 | Idris> (S (S (S (S Z)))) 107 | 4 : Nat 108 | \end{lstlisting} 109 | 110 | \noindent 111 | Like arithmetic operations, integer literals are also overloaded using type classes, meaning that we can also test the functions as follows: 112 | 113 | \begin{lstlisting}[style=stdout] 114 | Idris> plus 2 2 115 | 4 : Nat 116 | Idris> mult 3 (plus 2 2) 117 | 12 : Nat 118 | \end{lstlisting} 119 | 120 | \noindent 121 | You may wonder, by the way, why we have unary natural numbers when our computers have perfectly good integer arithmetic built in. 122 | The reason is primarily that unary numbers have a very convenient structure which is easy to reason about, and easy to relate to other data structures as we will see later. 123 | Nevertheless, we do not want this convenience to be at the expense of efficiency. 124 | Fortunately, \Idris{} knows about the relationship between \tTC{Nat} (and similarly structured types) and numbers. This means it can optimise the representation, and functions such as \tFN{plus} and \tFN{mult}. 125 | 126 | \subsubsection*{\texttt{where} clauses} 127 | 128 | Functions can also be defined \emph{locally} using \texttt{where} clauses. 129 | For example, to define a function which reverses a list, we can use an auxiliary function which accumulates the new, reversed list, and which does not need to be visible globally: 130 | 131 | \begin{code} 132 | reverse : List a -> List a 133 | reverse xs = revAcc [] xs where 134 | revAcc : List a -> List a -> List a 135 | revAcc acc [] = acc 136 | revAcc acc (x :: xs) = revAcc (x :: acc) xs 137 | \end{code} 138 | 139 | \noindent 140 | Indentation is significant --- functions in the \texttt{where} block must be indented further than the outer function. 141 | 142 | \textbf{Scope:} 143 | Any names which are visible in the outer scope are also visible in the \texttt{where} clause (unless they have been redefined, such as \texttt{xs} here). 144 | A name which appears only in the type will be in scope in the \texttt{where} clause if it is a \emph{parameter} to one of the types, i.e.\ it is fixed across the entire structure. 145 | 146 | As well as functions, \texttt{where} blocks can include local data declarations, such as the following where \texttt{MyLT} is not accessible outside the definition of \texttt{foo}: 147 | 148 | \begin{code} 149 | foo : Int -> Int 150 | foo x = case isLT of 151 | Yes => x*2 152 | No => x*4 153 | where 154 | data MyLT = Yes | No 155 | 156 | isLT : MyLT 157 | isLT = if x < 20 then Yes else No 158 | \end{code} 159 | 160 | \noindent 161 | In general, functions defined in a \texttt{where} clause need a type declaration just like any top level function. 162 | However, the type declaration for a function \texttt{f} \emph{can} be omitted if: 163 | 164 | \begin{itemize} 165 | \item \texttt{f} appears in the right hand side of the top level definition 166 | \item The type of \texttt{f} can be completely determined from its first application 167 | \end{itemize} 168 | 169 | \noindent 170 | So, for example, the following definitions are legal: 171 | 172 | \inputIdrisListing[firstline=3]{./examples/wheres.idr} 173 | 174 | \subsection{Dependent Types} 175 | 176 | \subsubsection{Vectors} 177 | 178 | A standard example of a dependent type is the type of ``lists with length'', 179 | conventionally called vectors in the dependent type literature. 180 | They are available as part of the \Idris{} library, by importing 181 | \texttt{Data.Vect}, or we can declare them as follows: 182 | 183 | \begin{code} 184 | data Vect : Nat -> Type -> Type where 185 | Nil : Vect Z a 186 | (::) : a -> Vect k a -> Vect (S k) a 187 | \end{code} 188 | 189 | \noindent 190 | Note that we have used the same constructor names as for \tTC{List}. 191 | Ad-hoc name overloading such as this is accepted by \Idris{}, provided that the names are declared in different namespaces (in practice, normally in different modules). 192 | Ambiguous constructor names can normally be resolved from context. 193 | 194 | This declares a family of types, and so the form of the declaration is rather 195 | different from the simple type declarations above. We explicitly state the 196 | type of the type constructor \tTC{Vect} --- it takes a \tTC{Nat} and a type as 197 | an argument, where \tTC{Type} stands for the type of types. We say that 198 | \tTC{Vect} is \emph{indexed} over \tTC{Nat} and \emph{parameterised} by 199 | \tTC{Type}. Each constructor targets a different part of the family of types. 200 | \tDC{Nil} can only be used to construct vectors with zero length, and \tDC{::} 201 | to construct vectors with non-zero length. In the type of \tDC{::}, we state 202 | explicitly that an element of type \texttt{a} and a tail of type \texttt{Vect k 203 | a} (i.e., a vector of length \texttt{k}) combine to make a vector of length 204 | \texttt{S k}. 205 | 206 | We can define functions on dependent types such as \tTC{Vect} in the same way as on simple types such as \tTC{List} and \tTC{Nat} above, by pattern matching. 207 | The type of a function over \tTC{Vect} will describe what happens to the lengths of the vectors involved. 208 | For example, \tFN{++}, defined as follows, appends two \tTC{Vect}s: 209 | 210 | \begin{code} 211 | (++) : Vect n a -> Vect m a -> Vect (n + m) a 212 | (++) Nil ys = ys 213 | (++) (x :: xs) ys = x :: xs ++ ys 214 | \end{code} 215 | 216 | \noindent 217 | The type of \tFN{(++)} states that the resulting vector's length will be the sum of the input lengths. 218 | If we get the definition wrong in such a way that this does not hold, \Idris{} will not accept the definition. 219 | For example: 220 | 221 | \begin{code} 222 | (++) : Vect n a -> Vect m a -> Vect (n + m) a 223 | (++) Nil ys = ys 224 | (++) (x :: xs) ys = x :: xs ++ xs -- BROKEN 225 | \end{code} 226 | 227 | \noindent 228 | When run through the \Idris{} type checker, this results in the following: 229 | 230 | \begin{lstlisting}[style=stdout] 231 | $ idris vbroken.idr --check 232 | vbroken.idr:9:23:When elaborating right hand side of Vect.++: 233 | When elaborating an application of constructor Vect.::: 234 | Can't unify 235 | Vect (k + k) a 236 | with 237 | Vect (plus k m) a 238 | 239 | Specifically: 240 | Can't unify 241 | plus k k 242 | with 243 | plus k m 244 | \end{lstlisting} 245 | 246 | \noindent 247 | This error message suggests that there is a length mismatch between two vectors 248 | --- we needed a vector of length \texttt{k + m}, but provided a vector of length 249 | \texttt{k + k}. 250 | 251 | % Note that the terms in the error message have been \emph{normalised}, so in particular \texttt{n + m} has been reduced to \texttt{plus n m}. 252 | 253 | \subsubsection{The Finite Sets} 254 | 255 | Finite sets, as the name suggests, are sets with a finite number of elements. 256 | They are available as part of the \Idris{} library, by importing 257 | \texttt{Data.Fin}, or can be declared as follows: 258 | 259 | \begin{code} 260 | data Fin : Nat -> Type where 261 | FZ : Fin (S k) 262 | FS : Fin k -> Fin (S k) 263 | \end{code} 264 | 265 | \noindent 266 | \tDC{FZ} is the zeroth element of a finite set with \texttt{S k} elements; \texttt{FS n} is the \texttt{n+1}th element of a finite set with \texttt{S k} elements. 267 | \tTC{Fin} is indexed by a \tTC{Nat}, which represents the number of elements in the set. 268 | Obviously we can't construct an element of an empty set, so neither constructor targets \texttt{Fin Z}. 269 | 270 | A useful application of the \tTC{Fin} family is to represent bounded natural numbers. 271 | Since the first \tTC{n} natural numbers form a finite set of \tTC{n} elements, we can treat \tTC{Fin n} as the set of natural numbers bounded by \tTC{n}. 272 | 273 | For example, the following function which looks up an element in a \tTC{Vect}, by a bounded index given as a \tTC{Fin n}, is defined in the prelude: 274 | 275 | \begin{code} 276 | index : Fin n -> Vect n a -> a 277 | index FZ (x :: xs) = x 278 | index (FS k) (x :: xs) = index k xs 279 | \end{code} 280 | 281 | \noindent 282 | This function looks up a value at a given location in a vector. 283 | The location is bounded by the length of the vector (\texttt{n} in each case), so there is no 284 | need for a run-time bounds check. 285 | The type checker guarantees that the location is no larger than the length of the vector. 286 | 287 | Note also that there is no case for \texttt{Nil} here. 288 | This is because it is impossible. Since there is no element of \texttt{Fin Z}, and the location is a \texttt{Fin n}, then \texttt{n} can not be \tDC{Z}. 289 | As a result, attempting to look up an element in an empty vector would give a compile time type error, since it would force \texttt{n} to be \tDC{Z}. 290 | 291 | 292 | \subsubsection{Implicit Arguments} 293 | 294 | Let us take a closer look at the type of \texttt{index}: 295 | 296 | \begin{code} 297 | index : Fin n -> Vect n a -> a 298 | \end{code} 299 | 300 | \noindent 301 | It takes two arguments, an element of the finite set of \texttt{n} elements, and a vector with \texttt{n} elements of type \texttt{a}. But there are also two names, \texttt{n} and \texttt{a}, which are not declared explicitly. 302 | These are \emph{implicit} arguments to \texttt{index}. We could also write the type of \texttt{index} as: 303 | 304 | \begin{code} 305 | index : {a:Type} -> {n:Nat} -> Fin n -> Vect n a -> a 306 | \end{code} 307 | 308 | \noindent 309 | Implicit arguments, given in braces \texttt{\{\}} in the type declaration, are not given in applications of \texttt{index}; their values can be inferred from the types of the \texttt{Fin n} and \texttt{Vect n a} arguments. 310 | Any name with a \remph{lower case initial letter} which appears as a parameter or index in a type declaration, but which is otherwise free, will be automatically bound as an implicit argument. 311 | Implicit arguments can still be given explicitly in applications, using \texttt{\{a=value\}} and \texttt{\{n=value\}}, for example: 312 | 313 | \begin{code} 314 | index {a=Int} {n=2} FZ (2 :: 3 :: Nil) 315 | \end{code} 316 | 317 | \noindent 318 | In fact, any argument, implicit or explicit, may be given a name. 319 | We could have declared the type of \texttt{index} as: 320 | 321 | \begin{code} 322 | index : (i:Fin n) -> (xs:Vect n a) -> a 323 | \end{code} 324 | 325 | \noindent 326 | It is a matter of taste whether you want to do this --- sometimes it can help document a function by making the purpose of an argument more clear. 327 | 328 | \subsubsection{``\texttt{using}'' notation} 329 | 330 | Sometimes it is useful to provide types of implicit arguments, particularly 331 | where there is a dependency ordering, or where the implicit arguments themselves 332 | have dependencies. 333 | For example, we may wish to state the types of the implicit arguments 334 | in the following definition, which defines a predicate on vectors: 335 | 336 | \begin{code} 337 | data Elem : a -> Vect n a -> Type where 338 | Here : {x:a} -> {xs:Vect n a} -> Elem x (x :: xs) 339 | There : {x,y:a} -> {xs:Vect n a} -> Elem x xs -> Elem x (y :: xs) 340 | \end{code} 341 | 342 | \noindent 343 | An instance of \texttt{Elem x xs} states that \texttt{x} is an element of 344 | \texttt{xs}. 345 | We can construct such a predicate if the required element is \texttt{Here}, at the head of the vector, or \texttt{There}, in the tail of the vector. 346 | For example: 347 | 348 | \begin{code} 349 | testVec : Vect 4 Int 350 | testVec = 3 :: 4 :: 5 :: 6 :: Nil 351 | 352 | inVect : Elem 5 testVec 353 | inVect = There (There Here) 354 | \end{code} 355 | 356 | \noindent 357 | If the same implicit arguments are being used a lot, it can make a definition difficult to read. 358 | To avoid this problem, a \texttt{using} block gives the types and ordering of any implicit arguments which can appear within the block: 359 | 360 | \begin{code} 361 | using (x:a, y:a, xs:Vect n a) 362 | data Elem : a -> Vect n a -> Type where 363 | Here : Elem x (x :: xs) 364 | There : Elem x xs -> Elem x (y :: xs) 365 | \end{code} 366 | 367 | \subsubsection*{Note: Declaration Order and \texttt{mutual} blocks} 368 | 369 | In general, functions and data types must be defined before use, since dependent types allow functions to appear as part of types, and their reduction behaviour to affect type checking. 370 | However, this restriction can be relaxed by using a \texttt{mutual} block, which allows data types and functions to be defined simultaneously: 371 | 372 | \begin{code} 373 | mutual 374 | even : Nat -> Bool 375 | even Z = True 376 | even (S k) = odd k 377 | 378 | odd : Nat -> Bool 379 | odd Z = False 380 | odd (S k) = even k 381 | \end{code} 382 | 383 | 384 | \noindent 385 | In a \texttt{mutual} block, first all of the type declarations are added, then the function bodies. 386 | As a result, none of the function types can depend on the reduction behaviour of any of the functions in the block. 387 | 388 | \subsection{I/O} 389 | 390 | Computer programs are of little use if they do not interact with the user or the system in some way. 391 | The difficulty in a pure language such as \Idris{} --- that is, a language where expressions do not have side-effects --- is that I/O is inherently side-effecting. 392 | Therefore in \Idris{}, such interactions are encapsulated in the type \texttt{IO}: 393 | 394 | \begin{code} 395 | data IO a -- IO operation returning a value of type a 396 | \end{code} 397 | 398 | \noindent 399 | We'll leave the definition of \texttt{IO} abstract, but effectively it describes what the I/O operations to be executed are, rather than how to execute them. 400 | The resulting operations are executed externally, by the run-time system. 401 | We've already seen one IO program: 402 | 403 | \begin{code} 404 | main : IO () 405 | main = putStrLn "Hello world" 406 | \end{code} 407 | 408 | 409 | \noindent 410 | The type of \texttt{putStrLn} explains that it takes a string, and returns an element of the unit type \texttt{()} via an I/O action. 411 | There is a variant \texttt{putStr} which outputs a string without a newline: 412 | 413 | \begin{code} 414 | putStrLn : String -> IO () 415 | putStr : String -> IO () 416 | \end{code} 417 | 418 | We can also read strings from user input: 419 | 420 | \begin{code} 421 | getLine : IO String 422 | \end{code} 423 | 424 | 425 | \noindent 426 | A number of other I/O operations are defined in the prelude, for example for reading and writing files, including: 427 | 428 | \begin{code} 429 | data File -- abstract 430 | data Mode = Read | Write | ReadWrite 431 | 432 | openFile : String -> Mode -> IO File 433 | closeFile : File -> IO () 434 | 435 | fread : File -> IO String 436 | fwrite : File -> String -> IO () 437 | feof : File -> IO Bool 438 | 439 | readFile : String -> IO String 440 | \end{code} 441 | 442 | 443 | \subsection{``\texttt{do}'' notation} 444 | \label{sect:do} 445 | 446 | I/O programs will typically need to sequence actions, feeding the output of one computation into the input of the next. 447 | \texttt{IO} is an abstract type, however, so we can't access the result of a computation directly. 448 | Instead, we sequence operations with \texttt{do} notation: 449 | 450 | \begin{code} 451 | greet : IO () 452 | greet = do putStr "What is your name? " 453 | name <- getLine 454 | putStrLn ("Hello " ++ name) 455 | \end{code} 456 | 457 | 458 | \noindent 459 | The syntax \texttt{x <- iovalue} executes the I/O operation \texttt{iovalue}, of type \texttt{IO a}, and puts the result, of type \texttt{a} into the variable \texttt{x}. 460 | In this case, \texttt{getLine} returns an \texttt{IO String}, so \texttt{name} has type \texttt{String}. 461 | Indentation is significant --- each statement in the do block must begin in the same column. 462 | The \texttt{return} operation allows us to inject a value directly into an IO operation: 463 | 464 | \begin{code} 465 | return : a -> IO a 466 | \end{code} 467 | 468 | \noindent 469 | As we will see later, \texttt{do} notation is more general than this, and can be overloaded. 470 | 471 | \subsection{Laziness} 472 | 473 | \label{sect:lazy} 474 | Normally, arguments to functions are evaluated before the function itself 475 | (that is, \Idris{} uses \emph{eager} evaluation). However, this is not always 476 | the best approach. Consider the following function: 477 | 478 | \begin{code} 479 | boolCase : Bool -> a -> a -> a; 480 | boolCase True t e = t; 481 | boolCase False t e = e; 482 | \end{code} 483 | 484 | \noindent 485 | This function uses one of the \texttt{t} or \texttt{e} arguments, but not both (in fact, this is used to implement the \texttt{if...then...else} construct as we will see later. 486 | We would prefer if \emph{only} the argument which was used was evaluated. 487 | To achieve this, \Idris{} provides a \texttt{Lazy} data type, which allows evaluation to be suspended: 488 | 489 | \begin{code} 490 | data Lazy : Type -> Type where 491 | Delay : (val : a) -> Lazy a 492 | 493 | Force : Lazy a -> a 494 | \end{code} 495 | 496 | \noindent 497 | A value of type \texttt{Lazy a} is unevaluated until it is forced by \texttt{Force}. 498 | The \Idris{} type checker knows about the \texttt{Lazy} type, and inserts conversions where necessary between \texttt{Lazy a} and \texttt{a}, and vice versa. 499 | We can therefore write \texttt{boolCase} as follows, without any explicit 500 | use of \texttt{Force} or \texttt{Delay}: 501 | 502 | \begin{code} 503 | boolCase : Bool -> Lazy a -> Lazy a -> a; 504 | boolCase True t e = t; 505 | boolCase False t e = e; 506 | \end{code} 507 | 508 | 509 | \subsection{Useful Data Types} 510 | 511 | \Idris{} includes a number of useful data types and library functions (see the \texttt{libs/} directory in the distribution). 512 | This chapter describes a few of these. 513 | The functions described here are imported automatically by every \Idris{} program, as part of \texttt{Prelude.idr}. 514 | 515 | \subsubsection{\texttt{List} and \texttt{Vect}} 516 | 517 | We have already seen the \texttt{List} and \texttt{Vect} data types: 518 | 519 | \begin{code} 520 | data List a = Nil | (::) a (List a) 521 | 522 | data Vect : Nat -> Type -> Type where 523 | Nil : Vect Z a 524 | (::) : a -> Vect k a -> Vect (S k) a 525 | \end{code} 526 | 527 | \noindent 528 | Note that the constructor names are the same for each --- constructor names (in fact, names in general) can be overloaded, provided that they are declared in different namespaces (see Section \ref{sect:namespaces}), and will typically be resolved according to their type. 529 | As syntactic sugar, any type with the constructor names \texttt{Nil} and \texttt{::} can be written in list form. 530 | For example: 531 | 532 | \begin{itemize} 533 | \item \texttt{[]} means \texttt{Nil} 534 | \item \texttt{[1,2,3]} means \texttt{1 :: 2 :: 3 :: Nil} 535 | \end{itemize} 536 | 537 | \noindent 538 | The library also defines a number of functions for manipulating these types. 539 | \texttt{map} is overloaded both for \texttt{List} and \texttt{Vect} and applies a function to every element of the list or vector. 540 | 541 | \begin{code} 542 | map : (a -> b) -> List a -> List b 543 | map f [] = [] 544 | map f (x :: xs) = f x :: map f xs 545 | 546 | map : (a -> b) -> Vect n a -> Vect n b 547 | map f [] = [] 548 | map f (x :: xs) = f x :: map f xs 549 | \end{code} 550 | 551 | 552 | \noindent 553 | For example, given the following vector of integers, and a function to double an integer: 554 | 555 | \inputIdrisListing[firstline=2,lastline=6]{./examples/usefultypes.idr} 556 | 557 | \noindent 558 | the function \texttt{map} can be used as follows to double every element in the vector: 559 | 560 | \begin{lstlisting}[style=stdout] 561 | *usefultypes> show (map double intVec) 562 | "[2, 4, 6, 8, 10]" : String 563 | \end{lstlisting} 564 | 565 | \noindent 566 | You'll find these examples in \texttt{usefultypes.idr} in the \texttt{examples/} directory. 567 | For more details of the functions available on \texttt{List} and \texttt{Vect}, look in the library files: 568 | 569 | \begin{itemize} 570 | \item\texttt{libs/prelude/Prelude/List.idr} 571 | \item\texttt{libs/base/Data/List.idr} 572 | \item\texttt{libs/base/Data/Vect.idr} 573 | \item\texttt{libs/base/Data/VectType.idr} 574 | \end{itemize} 575 | 576 | \noindent 577 | Functions include filtering, appending, reversing, and so on. 578 | Also remember that \Idris{} is still in development, so if you don't see the function you need, please feel free to add it and submit a patch! 579 | 580 | \subsubsection*{Aside: Anonymous functions and operator sections} 581 | 582 | There are actually neater ways to write the above expression. 583 | One way would be to use an anonymous function: 584 | 585 | \begin{lstlisting}[style=stdout] 586 | *usefultypes> show (map (\x => x * 2) intVec) 587 | "[2, 4, 6, 8, 10]" : String 588 | \end{lstlisting} 589 | 590 | 591 | \noindent 592 | The notation \lstinline!\x => val! constructs an anonymous function which takes one argument, \texttt{x} and returns the expression \texttt{val}. 593 | Anonymous functions may take several arguments, separated by commas, e.g.\ \lstinline!\x, y, z => val!. 594 | Arguments may also be given explicit types, e.g.\ \lstinline!\x : Int => x * 2!, and can pattern match, e.g.\ \lstinline!\(x, y) => x + y!. 595 | We could also use an operator section: 596 | 597 | \begin{lstlisting}[style=stdout] 598 | *usefultypes> show (map (* 2) intVec) 599 | "[2, 4, 6, 8, 10]" : String 600 | \end{lstlisting} 601 | 602 | 603 | \noindent 604 | \lstinline!(*2)! is shorthand for a function which multiplies a number by 2. 605 | It expands to \lstinline!\x => x * 2!. 606 | Similarly, \texttt{(2*)} would expand to \lstinline!\x => 2 * x!. 607 | 608 | \subsubsection{Maybe} 609 | 610 | \texttt{Maybe} describes an optional value. 611 | Either there is a value of the given type, or there isn't: 612 | 613 | \begin{code} 614 | data Maybe a = Just a | Nothing 615 | \end{code} 616 | 617 | 618 | \noindent 619 | \texttt{Maybe} is one way of giving a type to an operation that may fail. 620 | For example, looking something up in a \texttt{List} (rather than a vector) may result in an out of bounds error: 621 | 622 | \inputIdrisListing[firstline=11, lastline=15]{./examples/usefultypes.idr} 623 | 624 | \noindent 625 | The \texttt{maybe} function is used to process values of type \texttt{Maybe}, either by applying a function to the value, if there is one, or by providing a default value: 626 | 627 | \begin{code} 628 | maybe : Lazy b -> (a -> b) -> Maybe a -> b 629 | \end{code} 630 | 631 | \noindent 632 | Note that the type of the first argument is \texttt{Lazy b} rather than simply \texttt{b}. 633 | Since the default value might not be used, we mark it as \texttt{Lazy} in case it is a large expression where evaluating it then discarding it would be wasteful. 634 | 635 | \subsubsection{Tuples and Dependent Pairs} 636 | 637 | Values can be paired with the following built-in data type: 638 | 639 | \begin{code} 640 | data Pair a b = MkPair a b 641 | \end{code} 642 | 643 | 644 | \noindent 645 | As syntactic sugar, we can write \texttt{(a, b)} which, according to context, means either \texttt{Pair a b} or \texttt{MkPair a b}. 646 | Tuples can contain an arbitrary number of values, represented as nested pairs: 647 | 648 | \begin{code} 649 | fred : (String, Int) 650 | fred = ("Fred", 42) 651 | 652 | jim : (String, Int, String) 653 | jim = ("Jim", 25, "Cambridge") 654 | \end{code} 655 | 656 | 657 | \subsubsection*{Dependent Pairs} 658 | 659 | Dependent pairs allow the type of the second element of a pair to depend on the value of the first element. 660 | Traditionally, these are referred to as ``sigma types'': 661 | 662 | \begin{code} 663 | data Sigma : (A : Type) -> (P : A -> Type) -> Type where 664 | MkSigma : {P : A -> Type} -> (a : A) -> P a -> Sigma A P 665 | \end{code} 666 | 667 | \noindent 668 | Again, there is syntactic sugar for this. \texttt{(a : A ** P)} is the type of a pair of A and P, where the name \texttt{a} can occur inside \texttt{P}. 669 | \texttt{( a ** p )} constructs a value of this type. For example, we can pair a number with a \texttt{Vect} of a particular length. 670 | 671 | \begin{code} 672 | vec : (n : Nat ** Vect n Int) 673 | vec = (2 ** [3, 4]) 674 | \end{code} 675 | 676 | \noindent 677 | If you like, you can write it out the long way, the two are precisely equivalent. 678 | 679 | \begin{code} 680 | vec : Sigma Nat (\n => Vect n Int) 681 | vec = MkSigma 2 [3, 4] 682 | \end{code} 683 | 684 | The type checker could of course infer the value of the first element from the 685 | length of the vector. 686 | We can write an underscore \texttt{\_} in place of values which we expect the type checker to fill in, so the above definition could also be written as: 687 | 688 | \begin{code} 689 | vec : (n : Nat ** Vect n Int) 690 | vec = (_ ** [3, 4]) 691 | \end{code} 692 | 693 | 694 | \noindent 695 | We might also prefer to omit the type of the first element of the pair, since, again, it can be inferred: 696 | 697 | \begin{code} 698 | vec : (n ** Vect n Int) 699 | vec = (_ ** [3, 4]) 700 | \end{code} 701 | 702 | \noindent 703 | One use for dependent pairs is to return values of dependent types where the index is not necessarily known in advance. 704 | For example, if we filter elements out of a \texttt{Vect} according to some predicate, we will not know in advance what the length of the resulting vector will be: 705 | 706 | \begin{code} 707 | filter : (a -> Bool) -> Vect n a -> (p ** Vect p a) 708 | \end{code} 709 | 710 | 711 | \noindent 712 | If the \texttt{Vect} is empty, the result is easy: 713 | 714 | \begin{code} 715 | filter p Nil = (_ ** []) 716 | \end{code} 717 | 718 | 719 | \noindent 720 | In the \texttt{::} case, we need to inspect the result of a recursive call to \texttt{filter} to extract the length and the vector from the result. 721 | To do this, we use \texttt{with} notation, which allows pattern matching on intermediate values: 722 | 723 | \begin{code} 724 | filter p (x :: xs) with (filter p xs) 725 | | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' ) 726 | \end{code} 727 | 728 | \noindent 729 | We will see more on \texttt{with} notation later. 730 | 731 | \subsection{More Expressions} 732 | 733 | \subsubsection*{\texttt{let} bindings} 734 | 735 | Intermediate values can be calculated using \texttt{let} bindings: 736 | 737 | \inputIdrisListing[firstline=3, lastline=6]{./examples/letbind.idr} 738 | 739 | \noindent 740 | We can do simple pattern matching in \texttt{let} bindings too. 741 | For example, we can extract fields from a record as follows, as well as by pattern matching at the top level: 742 | 743 | \inputIdrisListing[firstline=7, lastline=12]{./examples/letbind.idr} 744 | 745 | \subsubsection*{List comprehensions} 746 | \label{sec:listcomp} 747 | 748 | \Idris{} provides \emph{comprehension} notation as a convenient shorthand for building lists. 749 | The general form is: 750 | 751 | \begin{lstlisting}[style=stdout] 752 | [ expression | qualifiers ] 753 | \end{lstlisting} 754 | 755 | \noindent 756 | This generates the list of values produced by evaluating the \texttt{expression}, according to the conditions given by the comma separated \texttt{qualifiers}. 757 | For example, we can build a list of Pythagorean triples as follows: 758 | 759 | \begin{code} 760 | pythag : Int -> List (Int, Int, Int) 761 | pythag n = [ (x, y, z) | z <- [1..n], y <- [1..z], x <- [1..y], 762 | x*x + y*y == z*z ] 763 | \end{code} 764 | 765 | 766 | \noindent 767 | The \texttt{[a..b]} notation is another shorthand which builds a list of numbers between \texttt{a} and \texttt{b}. 768 | Alternatively \texttt{[a,b..c]} builds a list of numbers between \texttt{a} and \texttt{c} with the increment specified by the difference between \texttt{a} and \texttt{b}. 769 | This works for any numeric type, using the \texttt{count} function from the prelude. 770 | 771 | \subsubsection*{\texttt{case} expressions} 772 | 773 | Another way of inspecting intermediate values of \emph{simple} types 774 | is to use a \texttt{case} expression. 775 | The following function, for example, splits a string into two at a given character: 776 | 777 | \inputIdrisListing[firstline=13]{./examples/letbind.idr} 778 | 779 | \noindent 780 | \texttt{break} is a library function which breaks a string into a pair of strings 781 | at the point where the given function returns true. 782 | We then deconstruct the pair it returns, and remove the first character of the second string. 783 | 784 | A \texttt{case} expression can match several cases, for example, to inspect an intermediate value of type \texttt{Maybe a}. 785 | Recall \texttt{list\_lookup} which looks up an index in a list, returning \texttt{Nothing} if the index is out 786 | of bounds. 787 | We can use this to write \texttt{lookup\_default}, which looks up an index and returns a default value if the index is out of bounds: 788 | 789 | \inputIdrisListing[firstline=16]{./examples/usefultypes.idr} 790 | 791 | \noindent 792 | If the index is in bounds, we get the value at that index, otherwise we get a default value: 793 | 794 | \begin{lstlisting}[style=stdout] 795 | *usefultypes> lookup_default 2 [3,4,5,6] (-1) 796 | 5 : Integer 797 | *usefultypes> lookup_default 4 [3,4,5,6] (-1) 798 | -1 : Integer 799 | \end{lstlisting} 800 | 801 | 802 | \noindent 803 | \textbf{Restrictions:} The \texttt{case} construct is intended for simple analysis of intermediate expressions to avoid the need to write auxiliary functions, and is also used internally to implement pattern matching \texttt{let} and lambda bindings. 804 | It will \emph{only} work if: 805 | 806 | \begin{itemize} 807 | \item Each branch \emph{matches} a value of the same type, and \emph{returns} a value of the same type. 808 | \item The type of the result is ``known''. i.e.\ the type of the expression can be determined \emph{without} type checking the \texttt{case}-expression itself. 809 | \end{itemize} 810 | 811 | \subsection{Dependent Records} 812 | 813 | \emph{Records} are data types which collect several values (the record's \emph{fields}) together. 814 | \Idris{} provides syntax for defining records and automatically generating field access and update functions. 815 | For example, we can represent a person's name and age in a record: 816 | 817 | \begin{code} 818 | record Person : Type where 819 | MkPerson : (name : String) -> 820 | (age : Int) -> Person 821 | 822 | fred : Person 823 | fred = MkPerson "Fred" 30 824 | \end{code} 825 | 826 | 827 | \noindent 828 | Record declarations are like \texttt{data} declarations, except that they are introduced by the \texttt{record} keyword, and can only have one constructor. 829 | The names of the binders in the constructor type (\texttt{name} and \texttt{age}) here are the field names, which we can use to access the field values: 830 | 831 | \begin{lstlisting}[style=stdout] 832 | *record> name fred 833 | "Fred" : String 834 | *record> age fred 835 | 30 : Int 836 | *record> :t name 837 | name : Person -> String 838 | \end{lstlisting} 839 | 840 | \noindent 841 | We can also use the field names to update a record (or, more precisely, produce a new record with the given fields updated). 842 | 843 | \begin{lstlisting}[style=stdout] 844 | *record> record { name = "Jim" } fred 845 | MkPerson "Jim" 30 : Person 846 | *record> record { name = "Jim", age = 20 } fred 847 | MkPerson "Jim" 20 : Person 848 | \end{lstlisting} 849 | 850 | \noindent 851 | The syntax \texttt{record \{ field = val, ... \}} generates a function which updates the given fields in a record. 852 | 853 | Records, and fields within records, can have dependent types. 854 | Updates are allowed to change the type of a field, provided that the result is well-typed, and the result does not affect the type of the record as a whole. 855 | For example: 856 | 857 | \begin{code} 858 | record Class : Type where 859 | ClassInfo : (students : Vect n Person) -> 860 | (className : String) -> 861 | Class 862 | \end{code} 863 | 864 | \noindent 865 | It is safe to update the \texttt{students} field to a vector of a different length because it will not affect the type of the record: 866 | 867 | \begin{code} 868 | addStudent : Person -> Class -> Class 869 | addStudent p c = record { students = p :: students c } c 870 | \end{code} 871 | 872 | \begin{lstlisting}[style=stdout] 873 | *record> addStudent fred (ClassInfo [] "CS") 874 | ClassInfo (prelude.vect.:: (MkPerson "Fred" 30) (prelude.vect.Nil)) "CS" 875 | : Class 876 | \end{lstlisting} 877 | 878 | \subsubsection*{Nested record update} 879 | 880 | \Idris{} also provides a convenient syntax for accessing and updating nested 881 | records. For example, if a field is accessible with the expression 882 | \texttt{c (b (a x))}, it can be updated using the following syntax: 883 | 884 | \begin{code} 885 | record { a->b->c = val } x 886 | \end{code} 887 | 888 | \noindent 889 | This returns a new record, with the field accessed by the path 890 | \texttt{a->b->c} set to \texttt{x}. The syntax is first class, i.e. 891 | \texttt{record \{ a->b->c = val \}} itself has a function type. 892 | Symmetrically, the field can also be accessed with the following syntax: 893 | 894 | \begin{code} 895 | record { a->b->c } x 896 | \end{code} 897 | 898 | 899 | -------------------------------------------------------------------------------- /content/views.tex: -------------------------------------------------------------------------------- 1 | \section{Views and the ``\texttt{with}'' rule} 2 | 3 | \subsection{Dependent pattern matching} 4 | 5 | Since types can depend on values, the form of some arguments can be determined by the value of others. 6 | For example, if we were to write down the implicit length arguments to \texttt{(++)}, we'd see that the form of the length argument was determined by whether the vector was empty or not: 7 | 8 | \begin{code} 9 | (++) : Vect n a -> Vect m a -> Vect (n + m) a 10 | (++) {n=Z} [] ys = ys 11 | (++) {n=S k} (x :: xs) ys = x :: xs ++ ys 12 | \end{code} 13 | 14 | \noindent 15 | If \texttt{n} was a successor in the \texttt{[]} case, or zero in the \texttt{::} case, the definition would not be well typed. 16 | 17 | \subsection{The \texttt{with} rule --- matching intermediate values} 18 | 19 | Very often, we need to match on the result of an intermediate computation. 20 | \Idris{} provides a construct for this, the \texttt{with} rule, inspired by views in \Epigram~\cite{view-left}, which takes account of the fact that matching on a value in a dependently typed language can affect what we know about the forms of other values. 21 | In its simplest form, the \texttt{with} rule adds another argument to the function being defined, e.g.\ we have already seen a vector filter function, defined as follows: 22 | 23 | \begin{code} 24 | filter : (a -> Bool) -> Vect n a -> (p ** Vect p a) 25 | filter p [] = ( _ ** [] ) 26 | filter p (x :: xs) with (filter p xs) 27 | | ( _ ** xs' ) = if (p x) then ( _ ** x :: xs' ) else ( _ ** xs' ) 28 | \end{code} 29 | 30 | \noindent 31 | Here, the \texttt{with} clause allows us to deconstruct the result of \texttt{filter p xs}. 32 | Effectively, it adds this value as an extra argument, which we place after the vertical bar. 33 | 34 | If the intermediate computation itself has a dependent type, then the result can affect the forms of other arguments --- we can learn the form of one value by testing another. 35 | For example, a \texttt{Nat} is either even or odd. 36 | If it's even it will be the sum of two equal \texttt{Nat}s. 37 | Otherwise, it is the sum of two equal \texttt{Nat}s plus one: 38 | 39 | \begin{code} 40 | data Parity : Nat -> Type where 41 | Even : Parity (n + n) 42 | Odd : Parity (S (n + n)) 43 | \end{code} 44 | 45 | \noindent 46 | We say \texttt{Parity} is a \emph{view} of \texttt{Nat}. 47 | It has a \emph{covering function} which tests whether it is even or odd and constructs the predicate accordingly. 48 | 49 | \begin{code} 50 | parity : (n:Nat) -> Parity n 51 | \end{code} 52 | 53 | \label{sect:nattobin} 54 | 55 | \noindent 56 | We'll come back to the definition of \texttt{parity} shortly. 57 | We can use it to write a function which converts a natural number to a list of binary digits (least significant first) as follows, using the \texttt{with} rule: 58 | 59 | \begin{code} 60 | natToBin : Nat -> List Bool 61 | natToBin Z = Nil 62 | natToBin k with (parity k) 63 | natToBin (j + j) | Even = False :: natToBin j 64 | natToBin (S (j + j)) | Odd = True :: natToBin j 65 | \end{code} 66 | 67 | \noindent 68 | The value of the result of \texttt{parity k} affects the form of \texttt{k}, because the result of \texttt{parity k} depends on \texttt{k}. 69 | So, as well as the patterns for the result of the intermediate computation (\texttt{Even} and \texttt{odd}) right of the \texttt{$\mid$}, we also write how the results affect the other patterns left of the $\mid$. 70 | Note that there is a function in the patterns (\texttt{+}) and repeated occurrences of \texttt{j}---this is allowed because another argument has determined the form of these patterns. 71 | 72 | We will return to this function in Section~\ref{sect:provisional} to complete the definition of \texttt{parity}. 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | check: .PHONY 2 | rm -f *.ibc 3 | for x in *.idr ; do \ 4 | echo "Checking $$x"; \ 5 | idris --check $$x; \ 6 | done 7 | 8 | clean: 9 | rm -f *.ibc 10 | 11 | .PHONY: 12 | -------------------------------------------------------------------------------- /examples/binary.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | data Binary : Nat -> Type where 4 | bEnd : Binary Z 5 | bO : Binary n -> Binary (n + n) 6 | bI : Binary n -> Binary (S (n + n)) 7 | 8 | instance Show (Binary n) where 9 | show (bO x) = show x ++ "0" 10 | show (bI x) = show x ++ "1" 11 | show bEnd = "" 12 | 13 | data Parity : Nat -> Type where 14 | Even : Parity (n + n) 15 | Odd : Parity (S (n + n)) 16 | 17 | parity : (n:Nat) -> Parity n 18 | parity Z = Even {n=Z} 19 | parity (S Z) = Odd {n=Z} 20 | parity (S (S k)) with (parity k) 21 | parity (S (S (j + j))) | Even ?= Even {n=S j} 22 | parity (S (S (S (j + j)))) | Odd ?= Odd {n=S j} 23 | 24 | natToBin : (n:Nat) -> Binary n 25 | natToBin Z = bEnd 26 | natToBin (S k) with (parity k) 27 | natToBin (S (j + j)) | Even = bI (natToBin j) 28 | natToBin (S (S (j + j))) | Odd ?= bO (natToBin (S j)) 29 | 30 | intToNat : Int -> Nat 31 | intToNat 0 = Z 32 | intToNat x = if (x>0) then (S (intToNat (x-1))) else Z 33 | 34 | main : IO () 35 | main = do putStr "Enter a number: " 36 | x <- getLine 37 | print (natToBin (fromInteger (cast x))) 38 | 39 | ---------- Proofs ---------- 40 | 41 | Main.natToBin_lemma_1 = proof 42 | intros 43 | rewrite plusSuccRightSucc j j 44 | rewrite sym (plusSuccRightSucc j j) 45 | trivial 46 | 47 | 48 | parity_lemma_1 = proof 49 | intros 50 | rewrite sym (plusSuccRightSucc j j) 51 | trivial 52 | 53 | 54 | parity_lemma_2 = proof { 55 | intro; 56 | intro; 57 | rewrite sym (plusSuccRightSucc j j); 58 | trivial; 59 | } 60 | 61 | 62 | -------------------------------------------------------------------------------- /examples/bmain.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | import btree 4 | 5 | main : IO () 6 | main = do let t = toTree [1,8,2,7,9,3] 7 | print (btree.toList t) 8 | 9 | -------------------------------------------------------------------------------- /examples/btree.idr: -------------------------------------------------------------------------------- 1 | module btree 2 | 3 | data BTree a = Leaf 4 | | Node (BTree a) a (BTree a) 5 | 6 | insert : Ord a => a -> BTree a -> BTree a 7 | insert x Leaf = Node Leaf x Leaf 8 | insert x (Node l v r) = if (x < v) then (Node (insert x l) v r) 9 | else (Node l v (insert x r)) 10 | 11 | toList : BTree a -> List a 12 | toList Leaf = [] 13 | toList (Node l v r) = btree.toList l ++ (v :: btree.toList r) 14 | 15 | toTree : Ord a => List a -> BTree a 16 | toTree [] = Leaf 17 | toTree (x :: xs) = insert x (toTree xs) 18 | 19 | -------------------------------------------------------------------------------- /examples/btreemod.idr: -------------------------------------------------------------------------------- 1 | module btree 2 | 3 | abstract data BTree a = Leaf 4 | | Node (BTree a) a (BTree a) 5 | 6 | abstract 7 | insert : Ord a => a -> BTree a -> BTree a 8 | insert x Leaf = Node Leaf x Leaf 9 | insert x (Node l v r) = if (x < v) then (Node (insert x l) v r) 10 | else (Node l v (insert x r)) 11 | 12 | abstract 13 | toList : BTree a -> List a 14 | toList Leaf = [] 15 | toList (Node l v r) = btree.toList l ++ (v :: btree.toList r) 16 | 17 | abstract 18 | toTree : Ord a => List a -> BTree a 19 | toTree [] = Leaf 20 | toTree (x :: xs) = insert x (toTree xs) 21 | -------------------------------------------------------------------------------- /examples/classes.idr: -------------------------------------------------------------------------------- 1 | m_add : Maybe Int -> Maybe Int -> Maybe Int 2 | m_add x y = do x' <- x -- Extract value from x 3 | y' <- y -- Extract value from y 4 | return (x' + y') -- Add them 5 | 6 | m_add' : Maybe Int -> Maybe Int -> Maybe Int 7 | m_add' x y = [ x' + y' | x' <- x, y' <- y ] 8 | 9 | sortAndShow : (Ord a, Show a) => List a -> String 10 | sortAndShow xs = show (sort xs) 11 | -------------------------------------------------------------------------------- /examples/foo.idr: -------------------------------------------------------------------------------- 1 | module foo 2 | 3 | namespace x 4 | test : Int -> Int 5 | test x = x * 2 6 | 7 | namespace y 8 | test : String -> String 9 | test x = x ++ x 10 | 11 | -------------------------------------------------------------------------------- /examples/hello.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | main : IO () 4 | main = putStrLn "Hello world" 5 | 6 | -------------------------------------------------------------------------------- /examples/idiom.idr: -------------------------------------------------------------------------------- 1 | module idiom 2 | 3 | data Expr = Var String 4 | | Val Int 5 | | Add Expr Expr 6 | 7 | data Eval : Type -> Type where 8 | MkEval : (List (String, Int) -> Maybe a) -> Eval a 9 | 10 | fetch : String -> Eval Int 11 | fetch x = MkEval fetchVal where 12 | fetchVal : List (String, Int) -> Maybe Int 13 | fetchVal [] = Nothing 14 | fetchVal ((v, val) :: xs) = if (x == v) then (Just val) else (fetchVal xs) 15 | 16 | instance Functor Eval where 17 | map f (MkEval g) = MkEval (\e => map f (g e)) 18 | 19 | instance Applicative Eval where 20 | pure x = MkEval (\e => Just x) 21 | 22 | (<*>) (MkEval f) (MkEval g) = MkEval (\x => app (f x) (g x)) where 23 | app : Maybe (a -> b) -> Maybe a -> Maybe b 24 | app (Just fx) (Just gx) = Just (fx gx) 25 | app _ _ = Nothing 26 | 27 | eval : Expr -> Eval Int 28 | eval (Var x) = fetch x 29 | eval (Val x) = [| x |] 30 | eval (Add x y) = [| eval x + eval y |] 31 | 32 | runEval : List (String, Int) -> Expr -> Maybe Int 33 | runEval env e = case eval e of 34 | MkEval envFn => envFn env 35 | 36 | m_add' : Maybe Int -> Maybe Int -> Maybe Int 37 | m_add' x y = [| x + y |] 38 | 39 | -------------------------------------------------------------------------------- /examples/interp.idr: -------------------------------------------------------------------------------- 1 | module Main 2 | 3 | data Ty = TyInt | TyBool| TyFun Ty Ty 4 | 5 | interpTy : Ty -> Type 6 | interpTy TyInt = Int 7 | interpTy TyBool = Bool 8 | interpTy (TyFun s t) = interpTy s -> interpTy t 9 | 10 | using (G : Vect n Ty) 11 | 12 | data Env : Vect n Ty -> Type where 13 | Nil : Env Nil 14 | (::) : interpTy a -> Env G -> Env (a :: G) 15 | 16 | data HasType : (i : Fin n) -> Vect n Ty -> Ty -> Type where 17 | Stop : HasType FZ (t :: G) t 18 | Pop : HasType k G t -> HasType (FS k) (u :: G) t 19 | 20 | lookup : HasType i G t -> Env G -> interpTy t 21 | lookup Stop (x :: xs) = x 22 | lookup (Pop k) (x :: xs) = lookup k xs 23 | 24 | data Expr : Vect n Ty -> Ty -> Type where 25 | Var : HasType i G t -> Expr G t 26 | Val : (x : Int) -> Expr G TyInt 27 | Lam : Expr (a :: G) t -> Expr G (TyFun a t) 28 | App : Expr G (TyFun a t) -> Expr G a -> Expr G t 29 | Op : (interpTy a -> interpTy b -> interpTy c) -> Expr G a -> Expr G b -> 30 | Expr G c 31 | If : Expr G TyBool -> Lazy (Expr G a) -> Lazy (Expr G a) -> Expr G a 32 | 33 | interp : Env G -> [static] (e : Expr G t) -> interpTy t 34 | interp env (Var i) = lookup i env 35 | interp env (Val x) = x 36 | interp env (Lam sc) = \x => interp (x :: env) sc 37 | interp env (App f s) = interp env f (interp env s) 38 | interp env (Op op x y) = op (interp env x) (interp env y) 39 | interp env (If x t e) = if interp env x then interp env t 40 | else interp env e 41 | 42 | eId : Expr G (TyFun TyInt TyInt) 43 | eId = Lam (Var Stop) 44 | 45 | eAdd : Expr G (TyFun TyInt (TyFun TyInt TyInt)) 46 | eAdd = Lam (Lam (Op (+) (Var Stop) (Var (Pop Stop)))) 47 | 48 | eEq : Expr G (TyFun TyInt (TyFun TyInt TyBool)) 49 | eEq = Lam (Lam (Op (==) (Var Stop) (Var (Pop Stop)))) 50 | 51 | eDouble : Expr G (TyFun TyInt TyInt) 52 | eDouble = Lam (App (App eAdd (Var Stop)) (Var Stop)) 53 | 54 | fact : Expr G (TyFun TyInt TyInt) 55 | fact = Lam (If (Op (==) (Var Stop) (Val 0)) 56 | (Val 1) (Op (*) (App fact (Op (-) (Var Stop) (Val 1))) (Var Stop))) 57 | 58 | testFac : Int 59 | testFac = interp [] fact 4 60 | 61 | -- unitTestFac : so (interp [] fact 4 == 24) 62 | -- unitTestFac = oh 63 | 64 | main : IO () 65 | main = do putStr "Enter a number: " 66 | x <- getLine 67 | print (interp [] fact (cast x)) 68 | 69 | -------------------------------------------------------------------------------- /examples/letbind.idr: -------------------------------------------------------------------------------- 1 | module letbind 2 | 3 | mirror : List a -> List a 4 | mirror xs = let xs' = reverse xs in 5 | xs ++ xs' 6 | 7 | data Person = MkPerson String Int 8 | 9 | showPerson : Person -> String 10 | showPerson p = let MkPerson name age = p in 11 | name ++ " is " ++ show age ++ " years old" 12 | 13 | splitAt : Char -> String -> (String, String) 14 | splitAt c x = case break (== c) x of 15 | (x, y) => (x, strTail y) 16 | 17 | -------------------------------------------------------------------------------- /examples/prims.idr: -------------------------------------------------------------------------------- 1 | module prims 2 | 3 | x : Int 4 | x = 42 5 | 6 | foo : String 7 | foo = "Sausage machine" 8 | 9 | bar : Char 10 | bar = 'Z' 11 | 12 | quux : Bool 13 | quux = False 14 | 15 | -------------------------------------------------------------------------------- /examples/theorems.idr: -------------------------------------------------------------------------------- 1 | 2 | fiveIsFive : 5 = 5 3 | fiveIsFive = Refl 4 | 5 | twoPlusTwo : 2 + 2 = 4 6 | twoPlusTwo = Refl 7 | 8 | total disjoint : (n : Nat) -> Z = S n -> Void 9 | disjoint n p = replace {P = disjointTy} p () 10 | where 11 | disjointTy : Nat -> Type 12 | disjointTy Z = () 13 | disjointTy (S k) = Void 14 | 15 | total acyclic : (n : Nat) -> n = S n -> Void 16 | acyclic Z p = disjoint _ p 17 | acyclic (S k) p = acyclic k (succInjective _ _ p) 18 | 19 | empty1 : Void 20 | empty1 = hd [] where 21 | hd : List a -> a 22 | hd (x :: xs) = x 23 | 24 | empty2 : Void 25 | empty2 = empty2 26 | 27 | plusReduces : (n:Nat) -> plus Z n = n 28 | plusReduces n = Refl 29 | 30 | plusReducesZ : (n:Nat) -> n = plus n Z 31 | plusReducesZ Z = Refl 32 | plusReducesZ (S k) = cong (plusReducesZ k) 33 | 34 | plusReducesS : (n:Nat) -> (m:Nat) -> S (plus n m) = plus n (S m) 35 | plusReducesS Z m = Refl 36 | plusReducesS (S k) m = cong (plusReducesS k m) 37 | 38 | plusReducesZ' : (n:Nat) -> n = plus n Z 39 | plusReducesZ' Z = ?plusredZ_Z 40 | plusReducesZ' (S k) = let ih = plusReducesZ' k in 41 | ?plusredZ_S 42 | 43 | 44 | ---------- Proofs ---------- 45 | 46 | plusredZ_S = proof { 47 | intro; 48 | intro; 49 | rewrite ih; 50 | trivial; 51 | } 52 | 53 | plusredZ_Z = proof { 54 | compute; 55 | trivial; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /examples/universe.idr: -------------------------------------------------------------------------------- 1 | myid : (a : Type) -> a -> a 2 | myid _ x = x 3 | 4 | idid : (a : Type) -> a -> a 5 | idid = myid _ myid 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/usefultypes.idr: -------------------------------------------------------------------------------- 1 | 2 | intVec : Vect 5 Int 3 | intVec = [1, 2, 3, 4, 5] 4 | 5 | double : Int -> Int 6 | double x = x * 2 7 | 8 | vec : (n ** Vect n Int) 9 | vec = (_ ** [3, 4]) 10 | 11 | list_lookup : Nat -> List a -> Maybe a 12 | list_lookup _ Nil = Nothing 13 | list_lookup Z (x :: xs) = Just x 14 | list_lookup (S k) (x :: xs) = list_lookup k xs 15 | 16 | lookup_default : Nat -> List a -> a -> a 17 | lookup_default i xs def = case list_lookup i xs of 18 | Nothing => def 19 | Just x => x 20 | 21 | -------------------------------------------------------------------------------- /examples/vbroken.idr: -------------------------------------------------------------------------------- 1 | module Vect 2 | 3 | data Vect : Nat -> Type -> Type where 4 | Nil : Vect Z a 5 | (::) : a -> Vect k a -> Vect (S k) a 6 | 7 | (++) : Vect n a -> Vect m a -> Vect (n + m) a 8 | (++) Nil ys = ys 9 | (++) (x :: xs) ys = x :: xs ++ xs -- BROKEN 10 | 11 | -------------------------------------------------------------------------------- /examples/views.idr: -------------------------------------------------------------------------------- 1 | module views 2 | 3 | data Parity : Nat -> Type where 4 | Even : Parity (n + n) 5 | Odd : Parity (S (n + n)) 6 | 7 | parity : (n:Nat) -> Parity n 8 | parity Z = Even {n=Z} 9 | parity (S Z) = Odd {n=Z} 10 | parity (S (S k)) with (parity k) 11 | parity (S (S (j + j))) | Even ?= Even {n=S j} 12 | parity (S (S (S (j + j)))) | Odd ?= Odd {n=S j} 13 | 14 | natToBin : Nat -> List Bool 15 | natToBin Z = Nil 16 | natToBin k with (parity k) 17 | natToBin (j + j) | Even = False :: natToBin j 18 | natToBin (S (j + j)) | Odd = True :: natToBin j 19 | 20 | 21 | ---------- Proofs ---------- 22 | 23 | views.parity_lemma_2 = proof { 24 | intro; 25 | intro; 26 | rewrite sym (plusSuccRightSucc j j); 27 | trivial; 28 | } 29 | 30 | views.parity_lemma_1 = proof { 31 | intro; 32 | intro; 33 | rewrite sym (plusSuccRightSucc j j); 34 | trivial; 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /examples/viewsbroken.idr: -------------------------------------------------------------------------------- 1 | 2 | data Parity : Nat -> Type where 3 | Even : Parity (n + n) 4 | Odd : Parity (S (n + n)) 5 | 6 | parity : (n:Nat) -> Parity n 7 | parity Z = Even {n=Z} 8 | parity (S Z) = Odd {n=Z} 9 | parity (S (S k)) with (parity k) 10 | parity (S (S (j + j))) | Even = Even {n=S j} 11 | parity (S (S (S (j + j)))) | Odd = Odd {n=S j} 12 | 13 | -------------------------------------------------------------------------------- /examples/wheres.idr: -------------------------------------------------------------------------------- 1 | module wheres 2 | 3 | even : Nat -> Bool 4 | even Z = True 5 | even (S k) = odd k where 6 | odd Z = False 7 | odd (S k) = even k 8 | 9 | test : List Nat 10 | test = [c (S 1), c Z, d (S Z)] 11 | where c x = 42 + x 12 | d y = c (y + 1 + z y) 13 | where z w = y + w 14 | 15 | -------------------------------------------------------------------------------- /fpmacros.sty: -------------------------------------------------------------------------------- 1 | %% ------------------------------------------- [ Functional Programming Macros ] 2 | %% A Package to provide support for functional programming. 3 | %% 4 | \NeedsTeXFormat{LaTeX2e}[1994/06/01] 5 | \ProvidesPackage{fpmacros}[2013/12/17 fpmacros] 6 | %% ------------------------------------------------------- [ Required Packages ] 7 | \RequirePackage{ifthen} 8 | \RequirePackage{amssymb} 9 | \RequirePackage{latexsym} 10 | \RequirePackage{eepic} 11 | \RequirePackage{fancyvrb} 12 | %% ----------------------------------------------------- [ Option Delcarations ] 13 | \newboolean{useverb} 14 | \setboolean{useverb}{true} 15 | 16 | \DeclareOption{noverb}{% 17 | \setboolean{useverb}{false} 18 | } 19 | 20 | \ProcessOptions\relax 21 | 22 | %% --------------------------------------------------------- [ Inference Rules ] 23 | \newlength{\rulevgap} 24 | \setlength{\rulevgap}{0.05in} 25 | \newlength{\ruleheight} 26 | \newlength{\ruledepth} 27 | \newsavebox{\rulebox} 28 | \newlength{\GapLength} 29 | \newcommand{\gap}[1]{\settowidth{\GapLength}{#1} \hspace*{\GapLength}} 30 | \newcommand{\dotstep}[2]{\begin{tabular}[b]{@{}c@{}} 31 | #1\\$\vdots$\\#2 32 | \end{tabular}} 33 | \newlength{\fracwid} 34 | \newcommand{\dotfrac}[2]{\settowidth{\fracwid}{$\frac{#1}{#2}$} 35 | \addtolength{\fracwid}{0.1in} 36 | \begin{tabular}[b]{@{}c@{}} 37 | $#1$\\ 38 | \parbox[c][0.02in][t]{\fracwid}{\dotfill} \\ 39 | $#2$\\ 40 | \end{tabular}} 41 | \newcommand{\Rule}[2]{\savebox{\rulebox}[\width][b] % 42 | {\( \frac{\raisebox{0in} {\( #1 \)}} % 43 | {\raisebox{-0.03in}{\( #2 \)}} \)} % 44 | \settoheight{\ruleheight}{\usebox{\rulebox}} % 45 | \addtolength{\ruleheight}{\rulevgap} % 46 | \settodepth{\ruledepth}{\usebox{\rulebox}} % 47 | \addtolength{\ruledepth}{\rulevgap} % 48 | \raisebox{0in}[\ruleheight][\ruledepth] % 49 | {\usebox{\rulebox}}} 50 | \newcommand{\Case}[2]{\savebox{\rulebox}[\width][b] % 51 | {\( \dotfrac{\raisebox{0in} {\( #1 \)}} % 52 | {\raisebox{-0.03in}{\( #2 \)}} \)} % 53 | \settoheight{\ruleheight}{\usebox{\rulebox}} % 54 | \addtolength{\ruleheight}{\rulevgap} % 55 | \settodepth{\ruledepth}{\usebox{\rulebox}} % 56 | \addtolength{\ruledepth}{\rulevgap} % 57 | \raisebox{0in}[\ruleheight][\ruledepth] % 58 | {\usebox{\rulebox}}} 59 | \newcommand{\Axiom}[1]{\savebox{\rulebox}[\width][b] % 60 | {$\frac{}{\raisebox{-0.03in}{$#1$}}$} % 61 | \settoheight{\ruleheight}{\usebox{\rulebox}} % 62 | \addtolength{\ruleheight}{\rulevgap} % 63 | \settodepth{\ruledepth}{\usebox{\rulebox}} % 64 | \addtolength{\ruledepth}{\rulevgap} % 65 | \raisebox{0in}[\ruleheight][\ruledepth] % 66 | {\usebox{\rulebox}}} 67 | \newcommand{\RuleSide}[3]{\gap{$#2$} \hspace*{0.1in} % 68 | \Rule{#1}{#3} % 69 | \hspace*{0.1in}$#2$} 70 | \newcommand{\AxiomSide}[2]{\gap{$#1$} \hspace*{0.1in} % 71 | \Axiom{#2} % 72 | \hspace*{0.1in}$#1$} 73 | \newcommand{\RULE}[1]{\textbf{#1}} 74 | \newcommand{\hg}{\hspace{0.2in}} 75 | 76 | \newcommand{\ProofState} 77 | [2]{\parbox{10cm}{\AR{\hg\AR{#1}\\\Axiom{\hg#2\hg}}}} 78 | 79 | %%%%%%%%%%%% TRISTUFF 80 | 81 | \newcommand{\btr}{ 82 | \setlength{\unitlength}{0.0005in} 83 | \begin{picture}(69,180)(0,12) 84 | \blacken\path(57,192)(57,12)(12,102) 85 | (57,192)(57,192) 86 | \path(57,192)(57,12)(12,102) 87 | (57,192)(57,192) 88 | \end{picture} 89 | } 90 | 91 | \newcommand{\btl}{ 92 | \setlength{\unitlength}{0.0005in} 93 | \begin{picture}(69,180)(0,12) 94 | \blacken\path(12,192)(12,12)(57,102) 95 | (12,192)(12,192)\path(12,192)(12,12)(57,102) 96 | (12,192)(12,192) 97 | \end{picture} 98 | } 99 | 100 | \newcommand{\wtr}{ 101 | \setlength{\unitlength}{0.0005in} 102 | \begin{picture}(69,180)(0,12) 103 | %\blacken\path(57,192)(57,12)(12,102) 104 | % (57,192)(57,192) 105 | \path(57,192)(57,12)(12,102) 106 | (57,192)(57,192) 107 | \end{picture} 108 | } 109 | 110 | \newcommand{\wtl}{ 111 | \setlength{\unitlength}{0.0005in} 112 | \begin{picture}(69,180)(0,12) 113 | %\blacken\path(12,192)(12,12)(57,102) 114 | % (12,192)(12,192) 115 | \path(12,192)(12,12)(57,102) 116 | (12,192)(12,192) 117 | \end{picture} 118 | } 119 | 120 | 121 | 122 | %%%%%%%%%%%% FONTS 123 | 124 | \newcommand{\TC}[1]{\mathsf{#1}} 125 | \newcommand{\DC}[1]{\mathsf{#1}} 126 | \newcommand{\VV}[1]{\mathit{#1}} 127 | \newcommand{\FN}[1]{\mathbf{#1}} 128 | \newcommand{\HFN}[1]{\mathtt{#1}} 129 | \newcommand{\RW}[1]{\underline{\textrm{#1}}} 130 | \newcommand{\MO}[1]{\mbox{\textsc{#1}}} 131 | 132 | \newcommand{\tTC}[1]{\texttt{#1}} 133 | \newcommand{\tDC}[1]{\texttt{#1}} 134 | \newcommand{\tFN}[1]{\texttt{#1}} 135 | 136 | \newcommand{\HF}[1]{\mathtt{#1}} 137 | 138 | \newcommand{\MV}[1]{\nhole\mathit{#1}} 139 | \newcommand{\Lang}[1]{\mathsf{#1}} 140 | \newcommand{\Name}[1]{\mathit{#1}} 141 | 142 | \newcommand{\demph}[1]{\textbf{#1}} 143 | \newcommand{\remph}[1]{\emph{#1}} 144 | 145 | %%%% Keywords for meta operations 146 | \newcommand{\IF}{\;\RW{if}\;\;} 147 | \newcommand{\THEN}{\RW{then}} 148 | \newcommand{\ELSE}{\RW{else}} 149 | \newcommand{\AND}{\RW{and}} 150 | \newcommand{\Otherwise}{\RW{otherwise}} 151 | \newcommand{\Do}{\RW{do}} 152 | \newcommand{\Return}{\RW{return}} 153 | 154 | \newcommand{\CASE}{\RW{case}} 155 | \newcommand{\LET}{\RW{let}} 156 | \newcommand{\IN}{\RW{in}} 157 | \newcommand{\of}{\RW{of}} 158 | 159 | \newcommand{\CLASS}{\mathtt{class}} 160 | \newcommand{\INSTANCE}{\mathtt{instance}} 161 | 162 | %%%%%%%%%%%% GROUPING 163 | 164 | \newcommand{\G}{ 165 | \setlength{\unitlength}{1pt} 166 | \begin{picture}(4,10)(0,0) 167 | \path(2,10)(2,-10) 168 | \end{picture} 169 | } 170 | 171 | \newcommand{\E}{ 172 | \setlength{\unitlength}{1pt} 173 | \begin{picture}(4,10)(0,0) 174 | \path(2,10)(2,-2)(4,-2) 175 | \end{picture} 176 | } 177 | 178 | %\newcommand{\C}{ 179 | %\setlength{\unitlength}{1pt} 180 | %\begin{picture}(4,10)(0,0) 181 | %\path(4,8)(2,8)(2,-2)(4,-2) 182 | %\end{picture} 183 | %} 184 | 185 | \newcommand{\M}{ 186 | \setlength{\unitlength}{1pt} 187 | \begin{picture}(4,10)(0,0) 188 | \path(2,10)(2,-2)(6,-2) 189 | \end{picture} 190 | } 191 | 192 | \newcommand{\F}{ 193 | \setlength{\unitlength}{1pt} 194 | \begin{picture}(4,10)(0,0) 195 | \path(4,8)(2,8)(2,-6) 196 | \end{picture} 197 | } 198 | 199 | \newcommand{\K}{ 200 | \setlength{\unitlength}{1pt} 201 | \begin{picture}(4,10)(0,0) 202 | \path(0,8)(4,8) 203 | \end{picture} 204 | } 205 | 206 | \newcommand{\J}{ 207 | \setlength{\unitlength}{1pt} 208 | \begin{picture}(4,10)(0,0) 209 | \path(0,-2)(4,-2) 210 | \end{picture} 211 | } 212 | 213 | \newcommand{\W}{ 214 | \setlength{\unitlength}{1pt} 215 | \begin{picture}(4,10)(0,0) 216 | \end{picture} 217 | } 218 | 219 | 220 | 221 | %%%%%%%%%%%% GUBBINS 222 | 223 | \newcommand{\mathskip}{\medskip} 224 | 225 | \newcommand{\fbx}[1]{\fbox{$#1$}} 226 | \newcommand{\stk}[1]{\begin{array}{c}#1\end{array}} 227 | %\newcommand{\DM}[1]{\hg\mbox{$#1$}} 228 | \newcommand{\DM}[1]{\mathskip\par\(#1\)\mathskip} 229 | \newcommand{\mbx}[1]{\mathskip\par\noindent\(#1\)\mathskip} 230 | \newcommand{\AR}[1]{\begin{array}[t]{@{}l}#1\end{array}} 231 | \newcommand{\ARt}[1]{\begin{array}[t]{@{}l@{}cl}#1\end{array}} 232 | \newcommand{\ARc}[1]{\begin{array}{@{}l}#1\end{array}} 233 | \newcommand{\ARd}[1]{\begin{array}[t]{cl}#1\end{array}} 234 | \newcommand{\DAR}[1]{\begin{array}{ll}\hg & #1\end{array}} 235 | \newcommand{\Dor}{\\ \hg\mid & } 236 | \newcommand{\EA}[1]{\begin{array}[t]{r@{}c@{}l}#1\end{array}} 237 | \newcommand{\A}{@{\:}c} 238 | %\newcommand{\R}{@{\:}r} 239 | \newcommand{\CA}{c} 240 | \newcommand{\LA}{l} 241 | \newcommand{\PAc}[2]{\begin{array}{l#1@{}r@{}l}#2\end{array}} 242 | \newcommand{\PA}[2]{\begin{array}[t]{l@{\:}l#1@{}r@{\:}l}#2\end{array}} 243 | \newcommand{\DTREE}[3]{\begin{array}[t]{l#1@{}r@{\:}l#2}#3\end{array}} 244 | \newcommand{\IDTREE}[2]{% 245 | \begin{array}[t]{l@{\:}c@{\:}l@{\:}r@{\:}l#1}#2\end{array}} 246 | \newcommand{\IA}[2] 247 | {\begin{array}[t]{l@{\:}r@{\:}c@{\:}l@{\:}#1@{\:}r@{\:}l}#2\end{array}} 248 | \newcommand{\IAc}[2] 249 | {\begin{array}[c]{r@{\:}c@{\:}l@{\:}#1@{}r@{}l}#2\end{array}} 250 | \newcommand{\CS}[1]{\left\lfloor\begin{array}{@{}l}#1\end{array}\right.} 251 | \newcommand{\BY}[3]{\multicolumn{2}{l}{\;\RW{by}\; #1} \\ % 252 | \multicolumn{#2}{l}{\CS{#3}} } 253 | \newcommand{\WITH}[3]{\multicolumn{2}{l}{\;\RW{with}\; #1} \\ % 254 | \multicolumn{#2}{l}{\CS{#3}} } 255 | \newcommand{\WithBy}{\RW{with-by}} 256 | \newcommand{\Wb}[1]{\WithBy& #1} 257 | \newcommand{\By}[1]{\multicolumn{2}{l}{\Leftarrow #1}} 258 | \newcommand{\andby}{\Leftarrow} 259 | \newcommand{\MyWith}[1]{\multicolumn{2}{l}{|\;#1}} 260 | \newcommand{\Byr}[1]{\;\RW{by}\; #1} 261 | 262 | \newcommand{\Bar}{|} 263 | \newcommand{\Bart}{\settowidth{\GapLength}{$\Bar$}% 264 | \raisebox{6pt}[0pt][0pt]{$\Bar$}% 265 | \hspace*{-1\GapLength}% 266 | \Bar} 267 | \newcommand{\With}[1]{\Bar & #1} 268 | \newcommand{\Witt}[1]{\Bart & #1} 269 | 270 | \newcommand{\B}{@{\:}r@{\:}c} 271 | \newcommand{\Ret}[1]{\multicolumn{2}{l}{\cq #1}} 272 | \newcommand{\MRet}[2]{\multicolumn{#1}{l}{\cq #2}} 273 | \newcommand{\HRet}[1]{\multicolumn{2}{l}{\hq #1}} 274 | \newcommand{\MHRet}[2]{\multicolumn{#1}{l}{\hq #2}} 275 | \newcommand{\IRet}[1]{\multicolumn{2}{l}{\iq #1}} 276 | \newcommand{\IMRet}[2]{\multicolumn{#1}{l}{\iq #2}} 277 | \newcommand{\MoRet}[1]{\multicolumn{2}{l}{\mq #1}} 278 | \newcommand{\MMoRet}[2]{\multicolumn{#1}{l}{\mq #2}} 279 | \newcommand{\Data}{\RW{data}} 280 | \newcommand{\Codata}{\RW{codata}} 281 | \newcommand{\Where}{\RW{where}} 282 | \newcommand{\Let}{\RW{let}} 283 | \newcommand{\Fact}{\RW{fact}} 284 | \newcommand{\Rec}[1]{#1\textbf{-Rec}} 285 | \newcommand{\Memo}[1]{#1\textbf{-Memo}} 286 | \newcommand{\Elim}[1]{#1\textbf{-Elim}} 287 | \newcommand{\Cases}[1]{#1\textbf{-Case}} 288 | \newcommand{\View}[1]{#1\textbf{-View}} 289 | \newcommand{\As}[2]{#1 \:\RW{as}\: #2} 290 | \newcommand{\nhole}{\Box} 291 | \newcommand{\turq}{\:\vdash_?\:} 292 | \newcommand{\split}{\;\lhd\;} 293 | \newcommand{\CType}[2]{\{#1 \split\; #2\}} 294 | \newcommand{\CC}[2]{(#1)\:#2} 295 | \newcommand{\UP}[2]{#1 | \{#2\}} 296 | \newcommand{\Ured}{\:\Downarrow\:} 297 | \newcommand{\gdd}{\prec} 298 | \newcommand{\HC}[1]{\left<#1\right>} 299 | \newcommand{\HT}[2]{\left<#1 \hab #2\right>} 300 | 301 | \newcommand{\view}{\RW{view}} 302 | \newcommand{\ecase}{\RW{case}} 303 | \newcommand{\rec}{\RW{rec}} 304 | 305 | \newcommand{\If}{\mathsf{if}} 306 | \newcommand{\Then}{\mathsf{then}} 307 | \newcommand{\Else}{\mathsf{else}} 308 | \newcommand{\elim}{\RW{elim}} 309 | 310 | \newcommand{\Payload}{\mathsf{type}} 311 | \newcommand{\Any}{\mathsf{Some}} 312 | 313 | \newcommand{\lbl}[2]{\langle #1 \Hab #2 \rangle} 314 | \newcommand{\call}[2]{\RW{call}\:\langle#1\rangle\:#2} 315 | \newcommand{\return}[1]{\RW{return}\:#1} 316 | 317 | \newcommand{\Remark}[1]{\noindent\textbf{Remark:} #1} 318 | 319 | \newcommand{\DBOX}[2]{\fbox{\parbox{#1}{\textbf{Definition:}#2}}} 320 | 321 | \ifthenelse{\boolean{useverb}}{% 322 | \newcommand{\useverbtb}[1]{\begin{tiny}\BUseVerbatim{#1}\end{tiny}} 323 | \newcommand{\useverb}[1]{\BUseVerbatim{#1}} 324 | \newcommand{\useverbs}[1]{\begin{small}\BUseVerbatim{#1}\end{small}} 325 | \newcommand{\useverbb}[1]{\begin{small}\BUseVerbatim{#1}\end{small}} 326 | \newcommand{\codefig}[2]{\begin{figure}[h]\useverb{#1}\caption{#2}\label{#1}\end{figure}} 327 | \newcommand{\codefigs}[2]{\begin{figure}[h]\useverbs{#1}\caption{#2}\label{#1}\end{figure}} 328 | \newcommand{\codefigt}[2]{\begin{figure}[t]\useverb{#1}\caption{#2}\label{#1}\end{figure}} 329 | \newcommand{\codefigb}[2]{\begin{figure}[b]\useverb{#1}\caption{#2}\label{#1}\end{figure}} 330 | \newcommand{\codefigtc}[2]{\begin{figure*}[t]\useverb{#1}\caption{#2}\label{#1}\end{figure}} 331 | }{} 332 | 333 | \newcommand{\diagfig}[3]{\begin{figure}[h]\begin{center}\includegraphics[width=#1]{#2}\end{center} 334 | \caption{#3}\label{#2}\end{figure}} 335 | \newcommand{\diagfigtc}[3]{\begin{figure*}[t]\begin{center}\includegraphics[width=#1]{#2}\end{center} 336 | \caption{#3}\label{#2}\end{figure*}} 337 | 338 | \newcommand{\FIG}[3]{\begin{figure}[h]\DM{#1}\caption{#2}\label{#3}\end{figure}} 339 | \newcommand{\FFIG}[3]{\begin{figure}\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure}} 340 | \newcommand{\FFIGB}[3]{\begin{figure}[b]\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure}} 341 | \newcommand{\FFIGTC}[3]{\begin{figure*}[t]\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure*}} 342 | \newcommand{\PFIG}[3]{\begin{figure}[p]\begin{center}\fbox{\DM{#1}}\end{center}\caption{#2}\label{#3}\end{figure}} 343 | \newcommand{\CFIG}[3]{\begin{figure}[h]\begin{center}\DM{#1}\end{center}\caption{#2}\label{#3}\end{figure}} 344 | 345 | \ifthenelse{\boolean{useverb}}{% 346 | \newcommand{\VFIG}[3]{\begin{figure}[h]\begin{boxedverbatim}#1\end{boxedverbatim}\caption{#2}\label{#3}\end{figure}} 347 | }{} 348 | 349 | \newcommand{\TFIG}[4]{\begin{figure}[h]\begin{center}\begin{tabular}{#1}#2\end{tabular}\end{center}\caption{#3}\label{#4}\end{figure}} 350 | \newcommand{\TFIGTC}[4]{\begin{figure*}[t]\begin{center}\begin{tabular}{#1}#2\end{tabular}\end{center}\caption{#3}\label{#4}\end{figure*}} 351 | 352 | \newcommand{\RESFIG}[3]{ 353 | \TFIG{|l|c|c|c|c|c|c|c|c|}{ 354 | \hline 355 | & \multicolumn{4}{c|}{\Naive{} compilation} & 356 | \multicolumn{4}{|c|}{Optimised compilation} \\ 357 | \cline{2-9} 358 | \raisebox{1.5ex}[0pt]{Program} & Instrs & Thunks & Cells & 359 | Accesses & Instructions & Thunks & Cells & Accesses \\ 360 | %\raisebox{1.5ex}[0pt]{Program} & I & T & C & M & I & T & C & M \\ 361 | \hline 362 | #1 363 | \hline 364 | }{#2}{#3}} 365 | 366 | \newcommand{\NEWRESFIG}[3]{ 367 | \TFIG{|l|l|c|c|c|c|}{ 368 | \hline 369 | % & \multicolumn{4}{c|}{\Naive{} compilation} & 370 | % \multicolumn{4}{|c|}{Optimised compilation} \\ 371 | %\cline{2-9} 372 | Program & Version & Instructions & Thunks & Memory Accesses & Cells \\ 373 | %\raisebox{1.5ex}[0pt]{Program} & I & T & C & M & I & T & C & M \\ 374 | \hline 375 | #1 376 | }{#2}{#3}} 377 | 378 | \newcommand{\NEWRESFIGTC}[3]{ 379 | \TFIGTC{|l|l|c|c|c|c|}{ 380 | \hline 381 | % & \multicolumn{4}{c|}{\Naive{} compilation} & 382 | % \multicolumn{4}{|c|}{Optimised compilation} \\ 383 | %\cline{2-9} 384 | Program & Version & Instructions & Thunks & Memory Accesses & Cells \\ 385 | %\raisebox{1.5ex}[0pt]{Program} & I & T & C & M & I & T & C & M \\ 386 | \hline 387 | #1 388 | }{#2}{#3}} 389 | 390 | \newcommand{\RESLINE}[9]{ 391 | & \Naive{} & #2 & #3 & #5 & #4 \\ 392 | #1 393 | & Optimised & #6 & #7 & #9 & #8 \\ 394 | } 395 | \newcommand{\RESCHANGE}[4]{ 396 | & Change & \textbf{#1} & \textbf{#2} & \textbf{#4} & \textbf{#3} \\ 397 | \hline 398 | } 399 | \newcommand{\RESCHANGEa}[5]{ 400 | #5 & Change & \textbf{#1} & \textbf{#2} & \textbf{#4} & \textbf{#3} \\ 401 | \hline 402 | } 403 | 404 | %%%%%%%%%%%% PUNCTUATION 405 | 406 | \newcommand{\pad}[2]{#1#2#1} 407 | 408 | \newcommand{\hab}{\pad{\,}{:}} 409 | \newcommand{\Hab}{\pad{\;}{:}} 410 | \newcommand{\HHab}{\pad{\;}{::}} 411 | 412 | %%%%%%%%%%%% TYPE 413 | 414 | \newcommand{\Type}{\mbox{\texttt{\#}}} %\star} 415 | 416 | 417 | %%%%%%%%%%%%% ARROWS 418 | 419 | \newcommand{\To}{\pad{\:}{\rightarrow}} 420 | \newcommand{\Gets}{\leftarrow} 421 | %\newcommand{\car}{\vartriangleright} 422 | 423 | %%%%%%%%%%%%% QUANTIFIERS 424 | 425 | \newcommand{\lam}[2]{\lambda#1\pad{\!}{:}#2} 426 | \newcommand{\fbind}[3]{(#1\Hab#2)\to#3} 427 | \newcommand{\all}[2]{\forall#1\pad{\!}{:}#2} 428 | \newcommand{\hole}[2]{?#1\pad{\!}{:}#2} 429 | \newcommand{\guess}[3]{?#1\pad{\!}{:}#2\approx#3} 430 | \newcommand{\remlam}[2]{\lambda\{#1\pad{\!}{:}#2\}} 431 | \newcommand{\remall}[2]{\forall\{#1\pad{\!}{:}#2\}} 432 | \newcommand{\allpi}[2]{\Pi#1\pad{\!}{:}#2} 433 | \newcommand{\ali}[2]{\forall#1|#2} 434 | \newcommand{\exi}[2]{\exists#1\pad{\!}{:}#2} 435 | \newcommand{\wit}[2]{\ang{#1,#2}} 436 | \newcommand{\X}{\times} 437 | \newcommand{\sig}[2]{\Sigma#1\pad{\!}{:}#2} 438 | 439 | \newcommand{\SC}{.\:} 440 | 441 | \newcommand{\letbind}[3]{\mathsf{let}\:#1{:}#2\:=\:#3\:\mathsf{in}} 442 | \newcommand{\ifthen}[3]{\mathsf{if}\:#1\:\mathsf{then}\:#2\:\mathsf{else}\:#3} 443 | 444 | %%%%%%%%%%%%% EQUALITIES 445 | 446 | \newcommand{\cq}{\pad{\:}{\mapsto}} 447 | \newcommand{\xq}{\pad{}{\doteq}} 448 | \newcommand{\pq}{\pad{\:}{=}} 449 | \newcommand{\dq}{\pad{\:}{:=}} 450 | \newcommand{\iq}{\pad{\:}{\leadsto}} 451 | \newcommand{\mq}{\Longrightarrow} 452 | \newcommand{\retq}{\Rightarrow} 453 | \newcommand{\hq}{\pad{\:}{=}} 454 | \newcommand{\defq}{\mapsto} 455 | 456 | \newcommand{\refl}{\TC{Refl}} 457 | 458 | 459 | 460 | 461 | %%%%%%%%%%%%% CATSTUFF 462 | 463 | \newlength{\Lwibrs} 464 | \newlength{\Lwobrs} 465 | \newsavebox{\Bwibrs} 466 | \newsavebox{\Bwobrs} 467 | \newcommand{\Db}[5]{% 468 | \savebox{\Bwobrs}[\width][b]{$#5$}% 469 | \savebox{\Bwibrs}[\width][b]{$\left#2\usebox{\Bwobrs}\right#3$}% 470 | \settowidth{\Lwobrs}{\usebox{\Bwobrs}}% 471 | \settowidth{\Lwibrs}{\usebox{\Bwibrs}}% 472 | \addtolength{\Lwibrs}{-\Lwobrs}% 473 | \left#1\pad{\hspace*{-0.25\Lwibrs}}{\usebox{\Bwibrs}}\right#4} 474 | \newcommand{\LDb}[3]{% 475 | \savebox{\Bwobrs}[\width][b]{$#3$}% 476 | \savebox{\Bwibrs}[\width][b]{$\left#2\usebox{\Bwobrs}\right.$}% 477 | \settowidth{\Lwobrs}{\usebox{\Bwobrs}}% 478 | \settowidth{\Lwibrs}{\usebox{\Bwibrs}}% 479 | \addtolength{\Lwibrs}{-\Lwobrs}% 480 | \left#1\hspace*{-0.4\Lwibrs}\usebox{\Bwibrs}\right.} 481 | \newcommand{\RDb}[3]{% 482 | \savebox{\Bwobrs}[\width][b]{$#3$}% 483 | \savebox{\Bwibrs}[\width][b]{$\left.\usebox{\Bwobrs}\right#1$}% 484 | \settowidth{\Lwobrs}{\usebox{\Bwobrs}}% 485 | \settowidth{\Lwibrs}{\usebox{\Bwibrs}}% 486 | \addtolength{\Lwibrs}{-\Lwobrs}% 487 | \left.\usebox{\Bwibrs}\hspace*{-0.4\Lwibrs}\right#2} 488 | \newcommand{\Sc}{\Db{[}{[}{]}{]}} 489 | \newcommand{\Mo}{\Db{|}{>}{<}{|}} 490 | \newcommand{\MoL}{\LDb{|}{>}} 491 | \newcommand{\MoR}{\RDb{<}{|}} 492 | 493 | \newcommand{\car}{\mbox{$-\!\triangleright$}} 494 | \newcommand{\io}[1]{\iota_{#1}} 495 | \newcommand{\cc}{\diamond} 496 | 497 | 498 | %%%%%%%%%%%%% FNS 499 | 500 | \newcommand{\Wk}{\Uparrow} 501 | 502 | %%%%%%%%%%%%% Transformation 503 | 504 | \newcommand{\Transform}[3]{\textsc{Trans}\:_{\Name{#1}} 505 | \interp{#2}\:\mq\:#3} 506 | %\:[\:#2\:\Longrightarrow\:#3\:]} 507 | \newcommand{\Morphism}[2]{\textsc{Morphism}\:#1\:\Longrightarrow\:#2} 508 | \newcommand{\MI}[1]{\begin{array}{ll} #1 \end{array}\\} 509 | \newcommand{\MorphItem}[2]{& #1 \:\Longrightarrow\: #2} 510 | 511 | %%%%%%%%%%%%% Stuff 512 | 513 | % Motive and methods 514 | 515 | \newcommand{\motive}{\vP} 516 | \newcommand{\meth}[1]{\vm_{#1}} 517 | 518 | % Tuples 519 | \newcommand{\tuple}[1]{\langle#1\rangle} 520 | \newcommand{\Tuple}[1]{\mathsf{Tuple}} 521 | \newcommand{\proj}{\mathsf{proj}} 522 | \newcommand{\app}{\mathrm{+\!+}} 523 | 524 | % Commenting out 525 | \newcommand{\ig}[1]{[#1]} 526 | \newcommand{\rem}[1]{\{\!#1\!\}} 527 | \newcommand{\igc}[1]{[#1]} 528 | \newcommand{\remc}[1]{\{\!#1\!\}} 529 | 530 | 531 | \newcommand{\ind}{\hspace*{0.1cm}} 532 | 533 | % Content free type 534 | \newcommand{\CF}{\TC{CF}} 535 | \newcommand{\cf}{\DC{cf}} 536 | 537 | % Error token 538 | \newcommand{\error}{\DC{error}} 539 | \newcommand{\fail}{\perp} 540 | 541 | % Constructor stripping 542 | \newcommand{\conarg}[2]{#1!#2} 543 | 544 | \newcommand{\Vect}{\TC{Vect}} 545 | \newcommand{\VectM}{\TC{Vect^-}} 546 | \newcommand{\Vnil}{\DC{\epsilon}} 547 | \newcommand{\Vcons}{\DC{::}} 548 | 549 | \newcommand{\Vsnoc}{\DC{::}} 550 | 551 | \newcommand{\VnilM}{\DC{\epsilon^-}} 552 | \newcommand{\VconsM}{\DC{::^-}} 553 | 554 | \newcommand{\Vnilcase}{\VV{vNilCase}} 555 | \newcommand{\Vconscase}{\VV{vConsCase}} 556 | 557 | \newcommand{\DSigma}{\TC{Sigma}} 558 | \newcommand{\Exists}{\DC{Exists}} 559 | 560 | \newcommand{\ListPair}[2]{\sig{#1}{\List\:\vA}.#2 = \FN{length}\:#1} 561 | \newcommand{\lpNilDef}{\lpNil{\FN{Refl}\:\Z}} 562 | \newcommand{\lpNil}[1]{(\nil\:\vA,#1)} 563 | \newcommand{\lpConsDef}[3]{\lpCons{#1}{(\FN{fst\:#2})}{\FN{resp}\:(\FN{snd}\:#2)}} 564 | \newcommand{\lpCons}[3]{(\cons\:#1\:#2,#3)} 565 | \newcommand{\lp}[2]{(#1, #2)} 566 | 567 | \newcommand{\VnilTop}{\DC{vNil}^\ast} 568 | \newcommand{\VconsTop}{\DC{vCons}^\ast} 569 | 570 | \newcommand{\VnilBot}{\DC{\epsilon}^-} 571 | \newcommand{\VconsBot}{\DC{::}^-} 572 | 573 | \newcommand{\VectTop}{\TC{Vect}^\ast} 574 | \newcommand{\VectBot}{\TC{Vect}^-} 575 | 576 | \newcommand{\VectDrop}{\FN{vectDropIdx}} 577 | \newcommand{\VectRebuild}{\FN{vectRebuild}} 578 | 579 | \newcommand{\Prop}{\TC{Prop}} 580 | \newcommand{\Set}{\TC{Set}} 581 | \newcommand{\CoqType}{\TC{Type}} 582 | 583 | \newcommand{\List}{\TC{List}} 584 | \newcommand{\nil}{\DC{nil}} 585 | \newcommand{\cons}{\DC{cons}} 586 | 587 | \newcommand{\Zip}{\TC{Tsil}} 588 | \newcommand{\zip}{\FN{tsil}} 589 | \newcommand{\zipcons}{\FN{tsilcons}} 590 | \newcommand{\snoc}{\DC{Snoc}} 591 | \newcommand{\lin}{\DC{Empty}} 592 | 593 | \newcommand{\BigInt}{\TC{BigInt}} 594 | \newcommand{\False}{\TC{False}} 595 | \newcommand{\Unit}{\TC{Unit}} 596 | \newcommand{\UnitI}{\DC{unit}} 597 | 598 | \newcommand{\genType}{\TC{X}} 599 | \newcommand{\genIndicesDec}{\tb\Hab\tB} 600 | \newcommand{\genIndices}{\tb} 601 | \newcommand{\genConArgsDec}[1]{\vec{\VV{a_#1}}\Hab\vec{\VV{A_#1}}} 602 | \newcommand{\genConArgs}[1]{\vec{\VV{a_#1}}} 603 | \newcommand{\genConIndicesDec}[1]{\vec{\VV{b_#1}}\Hab\vec{\VV{B_#1}}} 604 | \newcommand{\genConIndices}[1]{\vec{\VV{b_#1}}} 605 | \newcommand{\genCon}[1]{\DC{x}_#1} 606 | 607 | \newcommand{\genTypeTop}{\TC{X^\ast}} 608 | \newcommand{\genTypeBot}{\TC{X^-}} 609 | 610 | \newcommand{\genTypeDrop}{\FN{XDropIdx}} 611 | \newcommand{\genTypeRebuild}{\FN{XRebuild}} 612 | 613 | \newcommand{\HTerm}{\texttt{Term}} 614 | \newcommand{\Term}{\TC{Term}} 615 | \newcommand{\Var}{\DC{var}} 616 | \newcommand{\Lam}{\DC{lam}} 617 | \newcommand{\App}{\DC{app}} 618 | \newcommand{\TermM}{\TC{Term^-}} 619 | \newcommand{\VarM}{\DC{var^-}} 620 | \newcommand{\LamM}{\DC{lam^-}} 621 | \newcommand{\AppM}{\DC{app^-}} 622 | \newcommand{\Env}{\TC{Env}} 623 | \newcommand{\SType}{\TC{STy}} 624 | \newcommand{\farrow}{\Rightarrow} 625 | \newcommand{\lookup}{\FN{lookup}} 626 | 627 | % \newcommand{\source}{\Lang{TT}} 628 | \newcommand{\source}{\textbf{DT-Res}} 629 | \newcommand{\target}{\Lang{ExTT}} 630 | \newcommand{\runtime}{\Lang{RunTT}} 631 | 632 | \newcommand{\lt}{\TC{<}} 633 | \newcommand{\ltO}{\DC{ltO}} 634 | \newcommand{\ltS}{\DC{ltS}} 635 | 636 | \newcommand{\interp}[1]{\llbracket #1 \rrbracket} 637 | \newcommand{\inferrable}[2]{\FN{inferrable}(#1,#2)} 638 | \newcommand{\mkPat}{\FN{mkPat}} 639 | 640 | \newcommand{\FinM}{\TC{Fin^-}} 641 | \newcommand{\fzM}{\DC{f0^-}} 642 | \newcommand{\fsM}{\DC{fs^-}} 643 | 644 | \newcommand{\concat}{\mathrm{++}} 645 | 646 | %\newcommand{\bottom}{\perp} 647 | 648 | % Reductions 649 | 650 | \newcommand{\reduces}{\mapsto} 651 | \newcommand{\translation}{\Rightarrow} 652 | %\newcommand{\reducesn}[1]{\reduces\hspace*{-0.15cm}_{#1}} 653 | %\newcommand{\reducesto}{\reduces\hspace*{-0.15cm}^{*}} 654 | \newcommand{\reducesn}[1]{\reduces_{#1}} 655 | \newcommand{\reducesto}{\reduces^{*}} 656 | 657 | % Equality 658 | 659 | \newcommand{\Refl}{\DC{Refl}} 660 | \newcommand{\leZ}{\DC{O_{\le}}} 661 | \newcommand{\leS}{\DC{S_{\le}}} 662 | 663 | % Random elimination things 664 | 665 | \newcommand{\lte}{\TC{\leq}} 666 | \newcommand{\lten}{\DC{leN}} 667 | \newcommand{\lteO}{\DC{leO}} 668 | \newcommand{\lteS}{\DC{leS}} 669 | 670 | \newcommand{\ltelim}{\Elim{\lt}} 671 | \newcommand{\leelim}{\Elim{\lte}} 672 | 673 | \newcommand{\dD}{\TC{D}} 674 | \newcommand{\delim}{\Elim{\TC{D}}} 675 | \newcommand{\drec}{\Rec{\TC{D}}} 676 | \newcommand{\dcase}{\Cases{\TC{D}}} 677 | \newcommand{\dview}{\View{\TC{D}}} 678 | \newcommand{\dmemo}{\Memo{\TC{D}}} 679 | \newcommand{\natrec}{\Rec{\Nat}} 680 | \newcommand{\natmemo}{\Memo{\Nat}} 681 | \newcommand{\natmemogen}{\Nat\textbf{-MemoGen}} 682 | \newcommand{\natelim}{\Elim{\Nat}} 683 | \newcommand{\boolcase}{\Cases{\Bool}} 684 | \newcommand{\vectrec}{\Rec{\Vect}} 685 | \newcommand{\vectelim}{\Elim{\Vect}} 686 | \newcommand{\listrec}{\Rec{\List}} 687 | \newcommand{\listelim}{\Elim{\List}} 688 | \newcommand{\finrec}{\Rec{\Fin}} 689 | \newcommand{\finelim}{\Elim{\Fin}} 690 | \newcommand{\natcase}{\Cases{\Nat}} 691 | \newcommand{\vectcase}{\Cases{\Vect}} 692 | \newcommand{\natdoublerec}{\Nat\textbf{-double-elim}} 693 | \newcommand{\eqelim}{=\textbf{-elim}} 694 | \newcommand{\falsecase}{\Cases{\False}} 695 | 696 | % Code 697 | \ifthenelse{\boolean{useverb}}{% 698 | \newcommand{\Haskell}[1]{\begin{quotation}\begin{verbatim}#1\end{verbatim}\end{quotation}} 699 | }{} 700 | % Quicksort 701 | 702 | \newcommand{\QSView}{\TC{QuickSort}} 703 | \newcommand{\qsempty}{\DC{empty}} 704 | \newcommand{\partition}{\DC{partition}} 705 | \newcommand{\qsview}{\FN{mkQuickSort}} 706 | 707 | % More gubbins 708 | 709 | \newcommand{\converts}{\simeq} 710 | \newcommand{\cumul}{\preceq} 711 | \newcommand{\whnf}{\Downarrow} 712 | \newcommand{\elem}{\in} 713 | \newcommand{\proves}{\vdash} 714 | \newcommand{\biimplies}{\Longleftrightarrow} 715 | 716 | \newcommand{\lc}{\lambda_{\mathsf{AC}}} 717 | \newcommand{\zed}{\mathbb{Z}} 718 | 719 | % Haskell keywords 720 | 721 | \newcommand{\hdata}{\mathtt{data}} 722 | \newcommand{\newtype}{\mathtt{newtype}} 723 | %\newcommand{\htype}{\mathtt{type}} 724 | 725 | \newcommand{\HTC}[1]{\mathtt{#1}} 726 | \newcommand{\HDC}[1]{\mathtt{#1}} 727 | 728 | % Nobby 729 | 730 | \newcommand{\Value}{\HTC{Value}} 731 | \newcommand{\VGamma}{\HTC{Env}} 732 | \newcommand{\Ctxt}{\HTC{Ctxt}} 733 | \newcommand{\Defs}{\HTC{Defs}} 734 | \newcommand{\ECtxt}{\HTC{ECtxt}} 735 | \newcommand{\TCtxt}{\HTC{TCtxt}} 736 | \newcommand{\VG}{\HDC{Env}} 737 | \newcommand{\Model}{\HTC{Model}} 738 | \newcommand{\Const}{\HTC{Const}} 739 | \newcommand{\Normal}{\HTC{Normal}} 740 | \newcommand{\Scope}{\HTC{Scope}} 741 | \newcommand{\Kripke}{\HTC{Kripke}} 742 | \newcommand{\Weakening}{\HTC{Weakening}} 743 | \newcommand{\Ready}{\HTC{Ready}} 744 | \newcommand{\Blocked}{\HTC{Blocked}} 745 | \newcommand{\Spine}{\HTC{Spine}} 746 | 747 | \newcommand{\BV}{\HDC{BV}} 748 | \newcommand{\BCon}{\HDC{BCon}} 749 | \newcommand{\BTyCon}{\HDC{BTyCon}} 750 | \newcommand{\RCon}{\HDC{RCon}} 751 | \newcommand{\RTyCon}{\HDC{RTyCon}} 752 | \newcommand{\BElim}{\HDC{BElim}} 753 | \newcommand{\DV}{\HDC{V}} 754 | \newcommand{\DP}{\HDC{P}} 755 | 756 | \newcommand{\MR}{\HDC{R}} 757 | \newcommand{\MB}{\HDC{B}} 758 | \newcommand{\DSc}{\HDC{Sc}} 759 | \newcommand{\DKr}{\HDC{Kr}} 760 | \newcommand{\DWk}{\HDC{Wk}} 761 | \newcommand{\DSnoc}{\HDC{;}} 762 | \newcommand{\DType}{\HDC{Type}} 763 | \newcommand{\DName}{\HDC{Name}} 764 | \newcommand{\DInt}{\HDC{Int}} 765 | \newcommand{\DString}{\HDC{String}} 766 | \newcommand{\DElim}{\HDC{Elim}} 767 | \newcommand{\Empty}{\HDC{\emptyset}} 768 | 769 | \newcommand{\ConCode}{\HTC{ConCode}} 770 | \newcommand{\ElimRule}{\HTC{ElimRule}} 771 | 772 | \newcommand{\DConst}{\HDC{Const}} 773 | \newcommand{\DCon}{\HDC{Con}} 774 | \newcommand{\DTyCon}{\HDC{TyCon}} 775 | \newcommand{\RConst}{\HDC{RConst}} 776 | \newcommand{\RLam}{\HDC{RLam}} 777 | \newcommand{\RPi}{\HDC{RPi}} 778 | \newcommand{\DLam}{\HDC{Lam}} 779 | \newcommand{\DLet}{\HDC{Let}} 780 | \newcommand{\DPi}{\HDC{Pi}} 781 | \newcommand{\DApp}{\HDC{App}} 782 | 783 | \newcommand{\TMaybe}{\HTC{Maybe}} 784 | \newcommand{\DNothing}{\HDC{Nothing}} 785 | \newcommand{\DJust}{\HDC{Just}} 786 | 787 | 788 | % G-machine and heap 789 | 790 | \newcommand{\PUSH}{\mathsf{PUSH}} 791 | \newcommand{\PUSHNAME}{\mathsf{PUSHNAME}} 792 | \newcommand{\POP}{\mathsf{DISCARD}} 793 | \newcommand{\PUSHFUN}{\mathsf{PUSHFUN}} 794 | \newcommand{\APPLY}{\mathsf{MKAP}} 795 | \newcommand{\EVAL}{\mathsf{EVAL}} 796 | \newcommand{\GCON}{\mathsf{MKCON}} 797 | \newcommand{\GTUP}{\mathsf{MKTUP}} 798 | \newcommand{\GTYPE}{\mathsf{MKTYPE}} 799 | \newcommand{\UPDATE}{\mathsf{UPDATE}} 800 | \newcommand{\RET}{\mathsf{RET}} 801 | \newcommand{\UNWIND}{\mathsf{UNWIND}} 802 | \newcommand{\CASEJUMP}{\mathsf{CASEJUMP}} 803 | \newcommand{\LABEL}{\mathsf{LABEL}} 804 | \newcommand{\MOVE}{\mathsf{MOVE}} 805 | \newcommand{\JUMP}{\mathsf{JUMP}} 806 | \newcommand{\SPLIT}{\mathsf{SPLIT}} 807 | \newcommand{\SQUEEZE}{\mathsf{SQUEEZE}} 808 | \newcommand{\JFUN}{\mathsf{JFUN}} 809 | \newcommand{\PROJ}{\mathsf{PROJ}} 810 | \newcommand{\ERROR}{\mathsf{ERROR}} 811 | \newcommand{\SLIDE}{\mathsf{SLIDE}} 812 | \newcommand{\ALLOC}{\mathsf{ALLOC}} 813 | 814 | \newcommand{\PUSHBIG}{\mathsf{PUSHBIG}} 815 | \newcommand{\PUSHBASIC}{\mathsf{PUSHBASIC}} 816 | \newcommand{\PUSHINT}{\mathsf{PUSHINT}} 817 | \newcommand{\PUSHBOOL}{\mathsf{PUSHBOOL}} 818 | \newcommand{\GET}{\mathsf{GET}} 819 | \newcommand{\MKINT}{\mathsf{MKINT}} 820 | \newcommand{\MKBOOL}{\mathsf{MKBOOL}} 821 | \newcommand{\ADD}{\mathsf{ADD}} 822 | \newcommand{\SUB}{\mathsf{SUB}} 823 | \newcommand{\MULT}{\mathsf{MULT}} 824 | \newcommand{\LT}{\mathsf{LT}} 825 | \newcommand{\EQ}{\mathsf{EQ}} 826 | \newcommand{\GT}{\mathsf{GT}} 827 | \newcommand{\JTRUE}{\mathsf{JTRUE}} 828 | 829 | \newcommand{\APP}{\mathsf{APP}} 830 | \newcommand{\FUN}{\mathsf{FUN}} 831 | \newcommand{\CON}{\mathsf{CON}} 832 | \newcommand{\TYCON}{\mathsf{TYCON}} 833 | \newcommand{\TUP}{\mathsf{TUP}} 834 | \newcommand{\TYPE}{\mathsf{TYPE}} 835 | \newcommand{\INT}{\mathsf{INT}} 836 | \newcommand{\BIGINT}{\mathsf{BIGINT}} 837 | \newcommand{\BOOL}{\mathsf{BOOL}} 838 | \newcommand{\HOLE}{\mathsf{HOLE}} 839 | 840 | % G machine translation scheme 841 | 842 | \newcommand{\sinterp}[1]{\mathcal{S}\interp{#1}} 843 | \newcommand{\sinterpm}[1]{\mathcal{S}\AR{\interp{#1}}} 844 | \newcommand{\einterp}[3]{\mathcal{E}\interp{#1}\:#2\:#3} 845 | \newcommand{\cinterp}[3]{\mathcal{C}\interp{#1}\:#2\:#3} 846 | \newcommand{\binterp}[3]{\mathcal{B}\interp{#1}\:#2\:#3} 847 | \newcommand{\rinterp}[3]{\mathcal{R}\interp{#1}\:#2\:#3} 848 | \newcommand{\iinterp}[3]{\mathcal{I}\interp{#1}\:#2\:#3} 849 | \newcommand{\len}[1]{\MO{length}(#1)} 850 | 851 | \newcommand{\casecomp}[2]{\mathcal{I}(#1,\left\{\ARc{#2}\right\})} 852 | \newcommand{\casecompA}[3]{\mathcal{I}(#1,\left\{\ARc{#2}\right\}[#3])} 853 | \newcommand{\ischeme}{\mathcal{I}} 854 | 855 | % tail call markup 856 | 857 | \newcommand{\tailcall}{\mathsf{tail}} 858 | 859 | % Trees 860 | 861 | \newcommand{\Tree}{\TC{Tree}} 862 | \newcommand{\Leaf}{\DC{Leaf}} 863 | \newcommand{\Node}{\DC{Node}} 864 | \newcommand{\treecase}{\Cases{\Tree}} 865 | 866 | % Languages 867 | 868 | \newcommand{\Coq}{\textsc{Coq}} 869 | \newcommand{\Lego}{\textsc{Lego}} 870 | \newcommand{\Oleg}{\textsc{Oleg}} 871 | \newcommand{\Alf}{\textsc{Alf}} 872 | \newcommand{\Epigram}{\textsc{Epigram}} 873 | \newcommand{\SystemF}{System $\mathcal{F}$} 874 | \newcommand{\Iswim}{\textsc{Iswim}} 875 | \newcommand{\Cynthia}{\textit{C$^Y$\hspace*{-0.1cm}NTHIA}} 876 | 877 | % Accessibility 878 | 879 | \newcommand{\Acc}{\TC{Acc}} 880 | \newcommand{\acc}{\DC{acc}} 881 | \newcommand{\qsAcc}{\TC{qsAcc}} 882 | \newcommand{\qsNil}{\DC{qsNil}} 883 | \newcommand{\qsCons}{\DC{qsCons}} 884 | \newcommand{\allQsAcc}{\FN{allQsAcc}} 885 | 886 | % Lazy shortcuts 887 | 888 | \newcommand{\naive}{na\"{\i}ve} 889 | \newcommand{\Naive}{Na\"{\i}ve} 890 | 891 | % Conor's bits 892 | 893 | \newcommand{\remem}[1]{\left|#1\right|} 894 | \newcommand{\idsb}{\MO{id}} 895 | \newcommand{\ang}[1]{\langle#1\rangle} 896 | 897 | \newcommand{\vePm}[1]{\vP #1 \vm_{\Vnil} #1 \vm_{\Vcons}}% 898 | \newcommand{\vcrhs}{\vm_{\Vcons}\:\vk\:\va\:\vv\:% 899 | (\vectelim\:\vA\:\vk\:\vv\:\vePm{\:})}% 900 | 901 | \newcommand{\igV}[2]{#1^{\ig{#2}}} 902 | \newcommand{\remV}[2]{#1^{\rem{#2}}} 903 | 904 | % More gubbins 905 | 906 | \newcommand{\Between}{\TC{between}} 907 | \newcommand{\bZ}{\DC{bO}} 908 | \newcommand{\bZZS}{\DC{bOOs}} 909 | \newcommand{\bZSS}{\DC{b0ss}} 910 | \newcommand{\bSSS}{\DC{bsss}} 911 | \newcommand{\betelim}{\Elim{\Between}} 912 | \newcommand{\betrhs}[1]{\motive#1\meth{\bZ}#1\meth{\bZZS}#1\meth{\bZSS}#1\meth{\bSSS}} 913 | 914 | 915 | \newcommand{\valenv}{\TC{ValEnv}} 916 | \newcommand{\vempty}{\DC{empty}} 917 | \newcommand{\vextend}{\DC{extend}} 918 | 919 | \newcommand{\EpiVal}{\TC{Epigram}} 920 | \newcommand{\unsafeCoerce}{\HF{unsafeCoerce\mbox{\texttt{\#}}}} 921 | 922 | \newcommand{\qq}{\mbox{\texttt{"}}} 923 | \newcommand{\impossible}{\RW{Impossible}} 924 | 925 | \newcommand{\Real}{\mathbb{R}} 926 | 927 | \newcommand{\DoubleRec}{\TC{DoubleElim}} 928 | \newcommand{\DoubleOn}{\DC{Double_{\Z\vn}}} 929 | \newcommand{\DoubleSO}{\DC{Double_{\suc\Z}}} 930 | \newcommand{\DoubleSS}{\DC{Double_{\suc\suc}}} 931 | 932 | \newcommand{\doublerec}{\textbf{double-elim}} 933 | 934 | \newcommand{\set}{\TC{DList}} 935 | \newcommand{\setuser}{\TC{DListTop}} 936 | \newcommand{\setempty}{\emptyset} 937 | \newcommand{\setinsert}{\DC{insert}} 938 | 939 | 940 | %%%% Type systems 941 | 942 | \newcommand{\stlc}{\lambda\hspace*{-0.15cm}\to} 943 | \newcommand{\plc}{\lambda2} 944 | \newcommand{\dlc}{\lambda{}P} 945 | 946 | \newcommand{\EC}{\mathcal{E}} 947 | 948 | %%%% reductions 949 | 950 | \newcommand{\betared}{\iq\hspace*{-0.15cm}_{\beta}} 951 | \newcommand{\deltared}{\iq\hspace*{-0.15cm}_{\delta}} 952 | \newcommand{\gammared}{\iq\hspace*{-0.15cm}_{\gamma}} 953 | \newcommand{\etared}{\iq\hspace*{-0.15cm}_{\eta}} 954 | \newcommand{\iotared}{\iq\hspace*{-0.15cm}_{\iota}} 955 | \newcommand{\rhored}{\iq\hspace*{-0.15cm}_{\rho}} 956 | 957 | %%%% ExTT rules 958 | 959 | \newcommand{\exconverts}{\stackrel{\mathsf{Ex}}{\converts}} 960 | \newcommand{\excumul}{\stackrel{\mathsf{Ex}}{\cumul}} 961 | \newcommand{\exequiv}{\stackrel{\mathsf{Ex}}{\equiv}} 962 | \newcommand{\exreduces}{\stackrel{\mathsf{Ex}}\reduces} 963 | \newcommand{\exreducesto}{\stackrel{\mathsf{Ex}}{\reducesto}} 964 | \newcommand{\exreducesn}[1]{\exreduces_{#1}} 965 | 966 | \newcommand{\ttequiv}{\stackrel{\mathsf{TT}}{\equiv}} 967 | \newcommand{\ttreduces}{\stackrel{\mathsf{TT}}\reduces} 968 | \newcommand{\ttreducesn}[1]{\ttreduces_{#1}} 969 | 970 | %%% Type synthesis 971 | 972 | \newcommand{\hastype}{\Longrightarrow} 973 | \newcommand{\whnfs}{\twoheadrightarrow} 974 | \newcommand{\conv}{\converts} 975 | 976 | \newcommand{\exhastype}{\stackrel{\mathsf{Ex}}{\hastype}} 977 | \newcommand{\exwhnfs}{\stackrel{\mathsf{Ex}}{\whnfs}} 978 | \newcommand{\exconv}{\stackrel{\mathsf{Ex}}{\conv}} 979 | \newcommand{\exproves}{\stackrel{\mathsf{Ex}}{\proves}} 980 | 981 | \newcommand{\tthastype}{\stackrel{\mathsf{TT}}{\hastype}} 982 | \newcommand{\ttwhnfs}{\stackrel{\mathsf{TT}}{\whnfs}} 983 | \newcommand{\ttconv}{\stackrel{\mathsf{TT}}{\conv}} 984 | \newcommand{\ttproves}{\stackrel{\mathsf{TT}}{\proves}} 985 | 986 | %%% Lightning 987 | 988 | \newcommand{\light}[1]{\lightning^{#1}} 989 | \newcommand{\LHab}[1]{\pad{\;}{:^{#1}}} 990 | \newcommand{\llam}[3]{\lambda#1\pad{\!}{:}^{#2}#3} 991 | \newcommand{\lall}[3]{\forall#1\pad{\!}{:}^{#2}#3} 992 | \newcommand{\lapp}[3]{#1(#2)^{#3}} 993 | \newcommand{\larg}[2]{(#1)^{#2}} 994 | 995 | \newcommand{\RName}[1]{\hspace*{0.1in}\mathsf{#1}} 996 | 997 | %%% LOcal macros 998 | 999 | \newcommand{\ResState}{\TC{ResourceState}} 1000 | \newcommand{\Locked}{\DC{Locked}} 1001 | \newcommand{\ResHandle}{\TC{ResourceHandle}} 1002 | \newcommand{\Res}{\DC{Resource}} 1003 | \newcommand{\CLang}{\TC{CLang}} 1004 | \newcommand{\CFLang}{\TC{CFLang}} 1005 | \newcommand{\CFType}{\TC{CFType}} 1006 | \newcommand{\CLType}{\TC{CType}} 1007 | \newcommand{\RHandle}{\DC{RHandle}} 1008 | \newcommand{\RType}{\DC{RType}} 1009 | \newcommand{\RUnit}{\DC{RUnit}} 1010 | \newcommand{\LOCK}{\DC{LOCK}} 1011 | \newcommand{\UNLOCK}{\DC{UNLOCK}} 1012 | \newcommand{\ACTION}{\DC{ACTION}} 1013 | \newcommand{\FORK}{\DC{FORK}} 1014 | 1015 | \newcommand{\FSLang}{\TC{FSLang}} 1016 | \newcommand{\OPEN}{\DC{OPEN}} 1017 | \newcommand{\CLOSE}{\DC{CLOSE}} 1018 | \newcommand{\READ}{\DC{READ}} 1019 | \newcommand{\WRITE}{\DC{WRITE}} 1020 | \newcommand{\PRINT}{\DC{PRINT}} 1021 | \newcommand{\BIND}{\DC{BIND}} 1022 | 1023 | \newcommand{\FSType}{\TC{FSType}} 1024 | \newcommand{\FHandle}{\DC{FHandle}} 1025 | \newcommand{\FString}{\DC{FString}} 1026 | \newcommand{\FUnit}{\DC{FUnit}} 1027 | \newcommand{\ElemIs}{\TC{ElemIs}} 1028 | \newcommand{\elemHd}{\TC{atHead}} 1029 | \newcommand{\elemTl}{\TC{inTail}} 1030 | 1031 | \newcommand{\emptyEnv}{\DC{empty}} 1032 | \newcommand{\extendEnv}{\DC{extend}} 1033 | 1034 | \newcommand{\usera}{\FN{Alice}} 1035 | \newcommand{\userb}{\FN{Bob}} 1036 | \newcommand{\userc}{\FN{Charlie}} 1037 | 1038 | \newcommand{\FAcc}{\TC{FAcc}} 1039 | \newcommand{\UserA}{\DC{UserAcc}} 1040 | \newcommand{\GroupA}{\DC{GroupAcc}} 1041 | \newcommand{\GlobalA}{\DC{GlobalAcc}} 1042 | 1043 | \newcommand{\Perm}{\TC{Perm}} 1044 | \newcommand{\Username}{\TC{Username}} 1045 | \newcommand{\GroupData}{\TC{GroupData}} 1046 | \newcommand{\File}{\TC{File}} 1047 | \newcommand{\FS}{\DC{file}} 1048 | \newcommand{\Filepath}{\TC{Filepath}} 1049 | 1050 | \newcommand{\Read}{\DC{Read}} 1051 | \newcommand{\Write}{\DC{Write}} 1052 | \newcommand{\Execute}{\DC{Execute}} 1053 | 1054 | \newcommand{\Purpose}{\TC{Mode}} 1055 | \newcommand{\Reading}{\DC{Reading}} 1056 | \newcommand{\Writing}{\DC{Writing}} 1057 | 1058 | \newcommand{\FileState}{\TC{FileState}} 1059 | \newcommand{\FileHandle}{\TC{FileHandle}} 1060 | \newcommand{\OpenH}{\DC{OpenH}} 1061 | \newcommand{\ClosedH}{\DC{ClosedH}} 1062 | \newcommand{\Handle}{\TC{Handle}} 1063 | \newcommand{\Open}{\DC{Open}} 1064 | \newcommand{\Closed}{\DC{Closed}} 1065 | 1066 | \newcommand{\UserIO}{\TC{UserIO}} 1067 | \newcommand{\uio}{\DC{uio}} 1068 | 1069 | \newcommand{\CFS}{\TC{C_{fs}}} 1070 | \newcommand{\RFS}{\FN{R_{fs}}} 1071 | 1072 | \newcommand{\String}{\TC{String}} 1073 | 1074 | % inline idris code 1075 | 1076 | \newcommand{\Tcon}[1]{\texttt{#1}} 1077 | \newcommand{\Dcon}[1]{\texttt{#1}} 1078 | \newcommand{\Fname}[1]{\texttt{#1}} 1079 | \newcommand{\Vv}[1]{\texttt{#1}} 1080 | \newcommand{\TyTy}{\texttt{\#}} 1081 | 1082 | \newcommand{\direct}[1]{\texttt{\%#1}} 1083 | 1084 | \newcommand{\Feature}[1]{\textbf{Remark:}} 1085 | 1086 | \endinput 1087 | -------------------------------------------------------------------------------- /idris-tutorial.print.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper, british, final, pdftex]{article} 2 | 3 | \usepackage{fullpage} 4 | \usepackage{imports} 5 | 6 | \input{body.tex} 7 | -------------------------------------------------------------------------------- /idris-tutorial.screen.tex: -------------------------------------------------------------------------------- 1 | \documentclass[pdftex, british, final]{article} 2 | 3 | \usepackage[paperheight=9in, 4 | paperwidth=6in, 5 | margin=.5in]{geometry} 6 | \usepackage{setspace} 7 | 8 | \onehalfspacing 9 | 10 | \usepackage{imports} 11 | 12 | \renewcommand\familydefault{\sfdefault} 13 | 14 | \lstdefinestyle{default}{% 15 | basicstyle=\ttfamily\small, 16 | } 17 | 18 | \lstdefinestyle{stdout}{% 19 | xleftmargin=\parindent, 20 | tabsize=2, 21 | basicstyle=\ttfamily\footnotesize, 22 | showstringspaces=false, 23 | escapechar=^ 24 | } 25 | 26 | 27 | \input{body.tex} 28 | -------------------------------------------------------------------------------- /idrislang.sty: -------------------------------------------------------------------------------- 1 | %% --------------------------------------------------- [ Idris Styling Package ] 2 | %% 3 | %% A set of LaTeX macros and styling for working with Idris in LaTeX 4 | %% 5 | %% + Provides a listings bindings: 6 | %% + idris :: default ascii 7 | %% + literateidris :: convert ascii maths to math symbols. 8 | %% + Defines a `numbers', `default', and `stdout' listings style. 9 | %% + default :: Uses TT font for code and SF font for comments, 10 | %% and indented by parident. 11 | %% + numbers :: default but with numbers. 12 | %% + beamer :: default minus parindent 13 | %% + stdout :: for formatting stdout. 14 | %% + Defines a `code' environment for typesetting idris. 15 | %% + \begin{code}[...] ... \end{code} 16 | %% + Defines an input command for externally defined idris files. 17 | %% + \inputIdrisListing[...]{file.idr} 18 | %% + Provides definitions (from Idris Compiler) for pretty-printing Idris 19 | %% code using Fancy Verbatim and colour commands. 20 | %% + Sets commandchars for latex commands. 21 | %% + Defines commands typesetting the name Idris. 22 | %% + \Idris{} 23 | %% + \idris{} 24 | %% 25 | %% Options: 26 | %% - literate :: turn on literate idris for code environments. 27 | %% 28 | %% ----------------------------------------------------------- [ Begin Package ] 29 | \ProvidesPackage{idrislang} 30 | 31 | \RequirePackage{ifthen} 32 | \RequirePackage{xcolor} 33 | \RequirePackage{fancyvrb} 34 | \RequirePackage{listings} 35 | \RequirePackage{xspace} 36 | \RequirePackage{textcomp} 37 | \RequirePackage{setspace} 38 | %% ----------------------------------------------------------------- [ Options ] 39 | \newboolean{literate} 40 | \setboolean{literate}{false} 41 | 42 | \DeclareOption{literate}{% 43 | \setboolean{literate}{true} 44 | } 45 | 46 | \ProcessOptions\relax 47 | 48 | %% ---------------------------------------------------------------- [ Commands ] 49 | \newcommand{\Idris}{\textsc{Idris}\xspace} 50 | \newcommand{\idris}{\textsc{Idris}\xspace} 51 | \newcommand{\IdrisLineSpacing}{\singlespacing} 52 | %% ---------------------------------------------------------- [ Color Commands ] 53 | \newcommand{\IdrisData}[1]{\textcolor{red}{#1}} 54 | \newcommand{\IdrisType}[1]{\textcolor{blue}{#1}} 55 | \newcommand{\IdrisBound}[1]{\textcolor{magenta}{#1}} 56 | \newcommand{\IdrisFunction}[1]{\textcolor{green}{#1}} 57 | \newcommand{\IdrisKeyword}[1]{{\underline{#1}}} 58 | \newcommand{\IdrisImplicit}[1]{{\itshape \IdrisBound{#1}}} 59 | 60 | \fvset{commandchars=\\\{\}} 61 | 62 | %% --------------------------------------------------- [ Define Idris Listings ] 63 | \lstdefinelanguage{idris}{% 64 | sensitive,% 65 | %% ----------------------------------------------------------- [ Default Style ] 66 | xleftmargin=1.5em, 67 | tabsize=2, 68 | upquote=true, 69 | basicstyle=\ttfamily, 70 | flexiblecolumns=false, 71 | commentstyle=\footnotesize\itshape, 72 | %% ---------------------------------------------------------------- [ Keywords ] 73 | %% From Idris Parser and idris-mode and vimscript 74 | keywords={% 75 | abstract, attack, case, compute, do, dsl, else, exact, focus, if, 76 | import, in, infix, infixl, infixr, instance, intros, module, 77 | mutual, namespace, of, let, parameters, partial, pattern, prefix, 78 | private, public, refine, rewrite, solve, syntax, term, then, 79 | total, trivial, try, using, where, with 80 | }, 81 | %% ------------------------------------------------------- [ Prelude Functions ] 82 | morekeywords={% 83 | class, data, instance, record, dsl, postulate, default, 84 | lambda, variable, index_first, index_next 85 | }, 86 | %% ---------------------------------------------------------------- [ Comments ] 87 | morecomment=[l]--,% 88 | morecomment=[n]{\{-}{-\}} 89 | }[keywords,comments,strings]% 90 | 91 | %% ---------------------------------------- [ Define Idris with Literate Stuff ] 92 | \lstdefinelanguage{literateidris}[]{idris}{ 93 | literate= {+}{{$+$}}1 94 | {/}{{$/$}}1 95 | {*}{{$*$}}1 96 | {=}{{$=$}}1 97 | {>}{{$>$}}1 98 | {<}{{$<$}}1 99 | {\\}{{$\lambda$}}1 100 | {\\\\}{{\char`\\\char`\\}}1 101 | {->}{{$\rightarrow$}}2 102 | {>=}{{$\geq$}}2 103 | {<-}{{$\leftarrow$}}2 104 | {<=}{{$\leq$}}2 105 | {=>}{{$\Rightarrow$}}2 106 | {==}{{$\equiv$}}2 107 | {\ .}{{$\circ$}}2 108 | {\ .\ }{{$\circ$}}2 109 | {>>}{{>>}}2 110 | {>>=}{{>>=}}2 111 | {|}{{$\mid$}}1, 112 | } 113 | %% -------------------------------------------------- [ Default Listings Style ] 114 | 115 | \lstdefinestyle{default}{% 116 | basicstyle=\ttfamily\normalsize, 117 | } 118 | 119 | \lstdefinestyle{numbers}{% 120 | numbers=left, 121 | numbersep=10pt, 122 | numberstyle=\footnotesize\sffamily, 123 | frame=leftline 124 | } 125 | 126 | \lstdefinestyle{stdout}{% 127 | xleftmargin=\parindent, 128 | tabsize=2, 129 | basicstyle=\ttfamily\normalsize, 130 | showstringspaces=false, 131 | escapechar=^ 132 | } 133 | 134 | \lstdefinestyle{beamer}{% 135 | basicstyle=\ttfamily\normalsize, 136 | escapechar=^ 137 | } 138 | 139 | %% ------------------------------------------------------ [ A Code Environment ] 140 | %% Replicate the existence of literate haskell code environments, 141 | %% option to make pretty with numbers. 142 | \lstnewenvironment{code}[1][] 143 | {\ifthenelse{\boolean{literate}}{% 144 | \lstset{language=literateidris}}{% 145 | \lstset{language=idris}} 146 | \IdrisLineSpacing{} 147 | }{} 148 | %% ---------------------------------------------------------- [ Input Listings ] 149 | %% Command to add externally defined Idris code to the document. 150 | \newcommand{\inputIdrisListing}[2][]{% 151 | \begingroup 152 | \ifthenelse{\boolean{literate}}{% 153 | \lstset{language=literateidris}}{% 154 | \lstset{language=idris}} 155 | \IdrisLineSpacing{} 156 | \lstinputlisting[#1]{#2} 157 | \endgroup 158 | } 159 | \endinput 160 | %% --------------------------------------------------------------------- [ EOF ] 161 | -------------------------------------------------------------------------------- /imports.sty: -------------------------------------------------------------------------------- 1 | %% Common Stylings for both versions of the tutorial. 2 | \ProvidesPackage{imports} 3 | 4 | \RequirePackage[l2tabu,orthodox]{nag} 5 | \RequirePackage{fixltx2e} 6 | \RequirePackage{babel} 7 | \RequirePackage[iso]{isodate} 8 | \RequirePackage[utf8]{inputenc} 9 | \RequirePackage[T1]{fontenc} 10 | \RequirePackage[protrusion=true, expansion=true]{microtype} 11 | \RequirePackage[strict=true]{csquotes} 12 | \RequirePackage{xspace} 13 | \RequirePackage{float} 14 | 15 | \RequirePackage{mathpazo} 16 | \RequirePackage[scaled=0.95]{helvet} 17 | \RequirePackage{courier} 18 | 19 | \RequirePackage{hyperref} 20 | \RequirePackage[missing=0.9.17]{gitinfo} 21 | 22 | \RequirePackage{multicol} 23 | \RequirePackage{enumitem} 24 | 25 | \RequirePackage{fpmacros} 26 | \RequirePackage{idrislang} 27 | \RequirePackage{comment} 28 | 29 | \endinput 30 | -------------------------------------------------------------------------------- /library.ltx: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%% library file for datatypes etc. 2 | 3 | %%% Identifiers 4 | 5 | \newcommand{\va}{\VV{a}} 6 | \newcommand{\vb}{\VV{b}} 7 | \newcommand{\vc}{\VV{c}} 8 | \newcommand{\vd}{\VV{d}} 9 | \newcommand{\ve}{\VV{e}} 10 | \newcommand{\vf}{\VV{f}} 11 | \newcommand{\vg}{\VV{g}} 12 | \newcommand{\vh}{\VV{h}} 13 | \newcommand{\vi}{\VV{i}} 14 | \newcommand{\vj}{\VV{j}} 15 | \newcommand{\vk}{\VV{k}} 16 | \newcommand{\vl}{\VV{l}} 17 | \newcommand{\vm}{\VV{m}} 18 | \newcommand{\vn}{\VV{n}} 19 | \newcommand{\vo}{\VV{o}} 20 | \newcommand{\vp}{\VV{p}} 21 | \newcommand{\vq}{\VV{q}} 22 | \newcommand{\vr}{\VV{r}} 23 | \newcommand{\vs}{\VV{s}} 24 | \newcommand{\vt}{\VV{t}} 25 | \newcommand{\vu}{\VV{u}} 26 | \newcommand{\vv}{\VV{v}} 27 | \newcommand{\vw}{\VV{w}} 28 | \newcommand{\vx}{\VV{x}} 29 | \newcommand{\vy}{\VV{y}} 30 | \newcommand{\vz}{\VV{z}} 31 | \newcommand{\vA}{\VV{A}} 32 | \newcommand{\vB}{\VV{B}} 33 | \newcommand{\vC}{\VV{C}} 34 | \newcommand{\vD}{\VV{D}} 35 | \newcommand{\vE}{\VV{E}} 36 | \newcommand{\vF}{\VV{F}} 37 | \newcommand{\vG}{\VV{G}} 38 | \newcommand{\vH}{\VV{H}} 39 | \newcommand{\vI}{\VV{I}} 40 | \newcommand{\vJ}{\VV{J}} 41 | \newcommand{\vK}{\VV{K}} 42 | \newcommand{\vL}{\VV{L}} 43 | \newcommand{\vM}{\VV{M}} 44 | \newcommand{\vN}{\VV{N}} 45 | \newcommand{\vO}{\VV{O}} 46 | \newcommand{\vP}{\VV{P}} 47 | \newcommand{\vQ}{\VV{Q}} 48 | \newcommand{\vR}{\VV{R}} 49 | \newcommand{\vS}{\VV{S}} 50 | \newcommand{\vT}{\VV{T}} 51 | \newcommand{\vU}{\VV{U}} 52 | \newcommand{\vV}{\VV{V}} 53 | \newcommand{\vW}{\VV{W}} 54 | \newcommand{\vX}{\VV{X}} 55 | \newcommand{\vY}{\VV{Y}} 56 | \newcommand{\vZ}{\VV{Z}} 57 | \newcommand{\vas}{\VV{as}} 58 | \newcommand{\vbs}{\VV{bs}} 59 | \newcommand{\vcs}{\VV{cs}} 60 | \newcommand{\vds}{\VV{ds}} 61 | \newcommand{\ves}{\VV{es}} 62 | \newcommand{\vfs}{\VV{fs}} 63 | \newcommand{\vgs}{\VV{gs}} 64 | \newcommand{\vhs}{\VV{hs}} 65 | \newcommand{\vis}{\VV{is}} 66 | \newcommand{\vjs}{\VV{js}} 67 | \newcommand{\vks}{\VV{ks}} 68 | \newcommand{\vls}{\VV{ls}} 69 | \newcommand{\vms}{\VV{ms}} 70 | \newcommand{\vns}{\VV{ns}} 71 | \newcommand{\vos}{\VV{os}} 72 | \newcommand{\vps}{\VV{ps}} 73 | \newcommand{\vqs}{\VV{qs}} 74 | \newcommand{\vrs}{\VV{rs}} 75 | %\newcommand{\vss}{\VV{ss}} 76 | \newcommand{\vts}{\VV{ts}} 77 | \newcommand{\vus}{\VV{us}} 78 | \newcommand{\vvs}{\VV{vs}} 79 | \newcommand{\vws}{\VV{ws}} 80 | \newcommand{\vxs}{\VV{xs}} 81 | \newcommand{\vys}{\VV{ys}} 82 | \newcommand{\vzs}{\VV{zs}} 83 | 84 | %%% Telescope Identifiers 85 | 86 | \newcommand{\ta}{\vec{\VV{a}}} 87 | \newcommand{\tb}{\vec{\VV{b}}} 88 | \newcommand{\tc}{\vec{\VV{c}}} 89 | \newcommand{\td}{\vec{\VV{d}}} 90 | \newcommand{\te}{\vec{\VV{e}}} 91 | \newcommand{\tf}{\vec{\VV{f}}} 92 | \newcommand{\tg}{\vec{\VV{g}}} 93 | %\newcommand{\th}{\vec{\VV{h}}} 94 | \newcommand{\ti}{\vec{\VV{i}}} 95 | \newcommand{\tj}{\vec{\VV{j}}} 96 | \newcommand{\tk}{\vec{\VV{k}}} 97 | \newcommand{\tl}{\vec{\VV{l}}} 98 | \newcommand{\tm}{\vec{\VV{m}}} 99 | \newcommand{\tn}{\vec{\VV{n}}} 100 | %\newcommand{\to}{\vec{\VV{o}}} 101 | \newcommand{\tp}{\vec{\VV{p}}} 102 | \newcommand{\tq}{\vec{\VV{q}}} 103 | \newcommand{\tr}{\vec{\VV{r}}} 104 | \newcommand{\tts}{\vec{\VV{s}}} 105 | \newcommand{\ttt}{\vec{\VV{t}}} 106 | \newcommand{\tu}{\vec{\VV{u}}} 107 | %\newcommand{\tv}{\vec{\VV{v}}} 108 | \newcommand{\tw}{\vec{\VV{w}}} 109 | \newcommand{\tx}{\vec{\VV{x}}} 110 | \newcommand{\ty}{\vec{\VV{y}}} 111 | \newcommand{\tz}{\vec{\VV{z}}} 112 | \newcommand{\tA}{\vec{\VV{A}}} 113 | \newcommand{\tB}{\vec{\VV{B}}} 114 | \newcommand{\tC}{\vec{\VV{C}}} 115 | \newcommand{\tD}{\vec{\VV{D}}} 116 | \newcommand{\tE}{\vec{\VV{E}}} 117 | \newcommand{\tF}{\vec{\VV{F}}} 118 | \newcommand{\tG}{\vec{\VV{G}}} 119 | \newcommand{\tH}{\vec{\VV{H}}} 120 | \newcommand{\tI}{\vec{\VV{I}}} 121 | \newcommand{\tJ}{\vec{\VV{J}}} 122 | \newcommand{\tK}{\vec{\VV{K}}} 123 | \newcommand{\tL}{\vec{\VV{L}}} 124 | \newcommand{\tM}{\vec{\VV{M}}} 125 | \newcommand{\tN}{\vec{\VV{N}}} 126 | \newcommand{\tO}{\vec{\VV{O}}} 127 | \newcommand{\tP}{\vec{\VV{P}}} 128 | \newcommand{\tQ}{\vec{\VV{Q}}} 129 | \newcommand{\tR}{\vec{\VV{R}}} 130 | \newcommand{\tS}{\vec{\VV{S}}} 131 | \newcommand{\tT}{\vec{\VV{T}}} 132 | \newcommand{\tU}{\vec{\VV{U}}} 133 | \newcommand{\tV}{\vec{\VV{V}}} 134 | \newcommand{\tW}{\vec{\VV{W}}} 135 | \newcommand{\tX}{\vec{\VV{X}}} 136 | \newcommand{\tY}{\vec{\VV{Y}}} 137 | \newcommand{\tZ}{\vec{\VV{Z}}} 138 | 139 | 140 | 141 | %%% Nat 142 | 143 | \newcommand{\NatPackage}{ 144 | \newcommand{\Nat}{\TC{\mathbb{N}}} 145 | \newcommand{\Z}{\DC{0}} 146 | \newcommand{\suc}{\DC{s}} 147 | \newcommand{\NatDecl}{ 148 | \Data \hg 149 | \Axiom{\Nat\Hab\Type} \hg 150 | \Where \hg 151 | \Axiom{\Z\Hab\Nat} \hg 152 | \Rule{\vn\Hab\Nat} 153 | {\suc\:\vn\Hab\Nat} 154 | }} 155 | 156 | %%% Bool 157 | 158 | \newcommand{\BoolPackage}{ 159 | \newcommand{\Bool}{\TC{Bool}} 160 | \newcommand{\true}{\DC{true}} 161 | \newcommand{\false}{\DC{false}} 162 | \newcommand{\BoolDecl}{ 163 | \Data \hg 164 | \Axiom{\Bool\Hab\Type} \hg 165 | \Where \hg 166 | \Axiom{\true\Hab\Bool} \hg 167 | \Axiom{\false\Hab\Bool} 168 | }} 169 | 170 | %%% So 171 | 172 | \newcommand{\SoPackage}{ 173 | \newcommand{\So}{\TC{So}} 174 | \newcommand{\oh}{\DC{oh}} 175 | \newcommand{\SoDecl}{ 176 | \Data \hg 177 | \Rule{\vb\Hab\Bool} 178 | {\So\:\vb\Hab\Type} \hg 179 | \Where \hg 180 | \Axiom{\oh\Hab\So\:\true} 181 | }} 182 | 183 | %%% Unit 184 | 185 | \newcommand{\UnitPackage}{ 186 | \newcommand{\Unit}{\TC{Unit}} 187 | \newcommand{\void}{\DC{void}} 188 | \newcommand{\UnitDecl}{ 189 | \Data \hg 190 | \Axiom{\Unit\Hab\Type} \hg 191 | \Where \hg 192 | \Axiom{\void\Hab\Unit} 193 | }} 194 | 195 | %%% Maybe 196 | 197 | \newcommand{\MaybePackage}{ 198 | \newcommand{\Maybe}{\TC{Maybe}} 199 | \newcommand{\yes}{\DC{yes}} 200 | \newcommand{\no}{\DC{no}} 201 | \newcommand{\MaybeDecl}{ 202 | \Data \hg 203 | \Rule{\vA\Hab\Type} 204 | {\Maybe\:\vA\Hab\Type} \hg 205 | \Where \hg 206 | \Rule{\va \Hab \vA} 207 | {\yes\:\va\Hab\Maybe\:\vA} \hg 208 | \Axiom{\no\Hab\Maybe\:\vA} 209 | }} 210 | 211 | %%% Cross 212 | 213 | \newcommand{\pr}[2]{(#1\DC{,}#2)} %grrrr 214 | \newcommand{\CrossPackage}{ 215 | \newcommand{\Cross}{\times} 216 | \newcommand{\CrossDecl}{ 217 | \Data \hg 218 | \Rule{\vA,\vB\Hab\Type} 219 | {\vA\Cross\vB\Hab\Type} \hg 220 | \Where \hg 221 | \Rule{\va \Hab \vA \hg \vb\Hab\vB} 222 | {\pr{\va}{\vb}\Hab\vA\Cross\vB} 223 | }} 224 | 225 | %%% Fin 226 | 227 | \newcommand{\FinPackage}{ 228 | \newcommand{\Fin}{\TC{Fin}} 229 | \newcommand{\fz}{\DC{f0}} 230 | \newcommand{\fs}{\DC{fs}} 231 | \newcommand{\FinDecl}{ 232 | \AR{ 233 | \Data \hg 234 | \Rule{\vn\Hab\Nat} 235 | {\Fin\:\vn\Hab\Type} \hg \\ 236 | \Where \hg 237 | \begin{array}[t]{c} 238 | \Axiom{\fz\Hab\Fin\:(\suc\:\vn)} \hg 239 | \Rule{\vi\Hab\Fin\:\vn} 240 | {\fs\:\vi\Hab\Fin\:(\suc\:\vn)} 241 | \end{array} 242 | } 243 | }} 244 | 245 | %%% Vect 246 | 247 | \newcommand{\VectPackage}{ 248 | \newcommand{\Vect}{\TC{Vect}} 249 | \newcommand{\vnil}{\varepsilon} 250 | \newcommand{\vcons}{\,\dcolon\,} 251 | \newcommand{\vsnoc}{\,\dcolon\,} 252 | \newcommand{\VectConsDecl}{ 253 | \Data \hg 254 | \Rule{\vA \Hab \Type \hg \vn\Hab\Nat} 255 | {\Vect\:\vA\:\vn\Hab\Type} \hg 256 | \Where \hg \begin{array}[t]{c} 257 | \Axiom{\vnil \Hab \Vect\:\vA\:\Z} \\ 258 | \Rule{\vx\Hab\vA \hg \vxs\Hab \Vect\:\vA\:\vn } 259 | {\vx\vcons\vxs\Hab\Vect\:\vA\:(\suc\vn)} 260 | \end{array} 261 | } 262 | \newcommand{\VectSnocDecl}{ 263 | \Data \hg 264 | \Rule{\vA \Hab \Type \hg \vn\Hab\Nat} 265 | {\Vect\:\vA\:\vn\Hab\Type} \hg 266 | \Where \hg \begin{array}[t]{c} 267 | \Axiom{\vnil \Hab \Vect\:\vA\:\Z} \\ 268 | \Rule{\vxs\Hab \Vect\:\vA\:\vn \hg \vx\Hab\vA} 269 | {\vxs\vsnoc\vx\Hab\Vect\:\vA\:(\suc\vn)} 270 | \end{array} 271 | } 272 | } 273 | 274 | %%% Compare 275 | 276 | %Data Compare : (x:nat)(y:nat)Type 277 | % = lt : (x:nat)(y:nat)(Compare x (plus (S y) x)) 278 | % | eq : (x:nat)(Compare x x) 279 | % | gt : (x:nat)(y:nat)(Compare (plus (S x) y) y); 280 | 281 | 282 | \newcommand{\ComparePackage}{ 283 | \newcommand{\Compare}{\TC{Compare}} 284 | \newcommand{\ltComp}{\DC{lt}} 285 | \newcommand{\eqComp}{\DC{eq}} 286 | \newcommand{\gtComp}{\DC{gt}} 287 | \newcommand{\CompareDecl}{ 288 | \Data \hg 289 | \Rule{\vm\Hab\Nat\hg\vn\Hab\Nat} 290 | {\Compare\:\vm\:\vn\Hab\Type} \\ 291 | \Where \hg\begin{array}[t]{c} 292 | \Rule{\vx\Hab\Nat\hg\vy\Hab\Nat} 293 | {\ltComp_{\vx}\:\vy\Hab\Compare\:\vx\:(\FN{plus}\:\vx\:(\suc\:\vy))} \\ 294 | \Rule{\vx\Hab\Nat} 295 | {\eqComp_{\vx}\Hab\Compare\:\vx\:\vx}\\ 296 | \Rule{\vx\Hab\Nat\hg\vy\Hab\Nat} 297 | {\gtComp_{\vy}\:\vx\Hab\Compare\:(\FN{plus}\:\vy\:(\suc\:\vx))\:\vy} \\ 298 | \end{array} 299 | } 300 | 301 | %Data CompareM : Type 302 | % = ltM : (ydiff:nat)CompareM 303 | % | eqM : CompareM 304 | % | gtM : (xdiff:nat)CompareM; 305 | 306 | \newcommand{\CompareM}{\TC{Compare^-}} 307 | \newcommand{\ltCompM}{\DC{lt^-}} 308 | \newcommand{\eqCompM}{\DC{eq^-}} 309 | \newcommand{\gtCompM}{\DC{gt^-}} 310 | \newcommand{\CompareMDecl}{ 311 | 312 | \Data \hg 313 | \Axiom{\CompareM\Hab\Type} \\ 314 | \Where \hg\begin{array}[t]{c} 315 | \Rule{\vy\Hab\Nat} 316 | {\ltCompM\:\vy\Hab\CompareM} \\ 317 | \Axiom{\eqCompM\Hab\CompareM}\\ 318 | \Rule{\vx\Hab\Nat} 319 | {\gtCompM\:\vx\Hab\CompareM} \\ 320 | \end{array} 321 | } 322 | \newcommand{\CompareRec}{\FN{CompareRec}} 323 | \newcommand{\CompareRecM}{\FN{CompareRec^-}} 324 | 325 | } 326 | --------------------------------------------------------------------------------