/** * This module contains a collection of strategies for working with * lists of integers. */ module collection/list/integer imports collection/list/- term/integer strategies /** * Returns the sum of all integers in a list of integers * * @type List(Int) -> Int */ sum = foldr(!0, add) /** * Returns the average of all integers in a list of * integers. The result is an integer, which is * truncated (rounded down). * * @type List(Int) -> Int */ average = split(sum, length); div /** * Returns the lowest integer in a list of integers. * * @type List(Int) -> Int */ list-min = list-accum(min) /** * Returns the highest integer in a list of integers. * * @type List(Int) -> Int */ list-max = list-accum(max) /** * Reduces a list, applying s successively between * the head and tail of the list. This strategy is * related to foldl. * * Example: <list-accum(id)> [1,2,3] => (3,(2,1)) * * @param (a,b) -> c * @type List(a) -> d */ list-accum(s) = !(<Tl>, <Hd>); foldl(s) /** * Adds together multiple lists of numbers. The input * is a list of integer (or real) lists, which all must * be of the same length. The result is one list of * the same length, i.e. a sum of vectors. * * Example: <add-lists> [[1.0,2.0],[3,4],[6,7]] => [1.000000000000000e+01,1.300000000000000e+01] * * @type List(List(Number)) -> List(Number) */ add-lists = list-accum(zip(add <+ !"")) /** * Sort a list of integers in ascending order. * * @inc sort-test * * @type List(Int) -> List(Int) */ int-sort = sort-list(SortL(gt)) /** * Succeeds if the integer list is an ascending number * sequence, increasing by one, starting at a given * number. The range strategy can be used to * * Example: <is-interval-from> (3, [4,5,6,7]) => 7 * * @inc is-interval-test * * @type List(Int) -> _ */ is-interval-from = rec r( \ (low,[]) -> low \ <+ {l: \ (low,[x|xs]) -> <r>(x,xs) where <add>(low,1) => l ; <eq>(x,l)\ } ) strategies /** * Generates range of numbers in the form of an integer list. This * version of range accepts only one integer as input. The generated * sequence of integers is generated, starts at 0 and increases by one * until the specified end point is reached. The end point is never * part of the generated list. * * Example: <range> 10 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * * @type Int -> List(Int) * @type Int * Int -> List(Int) * @since 0.9.3 */ range = is-int; <range> (0, <id>) /** * Generates a range of numbers in the form of an integer list. This version * of range accepts two integers as input. The first is the lower bound, of * the sequence, the second is the upper bound. The upper bound is never * part of the generated list. * * Example: <range> (5, 10) => [5, 6, 7, 8, 9] * * @type Int * Int -> List(Int) * @since 0.9.3 */ range = (is-int, is-int); range(|1) strategies /** * Generates a sequence of integers, using a specified step size. This version * of range starts at zero and adds one integer to the sequence for every * step specified by the term argument. The input term gives the upper bound * of the sequence, and is never included. The step size is allowed * to be negative. * * Example: <range(|3)> 10 => [0, 3, 6, 9] * Example: <range(|-30)> (-10, -100) => [-10, -40, -70] * * @type step Int * @type Int -> List(Int) * @type Int * Int -> List(Int) * @since 0.9.3 */ range(|step) = is-int; <range(|step)> (0, <id>) /** * Generates a sequence of integers, using a specified step size. This version * of range starts at zero and adds one integer to the sequence for every * step specified by the term argument. The input terms give the lower and * upper bound of the sequence, respectively. The upper bound is never * included. The step size is allowed to be negative. * * Example: <range(|3)> (0, 10) => [0, 3, 6, 9] * * @type step Int * @type Int -> List(Int) * @type Int * Int -> List(Int) * @since 0.9.3 */ range(|step) = (is-int, is-int); range(<add> (<id>, step)) strategies /** * Generates a sequence of numbers using a generator strategy. The * input integer is the upper bound. The strategy argument is a * generator which specifies how to go from the current number in * the sequence to the next. The sequence starts at 0. * * Example: <range(inc)> 5 => [0,1,2,3,4] * * @type next Int -> Int * @type Int -> List(Int) */ range(next) = is-int; <range(next)> (0, <id>) /** * Generates a sequence of numbers using a generator strategy. The * input integers are the lower and upper bounds, respectively. The * strategy argument is a generator which specifies how to go from * the current number in the sequence to the next. * * * Example: <range(inc)> (2,5) => [2,3,4] * * @type Int * Int -> List(Int) * @since 0.9.3 */ range(next) = (is-int, is-int); range-next(next) <+ ![] /** @internal */ range-next(inc) : (start, end) -> [start | tail] where <inc> start => next ; ( (<lt-lt> (start, next, end) + <lt-lt> (end, next, start)) ; <range(inc)> (next, end) <+ (<lt-leq> (start, end, next) + <leq-lt> (next, end, start)) ; ![] ) => tail rules /** * Succeeds if the input term is a list of monotonously increasing * integers and the difference between two adjacent integers is * always one. * * Example: <is-interval> [1,2,3,4,5] => (1,5) * * @type List(Int) -> _ */ is-interval: [x|xs] -> (x,<is-interval-from>(x,xs))