-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add lua functional mini library to fallback scripts
- Loading branch information
1 parent
8da0bbd
commit d6639aa
Showing
2 changed files
with
176 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
-- Functional Library | ||
-- | ||
-- @file functional.lua | ||
-- @author Shimomura Ikkei | ||
-- @date 2005/05/18 | ||
-- | ||
-- @brief porting several convenience functional utilities form Haskell,Python etc.. | ||
|
||
-- map(function, table) | ||
-- e.g: map(double, {1,2,3}) -> {2,4,6} | ||
function map(func, tbl) | ||
local newtbl = {} | ||
for i, v in pairs(tbl) do | ||
newtbl[i] = func(v) | ||
end | ||
return newtbl | ||
end | ||
|
||
-- filter(function, table) | ||
-- e.g: filter(is_even, {1,2,3,4}) -> {2,4} | ||
function filter(func, tbl) | ||
local newtbl = {} | ||
for i, v in pairs(tbl) do | ||
if func(v) then | ||
newtbl[i] = v | ||
end | ||
end | ||
return newtbl | ||
end | ||
|
||
-- head(table) | ||
-- e.g: head({1,2,3}) -> 1 | ||
function head(tbl) | ||
return tbl[1] | ||
end | ||
|
||
-- tail(table) | ||
-- e.g: tail({1,2,3}) -> {2,3} | ||
-- | ||
-- XXX This is a BAD and ugly implementation. | ||
-- should return the address to next porinter, like in C (arr+1) | ||
function tail(tbl) | ||
if table.getn(tbl) < 1 then | ||
return nil | ||
else | ||
local newtbl = {} | ||
local tblsize = table.getn(tbl) | ||
local i = 2 | ||
while (i <= tblsize) do | ||
table.insert(newtbl, i - 1, tbl[i]) | ||
i = i + 1 | ||
end | ||
return newtbl | ||
end | ||
end | ||
|
||
-- foldr(function, default_value, table) | ||
-- e.g: foldr(operator.mul, 1, {1,2,3,4,5}) -> 120 | ||
function foldr(func, val, tbl) | ||
for i, v in pairs(tbl) do | ||
val = func(val, v) | ||
end | ||
return val | ||
end | ||
|
||
-- reduce(function, table) | ||
-- e.g: reduce(operator.add, {1,2,3,4}) -> 10 | ||
function reduce(func, tbl) | ||
return foldr(func, head(tbl), tail(tbl)) | ||
end | ||
|
||
-- curry(f,g) | ||
-- e.g: printf = curry(io.write, string.format) | ||
-- -> function(...) return io.write(string.format(unpack(arg))) end | ||
function curry(f, g) | ||
return function(...) | ||
return f(g(unpack(arg))) | ||
end | ||
end | ||
|
||
-- bind1(func, binding_value_for_1st) | ||
-- bind2(func, binding_value_for_2nd) | ||
-- @brief | ||
-- Binding argument(s) and generate new function. | ||
-- @see also STL's functional, Boost's Lambda, Combine, Bind. | ||
-- @examples | ||
-- local mul5 = bind1(operator.mul, 5) -- mul5(10) is 5 * 10 | ||
-- local sub2 = bind2(operator.sub, 2) -- sub2(5) is 5 -2 | ||
function bind1(func, val1) | ||
return function(val2) | ||
return func(val1, val2) | ||
end | ||
end | ||
function bind2(func, val2) -- bind second argument. | ||
return function(val1) | ||
return func(val1, val2) | ||
end | ||
end | ||
|
||
-- is(checker_function, expected_value) | ||
-- @brief | ||
-- check function generator. return the function to return boolean, | ||
-- if the condition was expected then true, else false. | ||
-- @example | ||
-- local is_table = is(type, "table") | ||
-- local is_even = is(bind2(math.mod, 2), 1) | ||
-- local is_odd = is(bind2(math.mod, 2), 0) | ||
is = function(check, expected) | ||
return function(...) | ||
if (check(unpack(arg)) == expected) then | ||
return true | ||
else | ||
return false | ||
end | ||
end | ||
end | ||
|
||
-- operator table. | ||
-- @see also python's operator module. | ||
operator = { | ||
mod = math.mod, | ||
pow = math.pow, | ||
add = function(n, m) | ||
return n + m | ||
end, | ||
sub = function(n, m) | ||
return n - m | ||
end, | ||
mul = function(n, m) | ||
return n * m | ||
end, | ||
div = function(n, m) | ||
return n / m | ||
end, | ||
gt = function(n, m) | ||
return n > m | ||
end, | ||
lt = function(n, m) | ||
return n < m | ||
end, | ||
eq = function(n, m) | ||
return n == m | ||
end, | ||
le = function(n, m) | ||
return n <= m | ||
end, | ||
ge = function(n, m) | ||
return n >= m | ||
end, | ||
ne = function(n, m) | ||
return n ~= m | ||
end | ||
} | ||
|
||
-- enumFromTo(from, to) | ||
-- e.g: enumFromTo(1, 10) -> {1,2,3,4,5,6,7,8,9} | ||
-- TODO How to lazy evaluate in Lua? (thinking with coroutine) | ||
enumFromTo = function(from, to) | ||
local newtbl = {} | ||
local step = bind2(operator[(from < to) and "add" or "sub"], 1) | ||
local val = from | ||
while val <= to do | ||
table.insert(newtbl, table.getn(newtbl) + 1, val) | ||
val = step(val) | ||
end | ||
return newtbl | ||
end | ||
|
||
-- make function to take variant arguments, replace of a table. | ||
-- this does not mean expand the arguments of function took, | ||
-- it expand the function's spec: function(tbl) -> function(...) | ||
function expand_args(func) | ||
return function(...) | ||
return func(arg) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters