The Miranda Standard Environment
We give here, in alphabetical order, a brief explanation of all the
identifiers in the Miranda standard environment, each followed by its
definition (except in a few cases where the definition cannot
conveniently be given in Miranda). The lines marked with a \> in
column one are formal program text, the other lines in the file are
comment. Note that a number of the functions given here are defined
internally (for speed) even though their definitions could have been
given in Miranda - in these cases the Miranda definition is given as a
comment. This is the standard environment of Miranda release two.
abs takes the absolute value of a number - e.g. abs (-3) is 3, abs
3.5 is 3.5
> abs :: num->num
> abs x = -x, if x<0
> = x, otherwise
and applied to a list of truthvalues, takes their logical
conjunction.
> and :: [bool]->bool
> and = foldr (&) True
arctan is the trigonometric function, inverse tangent. It returns a
result in the range -pi/2 to pi/2. See also sin\',cos`.
> arctan :: num->num ||defined internally
bool is the type comprising the two truthvalues.
bool ::= False | True ||primitive to Miranda
char\' is the type comprising ascii characters (e.g. \'a\', \'\\n).
char :: type ||primitive to Miranda
cjustify applied to a number and a string, centre justifies the
string in a field of the specified width. See also ljustify,
rjustify\',spaces`.
> cjustify :: num->[char]->[char]
> cjustify n s = spaces lmargin++s++spaces rmargin
> where
> margin = n - # s
> lmargin = margin div 2
> rmargin = margin - lmargin
code applied to a character returns the integer which is its ascii
code. E.g.
code 'a' = 97.
See also decode.
> code :: char->num ||defined internally
concat applied to a list of lists, joins them all together into a
single list with ++. E.g.
concat [[1,2],[],[3,4]] = [1,2,3,4].
> concat :: [[*]]->[*]
> concat = foldr (++) []
const is a combinator for creating constant-valued functions. E.g.
(const 3) is the function that always returns 3.
> const :: *->**->*
> const x y = x
converse is a combinator for inverting the order of arguments of a
two-argument function.
> converse :: (*->**->***)->**->*->***
> converse f a b = f b a
cos is the trigonometric cosine function, argument in radians.
> cos :: num->num ||defined internally
decode applied to a number between 0 and 255 returns the
corresponding value of type char.
> decode :: num->char ||defined internally
digit is a predicate on characters. True if the character is a
digit. See also letter.
> digit :: char->bool
> digit x = '0'<=x<='9'
drop applied to a number and a list returns the list with that many
elements removed from the front. If the list has less than the required
number of elements, drop returns []. Example
drop 2 [1,2,3,4] = [3,4]
See also take.
> drop :: num->[*]->[*] ||defined internally, as below
drop (n+1) (a:x) = drop n x
drop n x = x, if integer n
= error "drop applied to fractional number", otherwise
dropwhile applied to a predicate and a list, removes elements from
the front of the list while the predicate is satisfied. Example:
dropwhile digit "123gone" = "gone"
See also takewhile.
> dropwhile :: (*->bool)->[*]->[*]
> dropwhile f [] = []
> dropwhile f (a:x) = dropwhile f x, if f a
> = a:x, otherwise
e is a transcendental number, the base of natural logarithms.
> e :: num
> e = exp 1
entier when applied to a number returns its integer part, meaning
the largest integer not exceeding it. E.g.
entier 1.0 = 1
entier 3.5 = 3
entier (-3.5) = -4.
Notice that for Miranda the number 1\' and the number1.0are
different values - for example they yield different results under theinteger\' test. However 1=1.0 is True, because of the automatic
conversion from integer to float.
> entier :: num->num ||defined internally
A useful fact about entier, which relates it to the operators
div and mod, is that the following law holds for any integers a,
b with b\~=0 and a/b within the range for which integers can be
represented exactly as fractional numbers
a div b = entier (a/b)
error applied to a string creates an error value with the associated
message. Error values are all equivalent to the undefined value - any
attempt to access the value causes the program to terminate and print
the string as a diagnostic.
> error :: [char]->* ||defined internally
exp\' is the exponential function on real numbers. See alsolog`.
> exp :: num->num ||defined internally
filemode applied to a string representing the pathname of a UNIX
file, returns a string of length four giving the access permissions of
the current process to the file. The permissions are encoded as (in this
order) \"drwx\", any permission not granted is replaced by a \'-\'
character. If there is no file at pathname p, filemode p returns the
empty string. Example
member (filemode f) 'w'
tests f for write permission. See also getenv\',read\', system.
> filemode :: [char]->[char] ||defined internally
filter applied to a predicate and a list, returns a list containing
only those elements that satisfy the predicate. Example
filter (>5) [3,7,2,8,1,17] = [7,8,17]
> filter :: (*->bool)->[*]->[*]
> filter f x = [a | a<-x; f a]
foldl folds up a list, using a given binary operator and a given
start value, in a left associative way. Example:
foldl op r [a,b,c] = (((r $op a) $op b) $op c)
But note that in order to run in constant space, foldl forces op to
evaluate its first parameter. See the definitions of product,
reverse\',sum\' for examples of its use. See also foldr.
> foldl :: (*->**->*)->*->[**]->* ||defined internally, as below
foldl op r [] = r
foldl op r (a:x) = strict (foldl op) (op r a) x
where
strict f x = seq x (f x)
WARNING - this definition of foldl differs from that in older versions
of Miranda. The one here is the same as that in Bird and Wadler (1988).
The old definition had the two args of op reversed. That is:-
old_foldl op r = new_foldl (converse op) r
the function converse has been added to the standard environment.
foldl1 folds left over non-empty lists. See the definitions of
max\',min` for examples of its use.
> foldl1 :: (*->*->*)->[*]->* ||defined internally, as below
foldl1 op (a:x) = foldl op a x
foldl1 op [] = error "foldl1 applied to []"
foldr folds up a list, using a given binary operator and a given
start value, in a right associative way. Example:
foldr op r [a,b,c] = a $op (b $op (c $op r))
See the definitions of and\',concat\', or, for examples of its
use.
> foldr :: (*->**->**)->**->[*]->** ||defined internally, as below
foldr op r [] = r
foldr op r (a:x) = op a (foldr op r x)
foldr1 folds right over non-empty lists.
> foldr1 :: (*->*->*)->[*]->*
> foldr1 op [a] = a
> foldr1 op (a:b:x) = op a (foldr1 op (b:x))
> foldr1 op [] = error "foldr1 applied to []"
force applied to any data structure, returns it, but forces a check
that every part of the structure is defined. Example
hd(force x)
returns the hd of x, but fully evaluates x first (so x must be finite).
See also seq\'. Notice in particular the idiomseq (force a) bwhich returnsb\' but only after fully evaluating a.
> force :: *->* ||defined internally
fst\' returns the first component of a pair. See alsosnd`.
> fst :: (*,**)->*
> fst (a,b) = a
getenv\' looks up a string in the users UNIX environment. Example
getenv "HOME"
returns the pathname of your home directory. [If you want to see what
else is in your UNIX environment, say printenv as a UNIX command.]
> getenv :: [char]->[char] ||defined internally
hd applied to a non empty list, returns its first element. It is an
error to apply hd\' to the empty list, \[\]. See alsotl`.
> hd :: [*]->*
> hd (a:x) = a
> hd [] = error "hd []"
hugenum is the largest fractional number that can exist in this
implementation (should be around 1e308 for IEEE standard 64 bit floating
point). See also tinynum.
> hugenum :: num ||defined internally
id is the identity function - applied to any object it returns it.
> id :: *->*
> id x = x
index applied to a (finite or infinite) list, returns a list of its
legal subscript values, in ascending order. E.g. index \"hippopotamus\"
is [0,1,2,3,4,5,6,7,8,9,10,11].
> index :: [*]->[num]
> index x = f 0 x
> where
> f n [] = []
> f n (a:x) = n:f(n+1)x
init\' is dual totl`, it returns a list without its last
component. Example
init [1,2,3,4] = [1,2,3].
See also last\'. \[Note, by thedual` of a list processing function
we mean the function which does the same job in a world where all lists
have been reversed.]
> init :: [*]->[*]
> init (a:x) = [], if x=[]
> = a:init x, otherwise
> init [] = error "init []"
integer is a predicate on numbers. True if and only if the number is
not fractional.
> integer :: num->bool ||defined internally
[iterate - iterate f x returns the infinite list [x, f x, f(f x),
... ] Example, iterate (2*) 1 yields a list of the powers of 2. In
the definition note use of \", ..\" to express a recurrence relation
(see manual section 13/2).]{#iterate}
> iterate :: (*->*)->*->[*]
> iterate f x = [y | y<-x, f y ..]
last applied to a non empty list returns its last element. This
function is the dual of hd. Note that for any non-empty list x
(init x ++ [last x]) = x
> last :: [*]->* ||defined internally, as below
last x = x!(#x-1)
lay applied to a list of strings, joins them together after
appending a newline character to each string. Example
lay ["hello","world"] = "hello\nworld\n"
Used to format output thus,
lay(map show x)
as a top level expression, causes the elements of the list x to be
printed one per line. See also layn\',lines`.
> lay :: [[char]]->[char]
> lay [] = []
> lay (a:x) = a++"\n"++lay x
layn\' is similar tolay`, but produces output with numbered lines.
> layn :: [[char]]->[char]
> layn x = f 1 x
> where
> f n [] = []
> f n (a:x) = rjustify 4 (show n) ++") "++a++"\n"++f (n+1) x
\'letter\' is a predicate on characters. True if the character is a letter.
> letter :: char->bool
> letter c = 'a'<=c<='z' \/ 'A'<=c<='Z'
limit applied to a list of values, returns the first value which is
the same as its successor. Useful in testing for convergence. For
example the following Miranda expression computes the square root of 2
by the Newton-Raphson method
limit [x | x<-2, 0.5*(x + 2/x).. ]
> limit :: [*]->*
> limit (a:b:x) = a, if a=b
> = limit (b:x), otherwise
> limit other = error "incorrect use of limit"
lines applied to a list of characters containing newlines, returns a
list of lists, by breaking the original into lines. The newline
characters are removed from the result. Example, lines applied to
"hello world\nit's me,\neric\n"
returns [\"hello world\",\"it\'s me\",\"eric\"]. Note that lines
treats newline as a terminator, not a separator (although it will
tolerate a missing \'\n\' on the last line).
> lines :: [char]->[[char]]
> lines [] = []
> lines (a:x) = []:lines x, if a='\n'
> = (a:x1):xrest, otherwise
> where
> (x1:xrest) = lines x, if x~=[]
> = []:[], otherwise
> ||this handles missing '\n' on last line
Note that the inverse of lines\' is the functionlay, in that
applyinglay\' to the output of lines will restore the original
string (except that a final newline will be added, if missing in the
original string).
ljustify applied to a number and a string, left justifies the string
in a field of the specified width.
> ljustify :: num->[char]->[char]
> ljustify n s = s++spaces(n - # s)
log applied to a number returns its natural logarithm (i.e.
logarithm to the base e). It is the inverse of the exponential
function, exp. See also log10. Note that the log functions use a
different algorithm when applied to integer arguments (rather than just
converting to float first) so it is possible to take log, or log10, of
very large integers.
> log :: num->num ||defined internally
log10 applied to a number returns its logarithm to the base 10.
> log10 :: num->num ||defined internally
map applied to a function and a list returns a copy of the list in
which the given function has been applied to every element.
> map :: (*->**)->[*]->[**]
> map f x = [f a | a<-x]
map2\' is similar tomap, but takes a function of two arguments,
and maps it along two argument lists. We could also definemap3,map4` etc., but they are much less often needed.
> map2 :: (*->**->***)->[*]->[**]->[***]
> map2 f x y = [f a b | (a,b)<-zip2 x y]
Note: the Bird and Wadler function zipwith is just an uncurried
version of map2\', that iszipwith f (x,y)\' means map2 f x y.
max applied to a list returns the largest element under the built in
ordering of \>. Examples
max [1,2,12,-6,5] = 12
max "hippopotamus" = 'u'
See also min\',sort`.
> max :: [*]->*
> max = foldl1 max2
max2 applied to two values of the same type returns the larger under
the built in ordering of \'>\'. See also min2.
> max2 :: *->*->*
> max2 a b = a, if a>=b
> = b, otherwise
member applied to a list and a value returns True or False as the
value is or not present in the list.
> member :: [*]->*->bool
> member x a = or (map (=a) x)
merge applied to two sorted lists merges them to produce a single
sorted result. Used to define sort, see later.
> merge :: [*]->[*]->[*] ||defined internally, as below
merge [] y = y
merge (a:x) [] = a:x
merge (a:x) (b:y) = a:merge x (b:y), if a<=b
= b:merge (a:x) y, otherwise
min\' applied to a list returns its least member under\<`.
> min :: [*]->*
> min = foldl1 min2
min2 applied to two values of the same type returns the smaller
under the built in ordering of \'\<\'.
> min2 :: *->*->*
> min2 a b = b, if a>b
> = a, otherwise
mkset applied to a list returns a copy of the list from which any
duplicated elements have been removed. A list without duplications can
be used to represent a set, whence the name. Works even on infinite
list, but (beware) takes a time quadratic in the number of elements
processed.
> mkset :: [*]->[*]
> mkset [] = []
> mkset (a:x) = a:filter (~=a) (mkset x)
neg is a function of one numeric argument, with the same action as
the unary - operator.
> neg :: num->num
> neg x = -x
num is the type comprising both integer and fractional numbers (such
as 42, -12.73e8).
num :: type ||primitive to Miranda
numval converts a numeric string to the corresponding number - can
cope with sign, decimal point and scale factor (uses same rules as
Miranda compiler). Strings containing inappropriate characters cause an
error (exception - leading white space is harmless).
> numval :: [char]->num ||defined internally
or applied to a list of truthvalues, takes their logical
disjunction.
> or :: [bool]->bool
> or = foldr (\/) False
pi is the well known real number (the ratio of the circumference of
a circle to its diameter).
> pi :: num
> pi = 4*arctan 1
postfix takes an element and a list and adds the element to the end
of the list. This is the dual of the prefix operator, :.
> postfix :: *->[*]->[*]
> postfix a x = x ++ [a]
product applied to list of numbers returns their product. See also
sum.
> product :: [num]->num
> product = foldl (*) 1
read returns the contents of file with a given pathname. Provides an
interface to the UNIX filing system. If the file is empty read
returns [], but if the file does not exist, or lacks read permission,
read\' causes an error. See alsofilemode\', getenv.
> read :: [char]->[char] ||defined internally
readvals is a family of functions for reading a list of values from a file. See manual section 31/3.
rep applied to a number and a value, returns a list containing the
specified number of instances of the value. (The name is short for
replicate.) Example
rep 6 'o' = "oooooo"
See also repeat.
> rep :: num->*->[*]
> rep n x = take n (repeat x)
repeat applied to a value returns an infinite list, all of whose
elements are the given value.
> repeat :: *->[*]
> repeat x = xs
> where xs = x:xs
reverse applied to any finite list returns a list of the same
elements in reverse order.
> reverse :: [*]->[*]
> reverse = foldl (converse(:)) []
rjustify applied to a number and a string, right justifies the
string in a field of the specified width.
> rjustify :: num->[char]->[char]
> rjustify n s = spaces(n - # s)++s
scan op r\' appliesfoldl op rto every initial segment of a list.
For examplescan (+) 0 x` computes running sums.
> scan :: (*->**->*)->*->[**]->[*]
> scan op = g
> where
> g r = (r:). rest
> where
> rest [] = []
> rest (a:x) = g (op r a) x
There is another way to explain scan, which makes it clearer why it
is useful. Let s0 be the initial state of an automaton, and
f::state->input->state, its state transition function - then `scan f
s0\' is a function that takes a list of inputs for the automaton and
returns the resulting list of states, starting with s0.
seq applied to two values, returns the second but checks that the
first value is not completely undefined. Sometimes needed, e.g. to
ensure correct synchronisation in interactive programs.
> seq :: *->**->** ||defined internally
show is a keyword denoting a family of functions for converting
values of different types to their print representations. See manual
section on show for more details.
shownum applied to a number returns as a string a standard print
representation for it. A special case of the operator show. Applied
to fractional numbers shownum gives 12 decimal places (less any
trailing zeros), using a format appropriate to the size of number. For
more detailed control over number format see showfloat,
showscaled.
> shownum :: num->[char] ||defined internally,
showfloat p x returns as a string the number x printed in floating
point format, that is in the form \"digits.digits\", where the integer p
(>=0) gives the number of digits after the decimal point.
> showfloat :: num->num->[char] ||defined internally,
showscaled p x returns as a string the number x printed in
scientific format, that is in the form \"n.nnnnnne[+/-]nn\", where the
integer p (>=0) gives the number of digits required after the decimal
point.
> showscaled :: num->num->[char] ||defined internally,
sin is the trigonometric sine function, argument in radians.
> sin :: num->num ||defined internally
snd returns the second component of a pair.
> snd :: (*,**)->**
> snd (a,b) = b
sort applied to any finite list sorts the elements of the list into
ascending order on the built in \'\<\' relation. Note that you cannot
sort a list of functions. Example
sort "hippopotamus" = "ahimoopppstu"
The following definition uses merge-sort, which has n log n worst-case behaviour.
> sort :: [*]->[*]
> sort x = x, if n<=1
> = merge (sort(take n2 x)) (sort(drop n2 x)), otherwise
> where
> n = # x
> n2 = n div 2
spaces applied to a number returns a list of that many spaces.
> spaces :: num->[char]
> spaces n = rep n ' '
sqrt is the square root function on (integer or fractional) numbers.
The result is always fractional.
> sqrt :: num->num ||defined internally
subtract is a name for (converse) infix minus. Needed because you
cannot form postsections in -\'. (See manual entry onsections`.)
Example
subtract 3
is the function that subtracts 3.
> subtract :: num->num->num
> subtract x y = y - x
sum applied to list of numbers returns their sum.
> sum :: [num]->num
> sum = foldl (+) 0
sys_message is an algebraic type containing a family of constructors
used to control output to UNIX files. See manual section on Output to
UNIX files for details.
> sys_message ::= Stdout [char] | Stderr [char] | Tofile [char] [char] |
> Closefile [char] | Appendfile [char] | System [char] |
> Exit num
system applied to a string causes the string to be executed as a
UNIX shell command (by sh). The result returned is a 3-tuple,
comprising the standard_output, error_output, and exit_status
respectively, resulting from the execution of the UNIX command. See
manual section on Input from UNIX files etc for more details.
> system :: [char]->([char],[char],num) ||defined internally
take applied to a number and a list returns the specified number of
elements from the front of the list. If the list has less than the
required number of elements, take returns as many as it can get.
Examples
take 2 [1,2,3,4] = [1,2]
take 7 "girls" = "girls"
> take :: num->[*]->[*] ||defined internally, as below
take (n+1) (a:x) = a : take n x
take n x = [], if integer n
= error "take applied to fractional number", otherwise
takewhile applied to a predicate and a list, takes elements from the
front of the list while the predicate is satisfied. Example: takewhile
digit \"123gone\" = \"123\"
> takewhile :: (*->bool)->[*]->[*]
> takewhile f [] = []
> takewhile f (a:x) = a:takewhile f x, if f a
> = [], otherwise
tinynum is the smallest positive fractional number that can be
distinguished from zero in this implementation (should be around 1e-324
for IEEE standard 64 bit floating point).
> tinynum :: num ||defined internally
tl applied to a non empty list returns the list without its first
element. Example, tl \"snow\" is \"now\".
> tl :: [*]->[*]
> tl (a:x) = x
> tl [] = error "tl []"
transpose applied to a list of lists, returns their transpose (in
the sense of matrix transpose - rows and columns are interchanged).
Example
transpose [[1,2,3],[4,5,6]] = [[1,4],[2,5],[3,6]]
The following definition is slightly more subtle than is at first sight
necessary, in order to deal correctly with upper triangular
matrices. Example
transpose [[1,2,3],[4,5],[6]] = [[1,4,6],[2,5],[3]]
> transpose :: [[*]]->[[*]]
> transpose x = [], if x'=[]
> = map hd x':transpose(map tl x'), otherwise
> where
> x' = takewhile (~=[]) x
It might be thought that this function belongs in a specialised library of matrix handling functions, but it has been found useful as a general purpose list processing function, whence its inclusion in the standard environment.
undef is a name for the completely undefined value. Any attempt
access it results in an error message. Note that undef belongs to
every type.
> undef :: *
> undef = error "undefined"
until applied to a predicate, a function and a value, returns the
result of applying the function to the value the smallest number of
times necessary to satisfy the predicate. Example
until (>1000) (2*) 1 = 1024
> until :: (*->bool)->(*->*)->*->*
> until f g x = x, if f x
> = until f g (g x), otherwise
zip2 applied to two lists returns a list of pairs, formed by tupling
together corresponding elements of the given lists. Example
zip2 [0..3] "type" = [(0,'t'),(1,'y'),(2,'p'),(3,'e')]
This function is often useful in list comprehensions, where it provides an idiom for accessing two generators simultaneously. For example the following expression returns the scalar product of x and y (x,y::[num])
sum [ a*b | (a,b) <- zip2 x y ]
> zip2 :: [*]->[**]->[(*,**)] ||defined internally, as below
zip2 (a:x) (b:y) = (a,b):zip2 x y
zip2 x y = []
Note that if the lists being zipped are of different lengths, the length of the result is that of the shortest list (this holds for zip2 and all the following zip functions).
The function zip3 is analogous but takes three lists and returns a
list of 3-tuples. Similarly for zip4\',zip5\', zip6 - zip
functions above zip6 are not provided in the standard environment.
> zip3 (a:x) (b:y) (c:z) = (a,b,c):zip3 x y z
> zip3 x y z = []
> zip4 (a:w) (b:x) (c:y) (d:z) = (a,b,c,d):zip4 w x y z
> zip4 w x y z = []
> zip5 (a:v) (b:w) (c:x) (d:y) (e:z) = (a,b,c,d,e):zip5 v w x y z
> zip5 v w x y z = []
> zip6 (a:u)(b:v)(c:w)(d:x)(e:y)(f:z) = (a,b,c,d,e,f):zip6 u v w x y z
> zip6 u v w x y z = []
The following is included for compatibility with Bird and Wadler (1988).
The normal Miranda style is to use the curried form zip2.
> zip :: ([*],[**])->[(*,**)]
> zip (x,y) = zip2 x y
End of definitions of the standard environment