This module contains several functions and higher order functions or
decorators, mostly useful with HOF like map, reduce or in generators.
Indeed, using HOF often require some classical functions like constants one, identity, or classical operators.
Most of the times, these functions needs to be unary ones, i.e. have only one parameter. This module contains, among others, functions helping in the arity conversion of such functions:
curry that makes a function automatically partializable,uncurry that is the reverse of curry,unary and spreader that convert a polyadic function into a unary
function taking an array or a tuple of values instead of several
values,varargs which is the reverse of unaryMost of the binary operator functions defined here are curried. To ease
partialization, the non commutative operators have a reversed version, with
arguments swapped.
For example, using the reverse division operator rdiv with
map
[2, 4, 8]: map(rdiv(2)) == [1, 2, 4]
The identity function id, the constant function
const, together with composition (FunctionReference::andThen,
pipe, compose) and io can be
used to create monad-like processing chains.
false constant function.
null constant function.
true constant function.
Polymorphic addition and concatenation.
Adds value to element.
The behavior depends on the type of element:
+;add and returning the collection;Appendable or a StringBuilder, equivalent to invoking append and
returning the collection.This function is swapped and curried. For instance:
add("b", "a") == "ab"
list[1, 2, 3]: map(add(3)) == list[4, 5, 6]
add("a", StringBuilder()): toString() == "a"
let f = add(42): andThen(add(1337)): andThen(add(69))
f(list[]) == list[42, 1337, 69]
f(0) == 1448
f(StringBuilder()): toString() == "42133769"
value: the value to addelement: the element to add the value toSee also addTo
Not swapped version of add
Curried boolean and.
This implementation is lazy.
The arguments can be boolean expressions or predicate functions. If called with predicate functions, returns a new predicate function.
`and(a, b) == (a and b)
`and(gt(10), ^even) == |x| -> a > 10 and x % 2 == 0
    Function composition.
compose(f1, f2, f3)(x) == f1(f2(f3(x)))
This is similar to pipe, but with functions order
reversed (B combinator).
Conditional application combinator.
Equivalent to using the match construct:
let r = cond(predicate, ifTrue, ifFalse, x)
# equivalent to
let r = match {
  when predicate(x) then ifTrue(x)
  otherwise ifFalse(x)
}
Since this function is curried, it can be used as:
let f = cond(predicate, ifTrue, ifFalse)
# equivalent to
let f = |x| -> match {
  when predicate(x) then ifTrue(x)
  otherwise ifFalse(x)
}
predicate a boolean functionifTrue the unary function to apply if predicate holdsifFalse the unary function to apply otherwiseThe constant function.
Returns a new variadic functions that always returns val, ignoring its
arguments. For example:
let theAnswerTo = const(42)
theAnswerTo() == 42
theAnswerTo(1, 2, 3) == 42
theAnswerTo("Life, the Universe and Everything") == 42
One interesting use case is to write "pipe" like composition, with the argument on the left:
const(42): andThen(f): andThen(g): andThen(h)() == h(g(f(42)))
This is also the K combinator.
Swapped curried containment test.
Checks if collection contains value.
The collection object can be anything with a contains method.
For instance:
let predicate = contains(42)
if (predicate(collection)) {
  ...
}
value: the value to test for containmentcollection: any object having a contains methodFunction to curryfy a function, i.e. transforms a polyadic function into a sequence of variadic functions. This allows for automatic partial application.
This is equivalent to applying invokeOrBind on each call.
E.g.
function f = |a, b, c| -> a + b + c
let g = curry(^f)
g(29)(10)(3) == f(29, 10, 3)
g(29, 10)(3) == 42
g(29)(10, 3) == 42
let g1 = g(29)
let g2 = g1(10)
let g3 = g(29, 10)
g(29, 10, 3) == 42
g1(10, 3) == 42
g1(10)(3) == 42
g2(3) == 42
g3(3) == 42
This is particularly useful to allow composing polyadic functions. For
instance, with the previous g:
let h = g(2, 20): andThen(g("The answer", " is "))
h(20) == "The answer is 42"
If the function is variadic, only the fixed parameters can be partialized. For instance, given:
@!curry
function f = |a, b, c...| -> ...
...
let g = f(1, 2)
then g is a variadic function that can't be called partially. All the
following calls are valids:
g()
g(1)
g(1, 2, 3)
but
g(1)(2)
is not.
This function can also be used as a decorator.
f the function to curryf that can be partializedSee also uncurry
Checks if the value is even.
See also odd
First element of a list, tuple, vector, array.
fst([a, b]) == a
t: any object with a get method and at least one element.IndexOutOfBoundsException if the object is empty.Curried swapped greater than or equal.
ge(a, b) == (b >= a)
Note: this function is swapped to make curried version more readable.
Curried indexing.
getitem(obj, i) == obj: get(i)
Throws an IndexOutOfBoundsException (for a collection-like object) or returns
null (for a map-like object) if the index is not present.
obj: any object having a get methodi: the index to getCurried swapped greater than.
gt(a, b) == b > a
Note: this function is swapped to make curried version more readable.
The identity function.
Returns it's argument unchanged. This can be useful with higher order functions (I combinator).
Reversed curried function application.
Apply the given function to the given value.
invokeWith("a", "b", "c")(f) == f("a", "b", "c")
For instance, given a list of functions:
list[f, g, h]: map(invokeWith(42)) == list[f(42), g(42), h(42)]
It can also be used to promote a value in continuation passing style.
args the values on which apply the functionTransform a function with side effects (generally IO operations, thus the name) into a function applying the side effect and returning its argument.
The given function can have no parameters, or accept an argument.
This can be used to insert such a function into a composition chain:
f1: andThen(io({println("hello")})): andThen(f2)
f1: andThen(io(|x|{println("got " + x)})): andThen(f2)
block a function with side effectsCurried identity comparison
`is(ref, obj) == obj is ref
Parameters are swapped to ease partialization, as in:
lst: filter(is(ref))
    Emptiness test.
Checks if the collection-like argument is empty.
Curried difference comparison
`isnt(ref, obj) = obj isnt ref
Like is, this is more useful partialized. For instance:
lst: filter(`isnt(null))
    Curried swapped less than or equal.
le(a, b) == (a <= b)
Note: this function is swapped to make curried version more readable.
Curried swapped less than.
lt(a, b) == b < a
lt(42) == |x| -> x < 42
Note: this function is swapped to make curried version more readable: lt(42)
is a predicate testing if its argument is "less than 42".
Opposite (negative value).
neg(x) == -x
Same as mul(-1)
Polymorphic negation function.
E.g.
list[true, false, false]: map(^not) == list[false, true, true]
let even = |a| -> (a % 2) == 0
let odd = `not(even)
    Checks if the value is odd.
See also even
Curried type checking
`oftype(type, obj) = obj oftype type
Partialized version can be used as a predicate, for instance in filter:
alist: filter(`oftype(String.class))
    Curried boolean or.
