function wrap(fn, ...) local funargs = {...} return function() return fn(table.unpack(funargs)) end end function unwrap(fn, ...) return fn(...) end function seq(fns) for _, fn in ipairs(fns) do fn() end end function iopri(...) return wrap(io.write, ...) end function iorea(...) return wrap(io.read, ...) end function make_hi(who) return iopri(string.format("Hello, %s\n", who)) end local mef = make_hi("me") seq { iopri("Hello, "), iopri("world!\n"), iopri("Inefficient monadic programming here!\n"), mef, mef } local l = unwrap(iorea()) unwrap(iopri("read: " .. l .. "\n"))