• Subject: iterator sequences (was: Standard libraries)
• From: Wim Couwenberg <wim.couwenberg@...>
• Date: Fri, 1 Jan 2010 16:42:00 +0100

```As a pastime on new years day I updated my code for iterator sequences
from a previous post.  It is simpler, more efficient and more
powerful.  :-)  As a new example it shows how to easily combine steps
in a sequece to form a new primitive operator.  In this case: map
tonumber and filter out actual numbers.

The main function is "seq" that creates a sequence from an iterator.
The "map" and "filter" operators are included as basic operators (it
is easy to roll your own).   Finally two examples show how to use all
this...

Bye,
Wim

local type = type

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

function filter(seq, f, 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
end

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

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

-- -- only example code below this line -- --

-- a first simple example showing the use of "seq", "map" and "filter"

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

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

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

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

-- a seconde example that shows how to easily combine steps in a sequence

local function is_number(i, x)
return type(x) == "number"
end

local function to_number(i, x)
return i, tonumber(x)
end

local function select_numbers(seq)
seq(map, to_number)(filter, is_number)
end

list = {"1", "2", "aap", "3", false, "4", 5, {}}

for i, x in seq(ipairs(list)) (select_numbers) do
print(i, x)
end

```