`or(a, b) == (a or b)
This implementation is lazy.
The arguments can be boolean expressions or predicate functions. If called with predicate functions, returns a new predicate function.
Null value substitution
`orIfNull(0, 3) == 3
`orIfNull(0, null) == 0
This function can be useful, for example, to replace null values in a list with
a map:
list[1, 2, null, 3]:map(`orIfNull(0)) == list[1, 2, 0, 3]
    Function chaining.
This is similar to Unix pipe:
pipe(f1, f2, f3)(x) == f3(f2(f1(x))))
i.e. apply f1 to x, then pass it to f2, and then f3.
This is the same as f1: andThen(f2): andThen(f3)(x)
You can insert a side-effect only function in the chain using io:
pipe(f1, io({println("hello")}), f2)(42)
is equivalent to:
let tmp = f1(x)
println("hello")
f2(tmp)
This is similar to compose, but with functions order
reversed.
Example:
let cmd = pipe(mul(2), add(4), ^toString, addTo("val: "))
cmd(19) == "val: 42"
let other = pipe(^intValue, add(4), mul(2))
other("17") == 42
If no function is given, returns id
For a similar construct that deal with errors, see for instance the
gololang.Errors module
Fixed-point combinator.
This is an abstraction of recursion.
f the function that will recurfCurried indexed assignment
setitem(obj, i, v) == obj: set(i, v)
obj: any object having a set methodi: the index to setv: the value to setSecond element of a list, tuple, vector, array.
snd([a, b]) == b
t: any object with a get method and at least two elements.IndexOutOfBoundsException if the object has less than 2 elements.Convers a polyadic function into an unary function.
Similar to unary but using spread instead of invoke.
This function can also be used as a decorator.
See also varargs
Converts its argument to a String.
Polymorphic swapping.
This function dispatches on swapArgs,
swapCurry or swapCouple according
to its parameter.
Note that we have the property that given a binary function f and a
couple c
unary(f)(swap(c)) == unary(swap(f))(c)
When applied to functions, equivalent to the C combinator.
Change the signature of the given binary function by swapping its arguments, such that:
swapArgs(f)(b, a) == f(a, b)
Warning: when using this function with one previously wrapped in
curry or uncurry, the resulting function can't be
automatically partialized any more.
Swap the values of a couple.
The couple can be a tuple, a vector, a list or an array as long as its size is 2. The return value as the same type.
For example:
swap([a, b]) == [b, a]
    Change the signature of the given curried binary function by swapping its arguments, such that:
swapCurry(f)(a)(b) = f(b)(a)
    Convers a polyadic function into an unary function. E.g.
let f = |a, b, c| -> a + b + c
let g = unary(f)
g([1, 2, 3]) == 6
If the function already takes zero or one argument, it is returned unchanged.
This can be useful in HOF, for example to map a binary function on a list of
couple:
let f = |a, b| -> ...
list[["a", 1], ["b", 2], ["c", 3]]: map(unary(f))
results in list[f("a", 1), f("b", 2), f("c", 3)]
The resulting unary function will accept any object having a toArray method
(array, tuple, collection, map entry, struct...)
Thus, unary(func)(arg) is equivalent to func: invoke(arg: toArray())
This function can also be used as a decorator.
Reverse of curry.
Take a curried function (e.g. |a| -> |b| -> a + b) and return a polyadic
function (e.g. |a, b| -> a + b).
It is actually a variadic function calling the curried one in sequence.
The two functions defined by
let f = curry(|a, b, c| -> a + b + c)
let g = uncurry(|a| -> |b| -> |c| -> a + b + c)
have the same behavior.
This function can also be used as a decorator.
f the function to uncurryfSee also curry
Apply the given function until the predicate holds.
For instance:
let f = until(gt(10), mul(2))
f(15) == 15
f(2) == 16
f(9) == 18
    Convert an unary function taking an array into a variadic function.
This is the contrary of unary.
E.g.
let f = |t| -> t:get(0) + t:get(1) + t:get(2)
let g = varargs(f)
f([1, 2, 3]) == g(1, 2, 3)
This function can also be used as a decorator.