Skip to content

Commit

Permalink
enhance(func) Extend compose to suport N functions (#448)
Browse files Browse the repository at this point in the history
  • Loading branch information
broma0 committed Dec 28, 2022
1 parent ca34942 commit 7e67bcb
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 6 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ deprecation policy.

see [CONTRIBUTING.md](CONTRIBUTING.md#release-instructions-for-a-new-version) for release instructions

## 1.13.x (unreleased)
## 1.14.0 (unreleased)
- feat(func): extend `compose` to support N functions
[#448](https://github.com/lunarmodules/Penlight/pull/448)
- fix(utils) `nil` values in `utils.choose(cond, val1, val2)`
[#447](https://github.com/lunarmodules/Penlight/pull/#447)
[#447](https://github.com/lunarmodules/Penlight/pull/447)

## 1.13.1 (2022-Jul-22)
- fix: `warn` unquoted argument
Expand Down
15 changes: 11 additions & 4 deletions lua/pl/func.lua
Original file line number Diff line number Diff line change
Expand Up @@ -336,13 +336,20 @@ utils.add_function_factory(_PEMT,func.I)
func.bind1 = utils.bind1
func.curry = func.bind1

--- create a function which chains two functions.
--- create a function which chains multiple functions.
-- @func f a function of at least one argument
-- @func g a function of at least one argument
-- @param ... additional functions to compose
-- @return a function
-- @usage printf = compose(io.write,string.format)
function func.compose (f,g)
return function(...) return f(g(...)) end
-- @usage printf = compose(io.write, string.format)
-- @usage printf = compose(io.write, string.lower, string.format)
function func.compose (...)
local args = pack(...)
return tablex.reduce(function(f, g)
return function(...)
return f(g(...))
end
end, args)
end

--- bind the arguments of a function to given values.
Expand Down
54 changes: 54 additions & 0 deletions spec/func_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
local func = require("pl.func")

describe("pl.func", function ()

describe("compose", function ()

it("compose(f)(x) == f(x)", function ()
local f = function(x) return x + 1 end
assert.equals(func.compose(f)(1), f(1))
end)

it("compose(f, g)(x) == f(g(x))", function ()
local f = function(x) return x + 1 end
local g = function(x) return x + 2 end
assert.equals(func.compose(f, g)(1), f(g(1)))
end)

it("compose(f, g, h)(x) == f(g(h(x)))", function ()
local f = function(x) return x + 1 end
local g = function(x) return x + 2 end
local h = function(x) return x + 3 end
assert.equals(func.compose(f, g, h)(1), f(g(h(1))))
end)

it("compose(f)(x, y) == f(x, y)", function ()
local f = function(x, y) return x + 1, y + 1 end
local ax, ay = func.compose(f)(1, 2)
local bx, by = f(1, 2)
assert.equals(ax, bx)
assert.equals(ay, by)
end)

it("compose(f, g)(x, y) == f(g(x, y))", function ()
local f = function(x, y) return x + 1, y + 1 end
local g = function(x, y) return x + 2, y + 2 end
local ax, ay = func.compose(f, g)(1, 2)
local bx, by = f(g(1, 2))
assert.equals(ax, bx)
assert.equals(ay, by)
end)

it("compose(f, g, h)(x, y) == f(g(h(x, y)))", function ()
local f = function(x, y) return x + 1, y + 1 end
local g = function(x, y) return x + 2, y + 2 end
local h = function(x, y) return x + 3, y + 3 end
local ax, ay = func.compose(f, g, h)(1, 2)
local bx, by = f(g(h(1, 2)))
assert.equals(ax, bx)
assert.equals(ay, by)
end)

end)

end)

0 comments on commit 7e67bcb

Please sign in to comment.