.. Mars Documentation
Copyright (C) 2008 Matt Giuca
5/1/2012
.. 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:`iofuncs` --- I/O versions of higher-order functions
=========================================================
.. sectionauthor:: Matt Giuca
.. moduleauthor:: Matt Giuca
.. module:: iofuncs
:synopsis: I/O versions of higher-order functions.
Mars requires the use of the :keyword:`io` keyword to create a function
capable of performing I/O operations. Due to the simplistic I/O annotation
system in Mars, it is not possible to generalise higher-order functions to
work on both pure and I/O function values. This is limiting: for example, the
higher-order function :func:`map` only operates on pure functions. Indeed, it
would not be valid for :func:`map` to operate on I/O functions, because
:func:`map` itself is not permitted to perform side-effects. However, this
makes it impossible to easily apply an I/O action to each element of a list
from within an I/O context.
This module provides an equivalent of every higher-order function in the
:mod:`prelude`, but the versions here accept and return I/O-annotated
functions. Where necessary, the versions here are themselves required to be
called from an I/O context. In general, functions that manipulate (but do not
call) I/O function values, such as :func:`flipio`, may be called from a pure
context, but functions that call I/O function values, such as :func:`mapio`,
must be called from an I/O context.
This module also provides the *toio* (read as "to I/O") family of functions,
which convert pure functions to I/O functions, in order to use pure functions
with the other higher-order functions in this module.
Higher-order helper functions
-----------------------------
.. function:: toio0(f :: () -> r) :: () ->io r
Converts a pure nullary function *f* to an I/O function.
.. function:: toio1(f :: a -> r) :: a ->io r
Converts a pure unary function *f* to an I/O function.
.. function:: toio2(f :: (a, b) -> r) :: (a, b) ->io r
Converts a pure binary function *f* to an I/O function.
.. function:: applyio0(f :: () ->io r) :: io r = f()
Calls *f* with no arguments.
.. function:: applyio1(f :: a ->io r, x :: a) :: io r = f(x)
Calls *f* with *x* as an argument.
.. function:: applyio2(f :: (a, b) ->io r, x :: a, y :: b) :: io r = f(x, y)
Calls *f* with *x* and *y* as arguments.
.. function:: curryio2(f :: (a, b) ->io r) :: a -> b ->io 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:: curryio3(f :: (a, b, c) ->io r) :: a -> b -> c ->io 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:: curryio4(f :: (a, b, c, d) ->io r) :: a -> b -> c -> d ->io 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:: composeio(f :: b ->io c, g :: a ->io b) :: a ->io c
Creates a function which takes one argument and passes it to *g*, then
passes the result of that to *f*.
.. function:: flipio(f :: (a, b) ->io c) :: (b, a) ->io c
Creates a function which passes its two arguments to *f* in the reverse
order.
Linked List operations
----------------------
.. function:: mapio(function :: a ->io b, list :: List(a)) :: io List(b)
Applies *function* to each item in *list*, in order from head to tail,
producing a new list containing each of the results.
.. function:: filterio(predicate :: a ->io Num, list :: List(a)) :: io List(a)
Applies *function* to each item in *list*, in order from head to tail,
producing a new list containing only the items in *list* for which
*function* returned a nonzero result.
.. function:: foldlio(function :: (a, b) ->io a, initial :: a, list :: List(b)) :: io 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.
.. function:: foldrio(function :: (a, b) ->io b, initial :: b, list :: List(a)) :: io 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.
Array operations
----------------
.. function:: array_mapio(function :: a ->io b, array :: Array(a)) :: io Array(b)
Applies *function* to each item in *array*, in order from first to last,
producing a new array containing each of the results.
.. function:: array_filterio(function :: a ->io Num, array :: Array(a)) :: io Array(a)
Applies *function* to each item in *array*, in order from first to last,
producing a new array containing only the items in *array* for which
*function* returned a nonzero result.
.. function:: array_foldlio(function :: (a, b) ->io a, initial :: a, array :: Array(b)) :: io 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.
.. function:: array_foldrio(function :: (a, b) ->io b, initial :: b, array :: Array(a)) :: io 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.