.. Mars Documentation Copyright (C) 2008 Matt Giuca 3/9/2008 .. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. .. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. .. You should have received a copy of the GNU General Public License along with this program. If not, see . :mod:`prelude` --- Common functions =================================== .. sectionauthor:: Matt Giuca .. moduleauthor:: Matt Giuca .. module:: prelude :synopsis: Common standard library functions. The prelude is where the most common functions are found. This module is typically imported by any *Mars* module. It is not imported by default, but if :command:`mars` is run without any command-line arguments, this module will be loaded. Higher-order helper functions ----------------------------- .. function:: id(x :: a) :: a = x The identity function; returns *x*. .. function:: const(k :: a) :: b -> a Returns a function which returns *k*, regardless of its argument. .. function:: apply0(f :: () -> r) :: r = f() Calls *f* with no arguments. .. function:: apply1(f :: a -> r, x :: a) :: r = f(x) Calls *f* with *x* as an argument. .. function:: apply2(f :: (a, b) -> r, x :: a, y :: b) :: r = f(x, y) Calls *f* with *x* and *y* as arguments. .. function:: curry2(f :: (a, b) -> r) :: a -> b -> r Converts *f* into a curried function -- the resulting function takes one argument and returns a function that takes the second argument and calls *f* with both. .. function:: curry3(f :: (a, b, c) -> r) :: a -> b -> c -> r Converts *f* into a curried function -- the resulting function takes one argument and returns a function that takes the second argument and so on, and calls *f* with all of the arguments. .. function:: curry4(f :: (a, b, c, d) -> r) :: a -> b -> c -> d -> r Converts *f* into a curried function -- the resulting function takes one argument and returns a function that takes the second argument and so on, and calls *f* with all of the arguments. .. function:: compose(f :: b -> c, g :: a -> b) :: a -> c Creates a function which takes one argument and passes it to *g*, then passes the result of that to *f*. .. function:: flip(f :: (a, b) -> c) :: (b, a) -> c Creates a function which passes its two arguments to *f* in the reverse order. Logic functions --------------- .. constant:: false :: Num = 0 The number 0, representing false. .. constant:: true :: Num = 1 The number 1, representing true. .. function:: and(x :: Num, y :: Num) :: Num The Boolean AND of *x* and *y*. If *x* is nonzero, returns *y*; otherwise, returns 0. .. function:: or(x :: Num, y :: Num) :: Num The Boolean OR of *x* and *y*. If *x* is zero, returns *y*; otherwise, returns *x*. .. function:: not(x :: Num) :: Num The Boolean NOT of *x*. If *x* is zero, returns 1; otherwise, returns 0. Comparison functions -------------------- .. function:: ne(x :: a, y :: a) :: Num 1 if *x* is not equal to *y* (according to :func:`eq`), 0 otherwise. .. function:: lt(x :: Num, y :: Num) :: Num 1 if *x* is less than *y*, 0 otherwise. .. function:: le(x :: Num, y :: Num) :: Num 1 if *x* is less than or equal to *y*, 0 otherwise. .. function:: gt(x :: Num, y :: Num) :: Num 1 if *x* is greater than *y*, 0 otherwise. .. function:: ge(x :: Num, y :: Num) :: Num 1 if *x* is greater than or equal to *y*, 0 otherwise. Arithmetic ---------- .. function:: neg(x :: Num) :: Num Returns the negation of *x* (0 - *x*). .. function:: abs(x :: Num) :: Num Returns the absolute value of *x* (a positive number with the same magnitude). .. function:: min(x :: Num, y :: Num) :: Num The lesser value of *x* and *y*. .. function:: max(x :: Num, y :: Num) :: Num The greater value of *x* and *y*. .. function:: ceil(x :: Num) :: Num Returns the smallest integer that is greater than or equal to *x*. This rounds *x* towards positive infinity. .. function:: trunc(x :: Num) :: Num Rounds *x* to an integer, towards zero. .. function:: round(x :: Num) :: Num Rounds *x* towards the nearest integer. Halfway values (those that end in ".5") are rounded away from zero. Tuple types and operations -------------------------- .. note:: Mars doesn't have a general tuple type. It just defines specific types for tuples of arity two, three and four. .. type:: Pair(a, b) :: Pair(a, b) A pair of any two values. .. function:: fst(pair :: Pair(a, b)) :: a The first value of a given *pair*. .. function:: snd(pair :: Pair(a, b)) :: b The second value of a given *pair*. .. type:: Triple(a, b, c) :: Triple(a, b, c) A sequence of any three values. .. type:: Quadruple(a, b, c, d) :: Quadruple(a, b, c, d) A sequence of any four values. Linked List type and operations ------------------------------- .. type:: List(a) :: Cons(head :: a, tail :: List(a)) Nil A linked list of values, all of the same type. This type is incompatible with the :type:`Array` type, but it is possible to convert between the two using :func:`list_to_array` and :func:`array_to_list`. .. function:: empty(list :: List(a)) :: Num Test if *list* is empty. 1 if it is empty, 0 otherwise. .. function:: head(list :: List(a)) :: a The first item in *list*. Aborts if *list* is empty. .. function:: tail(list :: List(a)) :: List(a) The list corresponding to all but first item in *list*. Aborts if *list* is empty. .. function:: ref(list :: List(a), index :: Num) :: a The element of *list* with index *index*. The first element has index 0. It is an error if *index* is non-integral, equal to or greater than the length of the list, or negative. .. function:: length(list :: List(a)) :: Num The number of elements in *list*. .. function:: map(function :: a -> b, list :: List(a)) :: List(b) Applies *function* to each item in *list*, producing a new list containing each of the results. For example, ``map(f, array_to_list([a, b, c]))`` computes ``array_to_list([f(a), f(b), f(c)])``. .. function:: filter(predicate :: a -> Num, list :: List(a)) :: List(a) Produces a new list containing only the items in *list* for which *function* returns a nonzero result. .. function:: foldl(function :: (a, b) -> a, initial :: a, list :: List(b)) :: a Applies *function* to *initial* and the head of *list*, then to the result of that and the second element of *list*, and so on, returning the result of the final application. For example, ``foldl(f, z, array_to_list([a, b, c]))`` computes ``f(f(f(z, a), b), c)``. .. function:: foldl1(function :: (a, a) -> a, list :: List(a)) :: a :func:`foldl` without an initial value. Applies *function* to the first and second elements of *list*, then to the result of that and the third element of *list*, and so on, returning the result of the final application. For example, ``foldl1(f, array_to_list([a, b, c, d]))`` computes ``f(f(f(a, b), c), d)``. .. function:: foldr(function :: (a, b) -> b, initial :: b, list :: List(a)) :: b Applies *function* to the last element of *list* and *initial*, then to the second-last element of *list* and the result of that, and so on, returning the result of the final application. For example ``foldr(f, z, array_to_list([a, b, c]))`` computes ``f(a, f(b, f(c, z)))``. .. function:: foldr1(f :: (a, a) -> a, l :: List(a)) :: a :func:`foldr` without an initial value. Applies *function* to the second-last and last elements of *list*, then to the third-last element and the result of that, and so on, returning the result of the final application. For example, ``foldr1(f, array_to_list([a, b, c, d]))`` computes ``f(a, f(b, f(c, d)))``. .. function:: sum(list :: List(Num)) :: Num Computes the sum of all numbers in *list*. .. function:: minimum(list :: List(Num)) :: Num Computes the minimum of all numbers in *list*. .. function:: maximum(list :: List(Num)) :: Num Computes the minimum of all numbers in *list*. .. function:: reverse(list :: List(a)) :: List(a) Returns the elements of *list* in reverse order. .. function:: append(list1 :: List(a), list2 :: List(a)) :: List(a) Returns the elements of *list1* concatenated onto the front of *list2*. Note that this operation is linear in the length of *list1*, but constant in the length of *list2* (it makes a copy of *list1* but not *list2*). .. function:: index(list :: List(a), item :: a) :: Num Returns the index of the first element of *list* which compares equal (according to :func:`eq`) to *item*, or -1 if no element compares equal. The first element has index 0. .. function:: elem(item :: a, list :: List(a)) :: Num Returns 1 if any element of *list* compares equal (according to :func:`eq`) to *item*; 0 otherwise. .. function:: zip(list1 :: List(a), list2 :: List(b)) :: List(Pair(a, b)) Combine pairwise elements of *list1* and *list2* into a single list of pairs. For example, ``zip(array_to_list([a, b, c]), array_to_list([x, y, z]))`` produces ``array_to_list([Pair(a, x), Pair(b, y), Pair(c, z)])``. If the two lists are not the same length, the resulting list is as long as the shorter list, with the remaining elements of the longer list discarded. .. function:: unzip(list :: List(Pair(a, b))) :: Pair(List(a), List(b)) Separate a list of pairs into a pair of lists with corresponding elements of *list*. The first output list contains the :func:`fst` of each element of *list*, and the second output list contains the :func:`snd` of each element. For example, ``unzip(array_to_list([Pair(a, x), Pair(b, y), Pair(c, z)]))`` produces ``Pair(array_to_list([a, b, c]), array_to_list([x, y, z]))``. .. function:: range(start :: Num, end :: Num) :: List(Num) Returns a list of integers from *start*, inclusive, to *end*, exclusive. The arguments should be integers (if not, this will return values spaced 1 apart between *start* and *end*). .. function:: list_to_array(list :: List(a)) :: Array(a) Convert *list* to an :type:`Array` of the same elements. .. function:: array_to_list(array :: Array(a)) :: List(a) Convert *array* to a :type:`List` of the same elements. Array operations ---------------- .. function:: array_map(function :: a -> b, array :: Array(a)) :: Array(b) Applies *function* to each item in *array*, producing a new array containing each of the results. For example, ``array_map(f, [a, b, c])`` computes ``[f(a), f(b), f(c)]``. .. function:: array_filter(function :: a -> Num, array :: Array(a)) :: Array(a) Produces a new array containing only the items in *array* for which *function* returns a nonzero result. .. function:: array_foldl(function :: (a, b) -> a, initial :: a, array :: Array(b)) :: a Applies *function* to *initial* and the first element of *array*, then to the result of that and the second element of *array*, and so on, returning the result of the final application. For example, ``array_foldl(f, z, [a, b, c])`` computes ``f(f(f(z, a), b), c)``. .. function:: array_foldl1(function :: (a, a) -> a, array :: Array(a)) :: a :func:`array_foldl` without an initial value. Applies *function* to the first and second elements of *array*, then to the result of that and the third element of *array*, and so on, returning the result of the final application. For example, ``array_foldl1(f, [a, b, c, d])`` computes ``f(f(f(a, b), c), d)``. .. function:: array_foldr(function :: (a, b) -> b, initial :: b, array :: Array(a)) :: b Applies *function* to the last element of *array* and *initial*, then to the second-last element of *array* and the result of that, and so on, returning the result of the final application. For example ``array_foldr(f, z, [a, b, c])`` computes ``f(a, f(b, f(c, z)))``. .. function:: array_foldr1(function :: (a, a) -> a, array :: Array(a)) :: a :func:`array_foldr` without an initial value. Applies *function* to the second-last and last elements of *array*, then to the third-last element and the result of that, and so on, returning the result of the final application. For example, ``array_foldr1(f, [a, b, c, d])`` computes ``f(a, f(b, f(c, d)))``. .. function:: array_substr(array :: Array(a), start :: Num, length :: Num) :: Array(a) Returns an array consisting of all elements of *array* from *start*, inclusive, to *start* + *length*, exclusive. Out-of-range indices are dropped silently, so the resulting array may be shorter than *length*. It is an error if *start* is non-integral. If *length* is non-integral, it is rounded up. .. function:: array_index(array :: Array(a), item :: a) :: Num Returns the index of the first element of *array* which compares equal to *item*, or -1 if no element compares equal. The first element has index 0. .. function:: array_elem(item :: a, array :: Array(a)) :: Num Returns 1 if *item* is an element of *array*; 0 otherwise. .. function:: array_zip(array1 :: Array(a), array2 :: Array(b)) :: Array(Pair(a, b)) Combine pairwise elements of *array1* and *array2* into a single array of pairs. For example, ``zip([a, b, c], [x, y, z])`` produces ``[Pair(a, x), Pair(b, y), Pair(c, z)]``. If the two arrays are not the same length, the resulting array is as long as the shorter array, with the remaining elements of the longer array discarded. .. function:: array_unzip(array :: Array(Pair(a, b))) :: Pair(Array(a), Array(b)) Separate an array of pairs into a pair of arrays with corresponding elements of *array*. The first output array contains the :func:`fst` of each element of *array*, and the second output array contains the :func:`snd` of each element. For example, ``unzip([Pair(a, x), Pair(b, y), Pair(c, z)])`` produces ``Pair([a, b, c], [x, y, z])``. .. function:: array_range(start :: Num, end :: Num) :: Array(Num) Returns an array of integers from *start*, inclusive, to *end*, exclusive. (See :func:`range` for a discussion on non-integral inputs to this function.) Maybe type and operations ------------------------- .. type:: Maybe(a) :: Just(value :: a) Nothing A container for a single value, which may or may not exist. As *Mars* has no "``null``" value, any value which might be non-existant should have type :type:`Maybe(a)`, and non-existant values should be represented as :func:`Nothing`. .. function:: null(value :: Maybe(a)) :: Num Test if *value* is empty. 1 if it is :func:`Nothing`, 0 if it is a :func:`Just` value. I/O --- .. constant:: eof :: Num = -1 Represents the "end of file" condition in the output of the built-in function :func:`get_char`. Note that :const:`eof` is not actually a character; it is a special value indicating that no more bytes can be read from a file. .. function:: print_char_list(string :: List(Num)) :: io Num Writes *string* to standard output, where *string* is a list of byte values. This calls :func:`put_char` on each element of *string*. It is an error if any element is non-integral or outside the range [0, 255]. Does not print a newline. See also: :func:`print_string`. .. function:: print_string(string :: Array(Num)) :: io Num Writes *string* to standard output. This calls :func:`put_char` on each element of *string*. It is an error if any element non-integral or is outside the range [0, 255]. Does not print a newline. .. note:: This function (as with all input/output functions) can only be called from an :keyword:`io` context. To print text from a technically-pure function, consider the :func:`trace` function in the :mod:`debug` module. Note that this is only intended for debugging purposes! .. function:: print_value(value :: a) :: io Num Writes a string representation of *value* to standard output. This is equivalent to ``print_string(show(value))``. See also: :func:`print_string`, :func:`show`. .. function:: get_line_list() :: io List(Num) Reads a line (sequence of bytes terminated by ``'\n'``) from standard input, returning a list of byte values. The list does not contain the ``'\n'`` character. See also: :func:`get_line`. .. function:: get_line() :: io Array(Num) Reads a line (sequence of bytes terminated by ``'\n'``) from standard input, returning a string. The string does not contain the ``'\n'`` character.