--[[ -- Author: Patrick Carroll -- -- This file is part of lambda.lua. -- -- lambda.lua 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. -- -- lambda.lua 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 lambda.lua. If not, see . --]] local P = {} lambda = P --[[ -- map(fn, ...) -- -- Arguments: -- fn(...) - This function should take as many arguments as the number of -- lists being supplied. -- ... - map() takes a variable number of lists as it's last argument. All -- lists given should be at least as long as the first list. The above -- function will be called with each of the elements from each of the lists -- at every index up to the length of the first list. -- -- Returns: -- A list of the accumulated results of calling fn() on every element of the -- given lists. -- -- Example Usage: -- To double all of the elements in a list: -- -- > lambda.map(function(a) return a * 2 end, {1, 2, 3}) -- -> {2, 4, 6} -- -- Or to find the sum of each of the corresponding elements in the two lists: -- -- > lambda.map(function(a, b) return a + b end, {1, 2, 3}, {4, 5, 6}) -- -> {5, 7, 9} -- --]] function P.map(fn, ...) assert(arg.n > 0, "map() must be called with at least one list.") local lists = {} for i = 1, arg.n do table.insert(lists, arg[i]) end -- go through each of the elements in lists and call fn() on each -- set of elements res = {} for i, _ in pairs(lists[1]) do -- collect one argument from each of the lists local this_arg = {} for _, l in pairs(lists) do table.insert(this_arg, l[i]) end -- collect the results of applying fn() to it table.insert(res, fn(unpack(this_arg))) end return res end --[[ -- filter(fn, list) -- -- Pick elements out of a list which match a given criteria. -- -- Arguments: -- fn(x) - A function which takes one argument and returns a true or false -- value, determining whether or not it will be included in the resulting -- list. -- list - The list of elements to successively call fn(x) with. -- -- Returns: -- A list of elements in list which satisfy by the given function -- -- Example Usage: -- To find the even elements in a list: -- -- > lambda.filter(function(a) return (a % 2 == 0) end, {1, 2, 3, 4, 5, 6}) -- -> {2, 4, 6} -- --]] function P.filter(fn, list) local ret = {} for _, elem in pairs(list) do if fn(elem) then table.insert(ret, elem) end end return ret end --[[ -- reduce(fn, initial, list) -- -- Apply a calculation successively down the elements of a list to accumulate -- a single value. -- -- Arguments: -- fn(a, b) - A function which takes two elements at a time and performs the -- required operation and returns a result. -- initial - The initial value given to start the operation. -- list - The list of elements to be reduced. -- -- Returns: -- A single value which is the accumulation of calling fn(a, b) on each pair -- of successive elements in the list -- -- Example Usage: -- To add all of the elements in a list: -- -- > lambda.reduce(function(a, b) return a + b end, 0, {1, 2, 3, 4}) -- -> 10 -- --]] function P.reduce(fn, initial, list) local ret = initial for _, elem in pairs(list) do ret = fn(ret, elem) end return ret end