iofuncs — I/O versions of higher-order functions

Mars requires the use of the 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 map only operates on pure functions. Indeed, it would not be valid for map to operate on I/O functions, because 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 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 flipio, may be called from a pure context, but functions that call I/O function values, such as 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

toio0(f :: () → r) :: () → io r

Converts a pure nullary function f to an I/O function.

toio1(f :: ar) :: a → io r

Converts a pure unary function f to an I/O function.

toio2(f :: (a, b) → r) :: (a, b) → io r

Converts a pure binary function f to an I/O function.

applyio0(f :: () → io r) :: io r = f()

Calls f with no arguments.

applyio1(f :: a → io r, x :: a) :: io r = f(x)

Calls f with x as an argument.

applyio2(f :: (a, b) → io r, x :: a, y :: b) :: io r = f(x, y)

Calls f with x and y as arguments.

curryio2(f :: (a, b) → io r) :: ab → 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.

curryio3(f :: (a, b, c) → io r) :: abc → 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.

curryio4(f :: (a, b, c, d) → io r) :: abcd → 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.

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.

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

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.

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.

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.

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

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.

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.

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.

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.