Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:58

0001 /*!
0002 @file
0003 Forward declares `boost::hana::Foldable`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_FWD_CONCEPT_FOLDABLE_HPP
0011 #define BOOST_HANA_FWD_CONCEPT_FOLDABLE_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 
0015 
0016 namespace boost { namespace hana {
0017     //! @ingroup group-concepts
0018     //! @defgroup group-Foldable Foldable
0019     //! The `Foldable` concept represents data structures that can be reduced
0020     //! to a single value.
0021     //!
0022     //! Generally speaking, folding refers to the concept of summarizing a
0023     //! complex structure as a single value, by successively applying a
0024     //! binary operation which reduces two elements of the structure to a
0025     //! single value. Folds come in many flavors; left folds, right folds,
0026     //! folds with and without an initial reduction state, and their monadic
0027     //! variants. This concept is able to express all of these fold variants.
0028     //!
0029     //! Another way of seeing `Foldable` is as data structures supporting
0030     //! internal iteration with the ability to accumulate a result. By
0031     //! internal iteration, we mean that the _loop control_ is in the hand
0032     //! of the structure, not the caller. Hence, it is the structure who
0033     //! decides when the iteration stops, which is normally when the whole
0034     //! structure has been consumed. Since C++ is an eager language, this
0035     //! requires `Foldable` structures to be finite, or otherwise one would
0036     //! need to loop indefinitely to consume the whole structure.
0037     //!
0038     //! @note
0039     //! While the fact that `Foldable` only works for finite structures may
0040     //! seem overly restrictive in comparison to the Haskell definition of
0041     //! `Foldable`, a finer grained separation of the concepts should
0042     //! mitigate the issue. For iterating over possibly infinite data
0043     //! structures, see the `Iterable` concept. For searching a possibly
0044     //! infinite data structure, see the `Searchable` concept.
0045     //!
0046     //!
0047     //! Minimal complete definition
0048     //! ---------------------------
0049     //! `fold_left` or `unpack`
0050     //!
0051     //! However, please note that a minimal complete definition provided
0052     //! through `unpack` will be much more compile-time efficient than one
0053     //! provided through `fold_left`.
0054     //!
0055     //!
0056     //! Concrete models
0057     //! ---------------
0058     //! `hana::map`, `hana::optional`, `hana::pair`, `hana::set`,
0059     //! `hana::range`, `hana::tuple`
0060     //!
0061     //!
0062     //! @anchor Foldable-lin
0063     //! The linearization of a `Foldable`
0064     //! ---------------------------------
0065     //! Intuitively, for a `Foldable` structure `xs`, the _linearization_ of
0066     //! `xs` is the sequence of all the elements in `xs` as if they had been
0067     //! put in a list:
0068     //! @code
0069     //!     linearization(xs) = [x1, x2, ..., xn]
0070     //! @endcode
0071     //!
0072     //! Note that it is always possible to produce such a linearization
0073     //! for a finite `Foldable` by setting
0074     //! @code
0075     //!     linearization(xs) = fold_left(xs, [], flip(prepend))
0076     //! @endcode
0077     //! for an appropriate definition of `[]` and `prepend`. The notion of
0078     //! linearization is useful for expressing various properties of
0079     //! `Foldable` structures, and is used across the documentation. Also
0080     //! note that `Iterable`s define an [extended version](@ref Iterable-lin)
0081     //! of this allowing for infinite structures.
0082     //!
0083     //!
0084     //! Compile-time Foldables
0085     //! ----------------------
0086     //! A compile-time `Foldable` is a `Foldable` whose total length is known
0087     //! at compile-time. In other words, it is a `Foldable` whose `length`
0088     //! method returns a `Constant` of an unsigned integral type. When
0089     //! folding a compile-time `Foldable`, the folding can be unrolled,
0090     //! because the final number of steps of the algorithm is known at
0091     //! compile-time.
0092     //!
0093     //! Additionally, the `unpack` method is only available to compile-time
0094     //! `Foldable`s. This is because the return _type_ of `unpack` depends
0095     //! on the number of objects in the structure. Being able to resolve
0096     //! `unpack`'s return type at compile-time hence requires the length of
0097     //! the structure to be known at compile-time too.
0098     //!
0099     //! __In the current version of the library, only compile-time `Foldable`s
0100     //! are supported.__ While it would be possible in theory to support
0101     //! runtime `Foldable`s too, doing so efficiently requires more research.
0102     //!
0103     //!
0104     //! Provided conversion to `Sequence`s
0105     //! ----------------------------------
0106     //! Given a tag `S` which is a `Sequence`, an object whose tag is a model
0107     //! of the `Foldable` concept can be converted to an object of tag `S`.
0108     //! In other words, a `Foldable` can be converted to a `Sequence` `S`, by
0109     //! simply taking the linearization of the `Foldable` and creating the
0110     //! sequence with that. More specifically, given a `Foldable` `xs` with a
0111     //! linearization of `[x1, ..., xn]` and a `Sequence` tag `S`, `to<S>(xs)`
0112     //! is equivalent to `make<S>(x1, ..., xn)`.
0113     //! @include example/foldable/to.cpp
0114     //!
0115     //!
0116     //! Free model for builtin arrays
0117     //! -----------------------------
0118     //! Builtin arrays whose size is known can be folded as-if they were
0119     //! homogeneous tuples. However, note that builtin arrays can't be
0120     //! made more than `Foldable` (e.g. `Iterable`) because they can't
0121     //! be empty and they also can't be returned from functions.
0122     //!
0123     //!
0124     //! @anchor monadic-folds
0125     //! Primer on monadic folds
0126     //! -----------------------
0127     //! A monadic fold is a fold in which subsequent calls to the binary
0128     //! function are chained with the monadic `chain` operator of the
0129     //! corresponding Monad. This allows a structure to be folded in a
0130     //! custom monadic context. For example, performing a monadic fold with
0131     //! the `hana::optional` monad would require the binary function to return
0132     //! the result as a `hana::optional`, and the fold would abort and return
0133     //! `nothing` whenever one of the accumulation step would fail (i.e.
0134     //! return `nothing`). If, however, all the reduction steps succeed,
0135     //! then `just` the result would be returned. Different monads will of
0136     //! course result in different effects.
0137     template <typename T>
0138     struct Foldable;
0139 }} // end namespace boost::hana
0140 
0141 #endif // !BOOST_HANA_FWD_CONCEPT_FOLDABLE_HPP