From d6639aad989ce19e4a78f0ff203cf5338dec3149 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 28 Nov 2018 11:21:05 -0300 Subject: [PATCH] Add lua functional mini library to fallback scripts --- Themes/_fallback/Scripts/01 Functional.lua | 176 +++++++++++++++++++++ Themes/_fallback/Scripts/09 PackList.lua | 16 -- 2 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 Themes/_fallback/Scripts/01 Functional.lua diff --git a/Themes/_fallback/Scripts/01 Functional.lua b/Themes/_fallback/Scripts/01 Functional.lua new file mode 100644 index 0000000000..10f38a7d17 --- /dev/null +++ b/Themes/_fallback/Scripts/01 Functional.lua @@ -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 diff --git a/Themes/_fallback/Scripts/09 PackList.lua b/Themes/_fallback/Scripts/09 PackList.lua index b1c3c3b385..d4e45ba61b 100644 --- a/Themes/_fallback/Scripts/09 PackList.lua +++ b/Themes/_fallback/Scripts/09 PackList.lua @@ -5,15 +5,8 @@ local getAvgDiffPropName = "GetAvgDifficulty" local getNamePropName = "GetName" function PackList:GetPackTable() - SCREENMAN:SystemMessage(tostring(#(self.packs))) return self.packs end -local foldr = function(func, val, tbl) - for i, v in pairs(tbl) do - val = func(val, v) - end - return val -end function PackList:GetTotalSumByProp(propName) return foldr( function(sum, x) @@ -59,15 +52,6 @@ end function PackList:SortBySize() return self:SortByProp(getSizePropName) end -local 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 function PackList:FilterAndSearch(name, avgMin, avgMax, sizeMin, sizeMax) self.packs = filter(