.. 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.