summaryrefslogtreecommitdiff
path: root/miralib/stdenv.m
blob: 8c53ac83e2bf27586eca41b497aa1fb459d60fba (plain)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
> ||The Miranda Standard Environment  (C) Research Software Limited 1989

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.

Added October 2019 - showhex, showoct - see below.

`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 the  Latin-1  character  set  (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 its code number.  Example
        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 an integer returns the character with that code.

> 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  number `1.0' are
different values - for example they yield different  results  under  the
`integer'  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 also `log'.

> 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

`filestat'  applied  to  a  UNIX   pathname   returns   three   integers
((inode,device),mtime),  where  mtime  is  the time-last-modified of the
file, in seconds since 00.00h on 1 Jan 1970.   The  pair  (inode,device)
identifies a file uniquely, regardless of the pathname used to reach it.
A non-existent file has inode & device (0,-1) and mtime 0.

> filestat :: [char]->((num,num),num)  ||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 idiom `seq (force a) b'  which
returns `b' but only after fully evaluating `a'.

> force :: *->* ||defined internally

`fst' returns the first component of a pair.  See also `snd'.

> fst :: (*,**)->*
> fst (a,b) = a

`getenv' looks up a string in the user's 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 also `tl'.

> 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 to `tl', it returns a list without  its  last  component.
Example
        init [1,2,3,4] = [1,2,3].
See  also `last'.  [Note, by the `dual' 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.

> iterate :: (*->*)->*->[*]
> iterate f x = [y | y<-x, f y ..]

Note use of ", .." to generate an arbitrary sequence (see manual section
13/2).

`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 to `lay', 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 function `lay', in that applying
`lay'  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 to `map', but takes a function of two  arguments,  and
maps  it  along two argument lists.  We could also define `map3', `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 is `zipwith 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 - accepts
optional leading "-" followed by integer or floating point number, using
same rules as the 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 also `filemode', `getenv'.

> read :: [char]->[char]  ||defined internally

`readb' reads a file as bytes - useful in a UTF-8 locale,  where  binary
data  may  contain  illegal characters if read as text.  (In a non UTF-8
locale the results of read and readb do not differ.) See manual  section
31/9 for more information.

> readb :: [char]->[char]  ||defined internally

_r_e_a_d_v_a_l_s 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' applies `foldl op r' to every initial  segment  of  a  list.
For example `scan (+) 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

_s_h_o_w is a keyword denoting a family of functions for  converting  values
of  different  types to their print representations.  See manual section
23 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 16 significant figures  (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,

`showhex', `showoct' applied to an integer  return  its  hexadecimal  or
octal  representation  as a string.  Note that showhex will also convert
floating point numbers to hexdecimal format as per the C 2011  standard.
Example
	showhex pi => 0x1.921fb54442d18p+1
the scale factor in p is a power of 2 (oddly, this part is in decimal).

> showhex, showoct :: 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 page 9 on `sections'.)
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 31/2 on Output
to UNIX files.  The binary versions Stdoutb etc are used to write binary
data in a UTF-8 locale, see section 31/9 for more information.

> sys_message ::= Stdout [char] | Stderr [char] | Tofile [char] [char] |
>                 Closefile [char] | Appendfile [char] | System [char] |
>                 Exit num |  Stdoutb [char] |  Tofileb [char] [char]  |
>                 Appendfileb [char]

`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
31/1 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  traversing  two  lists  in  parallel.   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