forked from GitHub/gf-core
Transfer reference: first proof reading fixes.
This commit is contained in:
@@ -16,7 +16,9 @@ for an example of a Transfer program, and how to compile and use
|
||||
Transfer programs.
|
||||
|
||||
Transfer is a dependently typed functional programming language
|
||||
with eager evaluation.
|
||||
with eager evaluation. The language supports generalized algebraic
|
||||
datatypes, pattern matching and function overloading.
|
||||
|
||||
|
||||
== Current implementation status ==
|
||||
|
||||
@@ -24,7 +26,7 @@ with eager evaluation.
|
||||
important missing piece is the type checker. This means that there are almost
|
||||
no checks done on Transfer programs before they are run. It also means that
|
||||
the values of metavariables are not inferred. Thus metavariables cannot
|
||||
be used where their values matter. For example, dictionaries for overlaoded
|
||||
be used where their values matter. For example, dictionaries for overloaded
|
||||
functions must be given explicitly, not as metavariables.
|
||||
|
||||
|
||||
@@ -33,9 +35,9 @@ functions must be given explicitly, not as metavariables.
|
||||
Transfer uses layout syntax, where the indentation of a piece of code
|
||||
determines which syntactic block it belongs to.
|
||||
|
||||
To give the block structure of a piece of code without using layout
|
||||
syntax, you can enclose the block in curly braces (``{ }``) and
|
||||
separate the parts of the blocks with semicolons (``;``).
|
||||
To give the block structure without using layout
|
||||
syntax, you can enclose the block in curly braces and
|
||||
separate the parts of the blocks with semicolons.
|
||||
|
||||
For example, this case expression:
|
||||
|
||||
@@ -55,7 +57,7 @@ case x of {
|
||||
```
|
||||
|
||||
Here the layout is insignificant, as the structure is given with
|
||||
braces and semicolons. Thus the above is equivalent to:
|
||||
braces and semicolons. Thus it is equivalent to:
|
||||
|
||||
```
|
||||
case x of { p1 -> e1 ; p2 -> e2 }
|
||||
@@ -64,13 +66,14 @@ case x of { p1 -> e1 ; p2 -> e2 }
|
||||
|
||||
== Imports ==
|
||||
|
||||
A Transfer module start with some imports. Most modules will have to
|
||||
A Transfer module starts with some imports. Most modules will have to
|
||||
import the prelude, which contains definitons used by most programs:
|
||||
|
||||
```
|
||||
import prelude
|
||||
```
|
||||
|
||||
For more information about the standard prelude, see [Standard prelude #prelude].
|
||||
|
||||
== Function declarations ==
|
||||
|
||||
@@ -85,19 +88,37 @@ where ``f`` is the function's name, and ``T`` its type. See
|
||||
[Function types #function_types] for a how the types of functions
|
||||
are written.
|
||||
|
||||
The definition of the function is the given as a sequence of pattern
|
||||
The definition of the function is then given as a sequence of pattern
|
||||
equations. The first equation whose patterns match the function arguments
|
||||
is used when the function is called. Pattern equations are on the form:
|
||||
|
||||
```
|
||||
f p11 ... p1m = exp
|
||||
f p11 ... p1m = exp1
|
||||
...
|
||||
f pn1 ... pnm = exp
|
||||
f pn1 ... pnm = expn
|
||||
```
|
||||
|
||||
where ``p11`` to ``pnm`` are patterns, see [Patterns #patterns].
|
||||
|
||||
|
||||
Pattern equations can also have guards, boolean expressions which determine
|
||||
whether to use the equation when the pattern has been matched. Pattern equations
|
||||
with guards are written:
|
||||
|
||||
```
|
||||
f p11 ... p1m | guard1 = exp1
|
||||
...
|
||||
f pn1 ... pnm | guardn = expn
|
||||
```
|
||||
|
||||
Pattern equations with and without guards can be mixed in the definiton of
|
||||
a function.
|
||||
|
||||
Any variables bound in the patterns are in scope in the guards and
|
||||
right hand sides of each pattern equation.
|
||||
|
||||
|
||||
|
||||
== Data type declarations ==
|
||||
|
||||
Transfer supports Generalized Algebraic Datatypes.
|
||||
@@ -114,6 +135,8 @@ Here ``D`` is the name of the data type, ``T`` is the type of the type
|
||||
constructor, ``c1`` to ``cn`` are the data constructor names, and
|
||||
``Tc1`` to ``Tcn`` are their types.
|
||||
|
||||
FIXME: explain the constraints on the types of type and data constructors.
|
||||
|
||||
|
||||
== Lambda expressions ==
|
||||
|
||||
@@ -139,6 +162,10 @@ let x1 : T1 = exp1
|
||||
in exp
|
||||
```
|
||||
|
||||
Here, the variables ``x1`` to ``xn`` are in scope in all the expressions
|
||||
``exp1`` to ``expn``, and in ``exp``. Thus let-defined functions can be
|
||||
mutually recursive.
|
||||
|
||||
|
||||
== Types ==
|
||||
|
||||
@@ -154,7 +181,7 @@ This is the type of functions which take an argument of type
|
||||
``A`` and returns a result of type ``B``.
|
||||
|
||||
To write functions which take more than one argument, we use //currying//.
|
||||
A function which takes n arguments is a function which takes 1
|
||||
A function which takes n arguments is a function which takes one
|
||||
argument and returns a function which takes n-1 arguments. Thus,
|
||||
|
||||
```
|
||||
@@ -167,7 +194,7 @@ or, equivalently, since ``->`` associates to the right:
|
||||
A -> B -> C
|
||||
```
|
||||
|
||||
is the type of functions which take 2 arguments, the first of type
|
||||
is the type of functions which take teo arguments, the first of type
|
||||
``A`` and the second of type ``B``. This arrangement lets us do
|
||||
//partial application// of function to fewer arguments than the function
|
||||
is declared to take, returning a new function which takes the rest
|
||||
@@ -180,11 +207,10 @@ In a function type, the value of an argument can be used later
|
||||
in the type. Such dependent function types are written:
|
||||
|
||||
```
|
||||
(x1 : T1) -> ... -> (xn : Tn) -> T
|
||||
(x : A) -> B
|
||||
```
|
||||
|
||||
Here, ``x1`` can be used in ``T2`` to ``Tn``, ``x1`` can be used
|
||||
in ``T2`` to ``Tn``.
|
||||
Here, ``x`` is in scope in ``B``.
|
||||
|
||||
|
||||
=== Basic types ===
|
||||
@@ -192,7 +218,8 @@ in ``T2`` to ``Tn``.
|
||||
==== Integers ====
|
||||
|
||||
The type of integers is called ``Integer``.
|
||||
standard decmial integer literals are used to represent values of this type.
|
||||
Standard decmial integer literals, such as ``0`` and ``1234`` are used to
|
||||
represent values of this type.
|
||||
|
||||
|
||||
==== Floating-point numbers ====
|
||||
@@ -204,15 +231,17 @@ in decimal notation, e.g. ``123.456``.
|
||||
|
||||
==== Strings ====
|
||||
|
||||
There is a primitive ``String`` type. This might be replaced by a list of
|
||||
characters representation in the future. String literals are written
|
||||
There is a primitive ``String`` type. String literals are written
|
||||
with double quotes, e.g. ``"this is a string"``.
|
||||
FIXME: This might be replaced by a list of
|
||||
characters representation in the future.
|
||||
|
||||
|
||||
==== Booleans ====
|
||||
|
||||
Booleans are not a built-in type, though some features of the Transfer language
|
||||
depend on them.
|
||||
depend on them. The ``Bool`` type is defined in the
|
||||
[Standard prelude #prelude].
|
||||
|
||||
```
|
||||
data Bool : Type where
|
||||
@@ -253,7 +282,7 @@ rec { l1 = exp1; ... ; ln = expn }
|
||||
|
||||
==== Record projection ====
|
||||
|
||||
Fields are selection from records using the ``.`` operator. This expression selects
|
||||
Fields are selected from records using the ``.`` operator. This expression selects
|
||||
the field ``l`` from the record value ``r``:
|
||||
|
||||
```
|
||||
@@ -285,7 +314,7 @@ such that for every field ``p1 : T1`` in R2, ``p1 : T1`` is also a
|
||||
field of T1.
|
||||
|
||||
|
||||
=== Tuples ===
|
||||
=== Tuples ===[tuples]
|
||||
|
||||
Tuples on the form:
|
||||
|
||||
@@ -308,18 +337,18 @@ The list type is declared as:
|
||||
|
||||
```
|
||||
data List : Type -> Type where
|
||||
Nil : (A:Type) -> List A
|
||||
Nil : (A:Type) -> List A
|
||||
Cons : (A:Type) -> A -> List A -> List A
|
||||
```
|
||||
|
||||
The empty lists can be written as ``[]``. There is a operator ``::`` which can
|
||||
The empty list can be written as ``[]``. There is an operator ``::`` which can
|
||||
be used instead of ``Cons``. These are just syntactic sugar for expressions
|
||||
using ``Nil`` and ``Cons``, with the type arguments hidden.
|
||||
|
||||
|
||||
== Case expressions ==
|
||||
|
||||
Pattern matching is done in pattern equations and by using the
|
||||
Pattern matching is done in pattern equations and with the
|
||||
``case`` construct:
|
||||
|
||||
```
|
||||
@@ -355,9 +384,8 @@ C p1 ... pn
|
||||
```
|
||||
|
||||
where ``C`` is a data constructor which takes ``n`` arguments.
|
||||
If the value to be matched is the constructor ``C`` applied to
|
||||
arguments ``v1`` to ``vn``, then ``v1`` to ``vn`` will be matched
|
||||
against ``p1`` to ``pn``.
|
||||
If the value to be matched is ``C v1 ... vn``,
|
||||
then ``v1`` to ``vn`` will be matched against ``p1`` to ``pn``.
|
||||
|
||||
|
||||
=== Variable patterns ===
|
||||
@@ -370,11 +398,14 @@ x
|
||||
|
||||
A variable pattern matches any value, and binds the variable name to the
|
||||
value. A variable may not occur more than once in a pattern.
|
||||
Note that variable patterns may not use the same identifier as data constructors
|
||||
which are in scope, since they will then be interpreted as constructor
|
||||
patterns.
|
||||
|
||||
|
||||
=== Wildcard patterns ===
|
||||
|
||||
Wildcard patterns are written as with a single underscore:
|
||||
Wildcard patterns are written with a single underscore:
|
||||
|
||||
```
|
||||
_
|
||||
@@ -391,11 +422,11 @@ Record patterns match record values:
|
||||
rec { l1 = p1; ... ; ln = pn }
|
||||
```
|
||||
|
||||
A record value matches a record pattern, if the record value has all the
|
||||
A record value matches a record pattern if the record value has all the
|
||||
fields ``l1`` to ``ln``, and their values match ``p1`` to ``pn``.
|
||||
|
||||
Note that a record value may have more fields than the record pattern and
|
||||
they will still match.
|
||||
Note that a record value may have more fields than the record pattern.
|
||||
The values of these fields do not influence the pattern matching.
|
||||
|
||||
|
||||
=== Disjunctive patterns ===
|
||||
@@ -412,8 +443,8 @@ FIXME: talk about how this is expanded
|
||||
|
||||
=== List patterns ===
|
||||
|
||||
When pattern matching in lists, there are two special constructs.
|
||||
A whole list can be matched be a list of patterns:
|
||||
When pattern matching on lists, there are two special constructs.
|
||||
A whole list can by matched be a list of patterns:
|
||||
|
||||
```
|
||||
[p1, ... , pn]
|
||||
@@ -434,7 +465,7 @@ Non-empty lists can also be matched with ``::``-patterns:
|
||||
p1::p2
|
||||
```
|
||||
|
||||
This pattern matches a non-empty lists such that the first element of
|
||||
This pattern matches non-empty lists such that the first element of
|
||||
the list matches ``p1`` and the rest of the list matches ``p2``.
|
||||
|
||||
|
||||
@@ -446,7 +477,9 @@ Tuples patterns on the form:
|
||||
(p1, ... , pn)
|
||||
```
|
||||
|
||||
are syntactic sugar for record patterns, in the same way as tuple expressions.
|
||||
are syntactic sugar for record patterns, in the same way as
|
||||
tuple expressions, see [Tuples #tuples].
|
||||
|
||||
|
||||
=== String literal patterns ===
|
||||
|
||||
@@ -460,13 +493,13 @@ Integer literals can be used as patterns.
|
||||
|
||||
== Metavariables ==[metavariables]
|
||||
|
||||
Metavariable are written as questions marks:
|
||||
Metavariables are written as questions marks:
|
||||
|
||||
```
|
||||
?
|
||||
```
|
||||
|
||||
A metavariable is a way to the the type checker that:
|
||||
A metavariable is a way to tell the type checker that:
|
||||
"you should be able to figure out what this should be,
|
||||
I can't be bothered to tell you".
|
||||
|
||||
@@ -478,7 +511,7 @@ and dictionary arguments explicitly.
|
||||
|
||||
In Transfer, functions can be overloaded by having them take a record
|
||||
of functions as an argument. For example, the functions for equality
|
||||
and inequality in the Transfer prelude module are defined as:
|
||||
and inequality in the Transfer [Prelude #prelude] are defined as:
|
||||
|
||||
```
|
||||
Eq : Type -> Type
|
||||
@@ -494,7 +527,7 @@ neq A d x y = not (eq A d x y)
|
||||
We call ``Eq`` a //type class//, though it's actually just a record type
|
||||
used to pass function implementations to overloaded functions. We
|
||||
call a value of type ``Eq A`` an Eq //dictionary// for the type A.
|
||||
The dictionary is used to look up the version of the function for the
|
||||
The dictionary is used to look up the version of some function for the
|
||||
particular type we want to use the function on. Thus, in order to use
|
||||
the ``eq`` function on two integers, we need a dictionary of type
|
||||
``Eq Integer``:
|
||||
@@ -513,7 +546,7 @@ eq Integer eq_Integer x y
|
||||
```
|
||||
|
||||
Giving the type at which to use the overloaded function, and the appropriate
|
||||
dictionary is cumbersome. [Metavariables #metavariables] come to the rescue:
|
||||
dictionary can be cumbersome. [Metavariables #metavariables] come to the rescue:
|
||||
|
||||
```
|
||||
eq ? ? x y
|
||||
@@ -540,19 +573,19 @@ Ord A = sig eq : A -> A -> Bool
|
||||
|
||||
To extend an existing class, we keep the fields of the class we want to
|
||||
extend, and add any new fields that we want. Because of record subtyping,
|
||||
for any type A, a value of type ``Ord A`` is also a value of type ``Eq A``.
|
||||
for any type ``A``, a value of type ``Ord A`` is also a value of type ``Eq A``.
|
||||
|
||||
|
||||
=== Extending multiple classes ===
|
||||
|
||||
A type class can also extend several classes, by simply having all the fields
|
||||
from all the classes we want to extend. The ``Num`` class described below is
|
||||
an example of this.
|
||||
from all the classes we want to extend. The ``Num`` class in the
|
||||
[Standard prelude #prelude] is an example of this.
|
||||
|
||||
|
||||
== Standard prelude ==
|
||||
== Standard prelude ==[prelude]
|
||||
|
||||
The standard prelude, see [prelude.tra ../transfer/lib/prelude.tra]
|
||||
The standard prelude, see [prelude.tra ../transfer/lib/prelude.tra],
|
||||
contains definitions of a number of standard types, functions and
|
||||
type classes.
|
||||
|
||||
@@ -560,14 +593,14 @@ type classes.
|
||||
== Operators ==
|
||||
|
||||
Most built-in operators in the Transfer language are translated
|
||||
o calls to overloaded functions. This means that they can be
|
||||
use at any type for which there is a dictionry for the type class
|
||||
to calls to overloaded functions. This means that they can be
|
||||
used at any type for which there is a dictionary for the type class
|
||||
in question.
|
||||
|
||||
=== Unary operators ===
|
||||
|
||||
|| Operator | Precedence | Translation |
|
||||
| ``-`` | 10 | ``-x => negate ? ? x`` |
|
||||
|| Operator | Precedence | Translation |
|
||||
| ``-`` | 10 | ``-x => negate ? ? x`` |
|
||||
|
||||
|
||||
=== Binary operators ===
|
||||
|
||||
Reference in New Issue
Block a user