• Subject: Re: Standard Libraries:
• From: Wim Couwenberg <wim.couwenberg@...>
• Date: Sun, 20 Dec 2009 13:26:08 +0100

```> The other ugly part, however, is lack of convenient chaining support for these sort of constructs.

Here's a version that uses function composition for that.  It depends
on the convention that a "usual" iterator (like pairs, ipairs) does
not return a function as its second return value.  The final for loop
below shows how to use this construction.

Also note that the experiment below uses tail calls instead of
constructs like {...} and select to catch a variable number of return
values.

Bye,
Wim

local type = type

local function _chain(f, state, key)
return function(s, k, ...)
if type(s) == "function" then
return _chain(s(f, state, key, k, ...))
else
return f(s, k)
end
end, state, key
end

chain = _chain

function filter(f, state, key, test)
local function self(s, k, ...)
if k ~= nil then
if test(k, ...) then
return k, ...
end
return self(s, f(s, k))
end
end

return function(s, k)
return self(s, f(s, k))
end, state, key
end

function map(f, state, key, op)
local function self(k, ...)
if k ~= nil then
return op(k, ...)
end
end

return function(s, k)
return self(f(s, k))
end, state, key
end

function is_odd(i, x)
return x%2 == 1
end

function square(i, x)
return i, x^2
end

list = {1,2,3,4,5,6,7,8,9,10}

for i, x in chain(ipairs(list)) (map, square) (filter, is_odd) do
print(i, x)
end

```