General purpose function objects.
Variables | |
constexpr auto | boost::hana::always |
Return a constant function returning x regardless of the argument(s) it is invoked with. More... | |
constexpr auto | boost::hana::apply |
Invokes a Callable with the given arguments. More... | |
template<std::size_t n> | |
constexpr auto | boost::hana::arg |
Return the n th passed argument. More... | |
constexpr auto | boost::hana::capture |
Create a function capturing the given variables. More... | |
constexpr auto | boost::hana::compose |
Return the composition of two functions or more. More... | |
template<std::size_t n> | |
constexpr auto | boost::hana::curry |
Curry a function up to the given number of arguments. More... | |
constexpr auto | boost::hana::demux |
Invoke a function with the results of invoking other functions on its arguments. More... | |
constexpr auto | boost::hana::fix |
Return a function computing the fixed point of a function. More... | |
constexpr auto | boost::hana::flip |
Invoke a function with its two first arguments reversed. More... | |
constexpr auto | boost::hana::id |
The identity function – returns its argument unchanged. More... | |
constexpr auto | boost::hana::infix |
Return an equivalent function that can also be applied in infix notation. More... | |
template<std::size_t n> | |
constexpr auto | boost::hana::iterate |
Applies another function n times to its argument. More... | |
constexpr auto | boost::hana::lockstep |
Invoke a function with the result of invoking other functions on its arguments, in lockstep. More... | |
constexpr auto | boost::hana::on |
Invoke a function with the result of invoking another function on each argument. More... | |
constexpr auto | boost::hana::overload |
Pick one of several functions to call based on overload resolution. More... | |
constexpr auto | boost::hana::overload_linearly |
Call the first function that produces a valid call expression. More... | |
constexpr auto | boost::hana::partial |
Partially apply a function to some arguments. More... | |
constexpr unspecified | boost::hana::_ {} |
Create simple functions representing C++ operators inline. More... | |
constexpr auto | boost::hana::reverse_partial |
Partially apply a function to some arguments. More... | |
constexpr auto boost::hana::always |
#include <boost/hana/functional/always.hpp>
Return a constant function returning x
regardless of the argument(s) it is invoked with.
Specifically, always(x)
is a function such that
for any y...
. A copy of x
is made and it is owned by the always(x)
function. When always(x)
is called, it will return a reference to the x
it owns. This reference is valid as long as always(x)
is in scope.
constexpr auto boost::hana::apply |
#include <boost/hana/functional/apply.hpp>
Invokes a Callable with the given arguments.
This is equivalent to std::invoke that will be added in C++17. However, apply
is a function object instead of a function, which makes it possible to pass it to higher-order algorithms.
f | A Callable to be invoked with the given arguments. |
x... | The arguments to call f with. The number of x... must match the arity of f . |
Referenced by boost::hana::literals::operator""_c(), and boost::hana::literals::operator""_s().
constexpr auto boost::hana::arg |
#include <boost/hana/functional/arg.hpp>
Return the n
th passed argument.
Specifically, arg<n>(x1, ..., xn, ..., xm)
is equivalent to xn
. Note that indexing starts at 1, so arg<1>
returns the 1st argument, arg<2>
the 2nd and so on. Using arg<0>
is an error. Passing less than n
arguments to arg<n>
is also an error.
n | An unsigned integer representing the argument to return. n must be positive (meaning nonzero). |
x1,...,xm | A variadic pack of arguments from which the n th one is returned. |
n
be dynamic?We could have chosen arg
to be used like arg(n)(x...)
instead of arg<n>(x...)
. Provided all the arguments were of the same type, it would then be possible for n
to only be known at runtime. However, we would then lose the ability to assert the in-boundedness of n
statically.
n
being a non-type template parameterI claim that the only interesting use case is with a compile-time n
, which means that the usage would become arg(int_<n>)(x...)
, which is more cumbersome to write than arg<n>(x...)
. This is open for discussion.
constexpr auto boost::hana::capture |
#include <boost/hana/functional/capture.hpp>
Create a function capturing the given variables.
Given 0 or more variables, capture
creates a closure that can be used to partially apply a function. This is very similar to partial
, except that capture
allows the partially applied function to be specified later. Specifically, capture(vars...)
is a function object taking a function f
and returning f
partially applied to vars...
. In other words,
f
must match the total number of arguments passed to it, i.e. sizeof...(vars) + sizeof...(args)
.constexpr auto boost::hana::compose |
#include <boost/hana/functional/compose.hpp>
Return the composition of two functions or more.
compose
is defined inductively. When given more than two functions, compose(f, g, h...)
is equivalent to compose(f, compose(g, h...))
. When given two functions, compose(f, g)
is a function such that
If you need composition of the form f(g(x, y...))
, use demux
instead.
compose
is an associative operation; compose(f, compose(g, h))
is equivalent to compose(compose(f, g), h)
.constexpr auto boost::hana::curry |
#include <boost/hana/functional/curry.hpp>
Curry a function up to the given number of arguments.
Currying is a technique in which we consider a function taking multiple arguments (or, equivalently, a tuple of arguments), and turn it into a function which takes a single argument and returns a function to handle the remaining arguments. To help visualize, let's denote the type of a function f
which takes arguments of types X1, ..., Xn
and returns a R
as
Then, currying is the process of taking f
and turning it into an equivalent function (call it g
) of type
This gives us the following equivalence, where x1
, ..., xn
are objects of type X1
, ..., Xn
respectively:
Currying can be useful in several situations, especially when working with higher-order functions.
This curry
utility is an implementation of currying in C++. Specifically, curry<n>(f)
is a function such that
Note that the n
has to be specified explicitly because the existence of functions with variadic arguments in C++ make it impossible to know when currying should stop.
Unlike usual currying, this implementation also allows a curried function to be called with several arguments at a time. Hence, the following always holds
Of course, this requires k
to be less than or equal to n
; failure to satisfy this will trigger a static assertion. This syntax is supported because it makes curried functions usable where normal functions are expected.
Another "extension" is that curry<0>(f)
is supported: curry<0>(f)
is a nullary function; whereas the classical definition for currying seems to leave this case undefined, as nullary functions don't make much sense in purely functional languages.
constexpr auto boost::hana::demux |
#include <boost/hana/functional/demux.hpp>
Invoke a function with the results of invoking other functions on its arguments.
Specifically, demux(f)(g...)
is a function such that
Each g
is called with all the arguments, and then f
is called with the result of each g
. Hence, the arity of f
must match the number of g
s.
This is called demux
because of a vague similarity between this device and a demultiplexer in signal processing. demux
takes what can be seen as a continuation (f
), a bunch of functions to split a signal (g...
) and zero or more arguments representing the signal (x...
). Then, it calls the continuation with the result of splitting the signal with whatever functions where given.
demux
is associative. In other words (and noting demux(f, g) = demux(f)(g)
to ease the notation), it is true that demux(demux(f, g), h) == demux(f, demux(g, h))
.The signature of demux
is
\[ \mathtt{demux} : (B_1 \times \dotsb \times B_n \to C) \to ((A_1 \times \dotsb \times A_n \to B_1) \times \dotsb \times (A_1 \times \dotsb \times A_n \to B_n)) \to (A_1 \times \dotsb \times A_n \to C) \]
This can be rewritten more tersely as
\[ \mathtt{demux} : \left(\prod_{i=1}^n B_i \to C \right) \to \prod_{j=1}^n \left(\prod_{i=1}^n A_i \to B_j \right) \to \left(\prod_{i=1}^n A_i \to C \right) \]
The signature of compose
is
\[ \mathtt{compose} : (B \to C) \times (A \to B) \to (A \to C) \]
A valid observation is that this coincides exactly with the type of demux
when used with a single unary function. Actually, both functions are equivalent:
However, let's now consider the curried version of compose
, curry<2>(compose)
:
\[ \mathtt{curry_2(compose)} : (B \to C) \to ((A \to B) \to (A \to C)) \]
For the rest of this explanation, we'll just consider the curried version of compose
and so we'll use compose
instead of curry<2>(compose)
to lighten the notation. With currying, we can now consider compose
applied to itself:
\[ \mathtt{compose(compose, compose)} : (B \to C) \to (A_1 \to A_2 \to B) \to (A_1 \to A_2 \to C) \]
If we uncurry deeply the above expression, we obtain
\[ \mathtt{compose(compose, compose)} : (B \to C) \times (A_1 \times A_2 \to B) \to (A_1 \times A_2 \to C) \]
This signature is exactly the same as that of demux
when given a single binary function, and indeed they are equivalent definitions. We can also generalize this further by considering compose(compose(compose, compose), compose)
:
\[ \mathtt{compose(compose(compose, compose), compose)} : (B \to C) \to (A_1 \to A_2 \to A_3 \to B) \to (A_1 \to A_2 \to A_3 \to C) \]
which uncurries to
\[ \mathtt{compose(compose(compose, compose), compose)} : (B \to C) \times (A_1 \times A_2 \times A_3 \to B) \to (A_1 \times A_2 \times A_3 \to C) \]
This signature is exactly the same as that of demux
when given a single ternary function. Hence, for a single n-ary function g
, demux(f)(g)
is equivalent to the n-times composition of compose
with itself, applied to g
and f
:
More information on this insight can be seen here. Also, I'm not sure how this insight could be generalized to more than one function g
, or if that is even possible.
As explained above, demux
is associative when it is used with two functions only. Indeed, given functions f
, g
and h
with suitable signatures, we have
On the other hand, we have
and hence demux
is associative in the binary case.
constexpr auto boost::hana::fix |
#include <boost/hana/functional/fix.hpp>
Return a function computing the fixed point of a function.
fix
is an implementation of the Y-combinator, also called the fixed-point combinator. It encodes the idea of recursion, and in fact any recursive function can be written in terms of it.
Specifically, fix(f)
is a function such that
This definition allows f
to use its first argument as a continuation to call itself recursively. Indeed, if f
calls its first argument with y...
, it is equivalent to calling f(fix(f), y...)
per the above equation.
Most of the time, it is more convenient and efficient to define recursive functions without using a fixed-point combinator. However, there are some cases where fix
provides either more flexibility (e.g. the ability to change the callback inside f
) or makes it possible to write functions that couldn't be defined recursively otherwise.
f | A function called as f(self, x...) , where x... are the arguments in the fix(f)(x...) expression and self is fix(f) . |
constexpr auto boost::hana::flip |
#include <boost/hana/functional/flip.hpp>
Invoke a function with its two first arguments reversed.
Specifically, flip(f)
is a function such that
constexpr auto boost::hana::id |
#include <boost/hana/functional/id.hpp>
The identity function – returns its argument unchanged.
constexpr auto boost::hana::infix |
#include <boost/hana/functional/infix.hpp>
Return an equivalent function that can also be applied in infix notation.
Specifically, infix(f)
is an object such that:
Hence, the returned function can still be applied using the usual function call syntax, but it also gains the ability to be applied in infix notation. The infix syntax allows a great deal of expressiveness, especially when used in combination with some higher order algorithms. Since operator^
is left-associative, x ^infix(f)^ y
is actually parsed as (x ^infix(f))^ y
. However, for flexibility, the order in which both arguments are applied in infix notation does not matter. Hence, it is always the case that
However, note that applying more than one argument in infix notation to the same side of the operator will result in a compile-time assertion:
Additionally, a function created with infix
may be partially applied in infix notation. Specifically,
^
operator was chosen because it is left-associative and has a low enough priority so that most expressions will render the expected behavior.f | The function which gains the ability to be applied in infix notation. The function must be at least binary; a compile-time error will be triggered otherwise. |
constexpr auto boost::hana::iterate |
#include <boost/hana/functional/iterate.hpp>
Applies another function n
times to its argument.
Given a function f
and an argument x
, iterate<n>(f, x)
returns the result of applying f
n
times to its argument. In other words,
If n == 0
, iterate<n>(f, x)
returns the x
argument unchanged and f
is never applied. It is important to note that the function passed to iterate<n>
must be a unary function. Indeed, since f
will be called with the result of the previous f
application, it may only take a single argument.
In addition to what's documented above, iterate
can also be partially applied to the function argument out-of-the-box. In other words, iterate<n>(f)
is a function object applying f
n
times to the argument it is called with, which means that
This is provided for convenience, and it turns out to be especially useful in conjunction with higher-order algorithms.
Given a function \( f : T \to T \) and x
and argument of data type T
, the signature is \( \mathtt{iterate_n} : (T \to T) \times T \to T \)
n | An unsigned integer representing the number of times that f should be applied to its argument. |
f | A function to apply n times to its argument. |
x | The initial value to call f with. |
constexpr auto boost::hana::lockstep |
#include <boost/hana/functional/lockstep.hpp>
Invoke a function with the result of invoking other functions on its arguments, in lockstep.
Specifically, lockstep(f)(g1, ..., gN)
is a function such that
Since each g
is invoked on its corresponding argument in lockstep, the number of arguments must match the number of g
s.
constexpr auto boost::hana::on |
#include <boost/hana/functional/on.hpp>
Invoke a function with the result of invoking another function on each argument.
Specifically, on(f, g)
is a function such that
For convenience, on
also supports infix application as provided by infix
.
on
is associative, i.e. on(f, on(g, h))
is equivalent to on(on(f, g), h)
.constexpr auto boost::hana::overload |
#include <boost/hana/functional/overload.hpp>
Pick one of several functions to call based on overload resolution.
Specifically, overload(f1, f2, ..., fn)
is a function object such that
where fk
is the function of f1, ..., fn
that would be called if overload resolution was performed amongst that set of functions only. If more than one function fk
would be picked by overload resolution, then the call is ambiguous.
constexpr auto boost::hana::overload_linearly |
#include <boost/hana/functional/overload_linearly.hpp>
Call the first function that produces a valid call expression.
Given functions f1, ..., fn
, overload_linearly(f1, ..., fn)
is a new function that calls the first fk
producing a valid call expression with the given arguments. Specifically,
where fk
is the first function such that fk(args...)
is a valid expression.
constexpr auto boost::hana::partial |
#include <boost/hana/functional/partial.hpp>
Partially apply a function to some arguments.
Given a function f
and some arguments, partial
returns a new function corresponding to the partially applied function f
. This allows providing some arguments to a function and letting the rest of the arguments be provided later. Specifically, partial(f, x...)
is a function such that
f
must match the total number of arguments passed to it, i.e. sizeof...(x) + sizeof...(y)
.constexpr unspecified boost::hana::_ {} |
#include <boost/hana/functional/placeholder.hpp>
Create simple functions representing C++ operators inline.
Specifically, _
is an object used as a placeholder to build function objects representing calls to C++ operators. It works by overloading the operators between _
and any object so that they return a function object which actually calls the corresponding operator on its argument(s). Hence, for any supported operator @
:
Operators may also be partially applied to one argument inline:
When invoked with more arguments than required, functions created with _
will discard the superfluous instead of triggering an error:
This makes functions created with _
easier to use in higher-order algorithms, which sometime provide more information than necessary to their callbacks.
+
, binary -
, /
, *
, %
, unary +
, unary -
~
, &
, |
, ^
, <<
, >>
==
, !=
, <
, <=
, >
, >=
||
, &&
, !
*
(dereference), []
(array subscript)()
(function call)More complex functionality like the ability to compose placeholders into larger function objects inline are not supported. This is on purpose; you should either use C++14 generic lambdas or a library like Boost.Phoenix if you need bigger guns. The goal here is to save you a couple of characters in simple situations.
constexpr auto boost::hana::reverse_partial |
#include <boost/hana/functional/reverse_partial.hpp>
Partially apply a function to some arguments.
Given a function f
and some arguments, reverse_partial
returns a new function corresponding to f
whose last arguments are partially applied. Specifically, reverse_partial(f, x...)
is a function such that
f
must match the total number of arguments passed to it, i.e. sizeof...(x) + sizeof...(y)
.