Boost logo

Boost :

Subject: [boost] [hana]Either generalization & missing variant
From: Larry Evans (cppljevans_at_[hidden])
Date: 2015-06-08 11:12:40


The page:

  http://ldionne.com/hana/structboost_1_1hana_1_1Either.html

contains:

  An Either contains either a left value or a right value,
  both of which may have different data types. An Either
  containing a left value a is represented as left(a), and
  an Either containing a right value b is represented as
  right(b).

which makes anyone familiar with boost::variant to think
that hana's Either is simply a binary boost::variant, and

  left(a) ~=~ variant<A,B>(a)
  right(b) ~=~ variant<A,B>(b)

where ~=~ means some sort of similarity. However, since
the left and right functions only have 1 argument and no
template arguments, they can't produce something like
variant<A,B> where the left and right types are known.
IOW, it seems that left and right are just wrapper's around
the types. Looking at the code, the wrappers, _left and
_right are defined here:

https://github.com/ldionne/hana/blob/master/include/boost/hana/either.hpp#L37

https://github.com/ldionne/hana/blob/master/include/boost/hana/either.hpp#L79

But why should Either be limited just to _left and _right
wrappers. Why not provide wrapper's tagged by some
enumerable? For example, something like this:

      template
      < typename X
      , typename Enumerable=unsigned
      , Enumerable tag=Tag()
>
    struct _tagged //instead of _left and _right
    : operators::adl
    {
        X value;
    .
    .
    .
        template <typename... F>
        constexpr decltype(auto) go(F...&& f) const&
        { return (hana::arg<unsigned(tag)>(f...))(value);
        }
    .
    .
    .
    };

This would be more general than the binary Either. In
addition, _tagged could be used elsewhere. For example, it
could be used in a multiple inheritance implementation of
tuple. _tagged is already present in a more general form,
in fusion:

http://www.boost.org/doc/libs/1_39_0/libs/fusion/doc/html/fusion/support/pair.html

where:

  _tagged<X,0> ~=~ fusion::pair<int_<0>,X>

The obvious advantage of Either is that it doesn't require
memory use equal to the max of the components when the
component with the minimum size is used. IOW, left(a) only
requires sizeof(A) and right(b) only requires sizeof(B).

OTOH, Either, or the generalization described above, can't
be used where a true variant is needed, for example, in
spirit's attributes for the alternative parser. And this
brings up another question. Although hana has a tuple, it
doesn't have a variant. Is there any reason for excluding
variant from hana?

-regards,
Larry


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk