https://github.com/ezerfernandes/funkmoon
Functional Tools for Lua
https://github.com/ezerfernandes/funkmoon
Last synced: 4 months ago
JSON representation
Functional Tools for Lua
- Host: GitHub
- URL: https://github.com/ezerfernandes/funkmoon
- Owner: ezerfernandes
- License: mit
- Created: 2016-01-05T02:38:33.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2024-08-31T11:31:30.000Z (11 months ago)
- Last Synced: 2024-10-31T19:37:42.317Z (9 months ago)
- Language: Lua
- Size: 27.3 KB
- Stars: 11
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# funkmoon - Functional Tools for Lua
`funkmoon` is a collection of functional programming utilities for Lua, inspired by languages like Scala. It provides a set of tools to work with tables in a functional style, supporting method chaining to simulate a pipeline-like structure.
## Installation
To use `funkmoon`, simply require it in your Lua scripts:
```lua
local funkmoon = require "funkmoon"
```## Usage
### As standalone functions
You can use funkmoon functions directly, as shown in the following example:
```lua
local list = {1, 2, -3, 4}-- Returns only even numbers.
local even = funkmoon.filter(list, function(n) return n % 2 == 0 end)
```### As methods (pipeline style)
This is the preferred way if you want to use several functions as a pipeline, with [method chaining](https://en.wikipedia.org/wiki/Method_chaining), simulating what you can do in functional languages like Scala, for example.
```lua
-- Returns the sum of the squares of even numbers.
local list = funkmoon.FunctionalTable({1, 2, -3, 4, 9, 8})local sumOfSquaresEvenNumbers = list
:filter(function(n) return n % 2 == 0 end)
:map(function(n) return n*n end)
:reduce(function(a, b) return a + b end)
```FunctionalTable adds a metatable that allows to call the functions as methods and use this development style.
## API Reference
`map(list, fn)`
Builds a new table by applying `fn` to each element of `list`.
```lua
local list = {3, 5, 8}
local squares = funkmoon.map(list, function(n) return n*n end)
-- Result: {9, 25, 64}
````flatMap(list, fn)`
Builds a new table by applying `fn` to each element of `list` and flattening the result.
```lua
local values = {0, 5, 10}
local mapped = funkmoon.flatMap(values, function(x) return {x-1, x, x+1} end)
-- Result: {-1, 0, 1, 4, 5, 6, 9, 10, 11}
````filter(list, predicate)`
Selects all elements of `list` which satisfy `predicate`.
```lua
local list = {1, 4, 6, 3, 7}
local oddNumbers = funkmoon.filter(list, function(n) return n % 2 == 1 end)
-- Result: {1, 3, 7}
````filterNot(list, predicate)`
Selects all elements of `list` which don't satisfy `predicate`.
```lua
local values = {1, 2, 3, 4}
local filtered = funkmoon.filterNot(values, function(n) return n % 2 == 0 end)
-- Result: {2, 4}
````foldLeft`
Applies a binary function (fn) to startValue and all elements of `list`, going left to right.
```lua
local list = {1, 2, 3, 4, 5}
local sum = funkmoon.foldLeft(list, 0)(function(acc, n) return acc + n end)
-- Result: 16
````foldRight`
Applies a binary function (fn) to startValue and all elements of 'list', going right to left.
```lua
local list = {1, 2, 3, 4}-- Concatenate numbers from right to left
local result = funkmoon.foldRight(list, "")(function(acc, n)
return acc .. tostring(n)
end)-- result: "4321"
````reduce`
Reduces the elements of 'list' using the binary operator 'fn'.
```lua
local values = {1, 2, 3, 4, 5}
local result = reduce(values, function(acc, n) return acc * n end)
-- result: 120
````find`
Finds the first element of 'list' satisfying a predicate, if any.
```lua
local values = {1, 5, 8, 3, 9, 4, 6}
local result = funkmoon.find(values, function(n) return n % 2 == 0 end)
-- result: { [3] = 8 }
````arrayPart`
Returns the array-like part of list (1 to n).
```lua
local mixedTable = { foo = 3, 2 = "hello", bar = "world", 1 = 42 }
local result = funkmoon.arrayPart(mixedTable)
-- result: {42, "hello"}
````partition`
Partitions 'list' in two tables according to 'predicate'.
```lua
local evens, odds = partition({1, 3, 2, 7, 4, 9}, function(n) return n % 2 == 0 end)
-- evens = {2, 4}; odds = {1, 3, 7, 9}
````takeWhile`
Takes longest prefix of elements of 'list' that satisfy 'predicate'.
```lua
local testList = {1, 2, 3, 4, 0, 2, 5}
local result = funkmoon.takeWhile(testList, function(n) return n < 4 end)
-- result: {1, 2, 3}
````dropWhile`
Drops longest prefix of elements of 'list' that satisfy 'predicate'.
```lua
local testList = {1, 2, 3, 4, 0, 2, 5}
local result = funkmoon.takeWhile(testList, function(n) return n < 4 end)
-- result: {4, 0, 2, 5}
````any`
Tests whether 'predicate' holds for some of the elements of 'list'.
```lua
local values = {1, 2, 7, 0}
local result = funkmoon.any(values, function(n) return n > 5 end)
-- result: true
````all`
Tests whether 'predicate' holds for all elements of 'list'.
```lua
local values = {1, 2, 7, 0}
local result = funkmoon.all(values, function(n) return n > 5 end)
-- result: false
````corresponds`
Tests whether every element of 'list' relates to the corresponding element of 'otherList' by satisfying a test predicate.
```lua
local aList = {1, 2, 3}
local anotherList = {2, 4, 6}
local result = funkmoon.corresponds(aList, anotherList)(function(a, b) return 2*a == b end)
-- result: true
````fill`
Creates a table with 'value' repeated 'n' times.
```lua
local result = funkmoon.fill(3)("hello!")
-- result: {"hello!", "hello!", "hello!"}
````distinct`
Builds a new list from this 'list' with no duplicate elements.
```lua
list = {1, 2, 2, 3, 1, 2, 5}
result = funkmoon.distinct(list)
-- result: {1, 2, 3, 5}
````groupBy`
Gets the elements and keys from 'list' and partitions them by the result of the function fn(key, element), returning a new table where fn(key, element) are the keys and the values are tables with the keys and values.
```lua
list = {1, 2, 3, 4}
grouped = funkmoon.groupBy(list, function(_, n) return n % 2 == 0 end)
-- grouped: {[true] = {{2, 2}, {4, 4}}, [false] = {{1, 1}, {3, 3}}}
````partial`
Returns a new function with partial application of the given arguments.
```lua
local function sum(a, b)
return a + b
endlocal increment = funkmoon.partial(sum, 1)
local result = increment(4)
-- result: 5
````apply`
Applies a function using list as an argument
```lua
values = {0, 9, -4}-- sum the three values
result = funkmoon.apply(values, function(a, b, c) return a+b+c end)
````isEmpty`
Test whether `list` is empty.
```lua
result = funkmoon.isEmpty({}) -- result: true
result = funkmoon.isEmpty({2, 3}) -- result: false
````max`
Returns a functional table with the greatest element of a table.
```lua
-- result: 9
local result = funkmoon.max({-3, 2, 9, 4})-- square of the greatest number
local result = funkmoon.FunctionalTable(values)
:max()
:apply(function (n) return n * n end)
````min`
Returns a functional table with the smallest element of a table.
```lua
-- result: -3
local result = funkmoon.min({-3, 2, 9, 4})-- checks if the smallest number is positive.
local result = funkmoon.FunctionalTable(values)
:min()
:all(function(n) return n > 0 end)
````ifEmpty`
Returns a functional table with the smallest element of a table.
```lua
-- result = 5
local result = funkmoon.FunctionalTable({ 1, 2, 3, 4 })
:filter(function(n) return n > 4 end)
:ifEmpty(5)
````zip`
Returns a new table formed from 'list' and 'otherList' by combining corresponding elements in pairs.
```lua
local x = {1, 2}
local y = {"blue", "green"}
local result = funkmoon.zip(x, y)
-- result: { {1, "blue"}, {2, "green"} }
````unzip`
Converts this 'list' of pairs into two tables of the first and second half of each pair.
```lua
local list = { {5, 'a'}, {8, 'b'} }
local numbers, letters = funkmoon.unzip(list)
-- numbers = {5, 8}; letters = {'a', 'b'}
````slice`
Returns a new table with the elements of 'list' from 'from' to 'to'.
```lua
local list = {5, 21, 8, 2, 9, 11}
local result = funkmoon.slice(list, 3, 5)
-- result: {8, 2, 9}
````reverse`
Returns a new table with the elements of 'list' reversed.
```lua
local list = {5, 2, 4, 1}
local result = funkmoon.reverse(list)
-- result: {1, 4, 2, 5}
````range`
```lua
local result = funkmoon.range(1, 5, 2)
-- result: {1, 3, 5}
````irange`
```lua
for i in funkmoon.irange(1, 4, 2) do
print(i)
end
--[[
printed:
1
3
]]
````fill` and `ifill`
Fills a list with repeated values.
```lua
local filledList = funkmoon.fill(5)("hello")
-- filledList: {"hello", "hello", "hello", "hello", "hello"}```
`stream` and `istream`
Creates an iterator that generates values or repeats a function call.
```lua
local stream = funkmoon.stream(function(x) return x + 1 end, 0)
local result = {}
for i = 1, 5 do
result[i] = stream()
end
-- result: {1, 2, 3, 4, 5}local count = 0
for _ in funkmoon.itimes(3, function() count = count + 1 end) do end
-- count: 3
````itimes`
Creates an iterator that calls a function a specified number of times.
```lua
local count = 0
for _ in funkmoon.itimes(3, function()
count = count + 1
print("This is call number " .. count)
end) do
-- The loop will run 3 times
end-- Output:
-- This is call number 1
-- This is call number 2
-- This is call number 3
```## Contributing
Contributions are welcome! Please fork the repository and submit a pull request.
## License
This project is licensed under the MIT License.