# Functional Library

``` -- 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)
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)
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.
-- @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.
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
```

• TODO: YCombinator, IteratorChain?, ...

### Sample codes

``` local product = bind1(reduce, operator.mul)