lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> 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