|
||||
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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |