diff options
Diffstat (limited to 'miralib/stdenv.m')
-rw-r--r-- | miralib/stdenv.m | 761 |
1 files changed, 761 insertions, 0 deletions
diff --git a/miralib/stdenv.m b/miralib/stdenv.m new file mode 100644 index 0000000..8c53ac8 --- /dev/null +++ b/miralib/stdenv.m @@ -0,0 +1,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 + |