1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
_D_e_f_i_n_i_t_i_o_n_s
The purpose of a definition is to give a value to one or more variables.
There are two kinds of definition, `scalar' and `conformal'. A scalar
definition gives a value to a single variable, and consists of one or
more consecutive equations of the form
fnform = rhs
where a `fnform' consists of the name being defined followed by zero or
more formal parameters. Here are three examples of scalar definitions,
of `answer', `sqdiff' and `equal' respectively
answer = 42
sqdiff a b = a^2 - b^2
equal a a = True
equal a b = False
When a scalar definition consists of more than one equation, the order
of the equations can be significant, as the last example shows. (Notice
that `equals' as defined here is a function of two arguments with the
same action as the built in `=' operator of boolean expressions.)
A conformal definition gives values to several variables simultaneously
and is an equation of the form
pattern = rhs
An example of this kind of definition is
(x,y,z) = ploggle
For this to make sense, the value of `ploggle' must of course be a
3-tuple. More information about the _p_a_t_t_e_r_n _m_a_t_c_h_i_n_g aspect of
definitions is given in the manual section of that name.
Both fnform and pattern equations share a common notion of `right hand
side'
_R_i_g_h_t_ _h_a_n_d_ _s_i_d_e_s
The simplest form of rhs is just an expression (as in all the equations
above). It is also possible to give several alternative expressions,
distinguished by guards. A guard consists of the word `if' followed by
a boolean expression. An example of a right hand side with several
alternatives is given by the following definition of the greatest common
divisor function, using Euclid's algorithm
gcd a b = gcd (a-b) b, _i_f a>b
= gcd a (b-a), _i_f a<b
= a, _i_f a=b
Note that the guards are written on the right, following a comma. The
layout is significant (because the offside rule is used to resolve any
ambiguities in the parse).
The last guard can be written `otherwise', to indicate that this is the
case which applies if all the other guards are false. For example the
correct rule for recognising a leap year can be written:
leap y = y _d_i_v 400 = 0, _i_f y _m_o_d 100 = 0
= y _d_i_v 4 = 0, _o_t_h_e_r_w_i_s_e
The _o_t_h_e_r_w_i_s_e may here be regarded as standing for _i_f y _m_o_d 100 ~= 0.
In the general case it abbreviates the conjunction of the negation of
all the previous guards, and may be used to avoid writing out a long
boolean expression.
Although it is better style to write guards that are mutually exclusive,
this is not something the compiler can enforce - in the general case the
alternative selected is the first (in the order they are written) whose
guard evaluates to True.
[In older versions of Miranda the presence of the keyword `if' after the
guard comma was optional.]
_B_l_o_c_k_ _s_t_r_u_c_t_u_r_e
A right hand side can be qualified by a _w_h_e_r_e clause. This is written
after the last alternative. The bindings introduced by the _w_h_e_r_e govern
the whole rhs, including the guards. Example
foo x = p + q, _i_f p<q
= p - q, _i_f p>=q
_w_h_e_r_e
p = x^2 + 1
q = 3*x^3 - 5
Notice that the whole _w_h_e_r_e clause must be indented, to show that it is
part of the rhs. Following a _w_h_e_r_e can be any number of definitions,
and the syntax of such local definitions is exactly the same as that for
top level definitions (including therefore, recursively, the possibility
that they may contain nested _w_h_e_r_e's).
It is not permitted to have locally defined types, however. New
typenames can be introduced only at top level.
|