Larry Evans
[...]
What puzzled me was initially, was that left(a) and right(b) produced _left<A> and _right<B> and there was no indication that the result was of type either_t, where either_t is a variant like in boost::variant. Hence, I don't think the way hana implements Either, it can truly be a discriminated union because _left<A> has no information about what the other possible alternative values are in either_t.
That is true; in its current form, no actual type checking was done to ensure that only things of type A or B were put in the Either. That is also in line with the decision not to provide parameterized data types. You can find a discussion related to your question at [1]. If you're still puzzled after reading it, please let me know and I will clarify.
[...]
I'd say there are two reasons for this omission.
1. In the mathematical construction upon which Hana stands, sum types are exactly Either as currently implemented. An actual runtime variant can't be implemented (while staying in that mathematical universe). However, runtime variants might be a very useful addition to Hana, allowing one to have a compile-time computation depending on a runtime value to return a runtime variant instead of failing because the result can't be determined at compile-time, like it currently does. This brings us to the second point.
That's what I would have thought. IOW, the type returned by get depends on the *runtime* value of the discriminant (the value returned by variant
::which(). However, I think there have been some constexpr get's for variant structures, at least as for as I can tell from reading:
The difference is quite subtle, and it has to do with the problem of constexpr
stripping explained at [2]. Basically, Hana's Either was supposed to be able
to provide a `which()` returning a compile-time value, even if the Either
itself was only known at runtime. The only way to achieve this is to encode
the discriminant into the type of the Either object.
In contrast, Egg's variant can only guarantee that the discriminant will
be known at compile-time if everything in the variant is also known at
compile-time. That can be achieved by making the which() function constexpr
and making sure that the constexpr-ness of the contents of the variant is
preserved by the variant. However, initializing the variant with a
non-constexpr value will make it impossible to retrieve the discriminant
at compile-time.
The benefit of Hana's approach was that you could know the content of your
variant at compile-time, whatever those contents where, which makes it useful
for __static heterogeneous__ programming. The benefit of runtime variants is
that they project several types T1, ..., Tn into a single type
variant
[...]
So the bottom line is: Hana does not officially provide a sum type (variant/Either) for now, and it is not useful as far as my experience shows.
spirit uses variants as the attributes of alternative parsers:
https://github.com/djowel/spirit_x3/blob/master/example/x3/calc5.cpp#L43
Is there something spirit could be using instead?
IIUC, Spirit really needs __runtime__ variants, because they are used to store the result of parsing a string, which is done at runtime. In other words, you need the __actual__ type of the object held in the variant to be determinable at runtime, because that information is only available at runtime. You couldn't use Hana's Either, because the actual C++ type of your Either will change depending on the type of the object held in it. Regards, Louis [1]: https://groups.google.com/forum/#!topic/boost-devel-archive/H4_X1y0n7mU [2]: http://ldionne.com/hana/#tutorial-appendix-constexpr-stripping