Boost.Hana - Maybe and Either data types design
Hi Louis, I have some concerns with the design of the Maybe and Either data types (maybe the other data types have the same design, I have not taken a look at). There are somethings that I don't understand, sorry I have not changed yet my mind to then new C++ way. If I want to define a function that takes an Either string int, how can I define it? void f(??? p) {} I see that there is a maybe_detail::maybe<bool,class>, however I don't think this is the data type of Maybe, is it? Anyway, I don't see a either_detail::either<bool, class, class>. I have the impression that I must use always auto with lambdas auto f = [](auto p) {...}; But I don't know what I can put in the body. It is to clear neither how can I declare a variable of type Either string int. I see that I can declare a Left string and a Right int BOOST_HANA_CONSTEXPR_LAMBDA auto left_value = left("x"); BOOST_HANA_CONSTEXPR_LAMBDA auto right_value = right(1); I have the impression that the variables are initialized only once and can not be reassigned,or at least we can not assing a Left value to a variable initialized with a Right value. Is this by design? A last concern related to the applicative lift function. I suspect that it corresponds to the Haskell return function and the more general unit Monad function. As there is a lift function in Haskell, this is a little bit confusing. I have named this function make :) In Haskell, the template parameter is a type constructor. This Monad(Applicative) type constructor should be Either E, not Either. Is the type-constructor feature missing from your design? How wan I create an Either string int with a call to auto x =lift<Either>(123); I would expect something like auto x = lift<Either<string>>(123); In my prototype I have auto x = make<expected<holder, string>>(123); where expected<holder, string> is the Monad type constructor for expected<T, string>. Sorry the argument of expected and Either are in interchanged. The string type is the Error. Best, Vicente
Vicente J. Botet Escriba <vicente.botet <at> wanadoo.fr> writes:
Hi Louis,
I have some concerns with the design of the Maybe and Either data types (maybe the other data types have the same design, I have not taken a look at). There are somethings that I don't understand, sorry I have not changed yet my mind to then new C++ way.
If I want to define a function that takes an Either string int, how can I define it?
void f(??? p) {}
I see that there is a maybe_detail::maybe<bool,class>, however I don't think this is the data type of Maybe, is it? Anyway, I don't see a either_detail::either<bool, class, class>.
I have the impression that I must use always auto with lambdas
auto f = [](auto p) {...};
That's a tricky question. Basically, what you're saying is "Hana does not have parameterized data types". You're right. The reason for this is that I have not figured out two important things: 1. Does it even make sense to have parameterized data types considering that Hana deals with heterogeneous objects? For example, you probably wouldn't write a function returning Maybe<T> with Hana: you would write a function returning Maybe<T or U or V>. Also, consider the following: what should a Tuple containing objects of type T, U and V be parameterized over? Clearly, it is not a Tuple<T>, nor a Tuple<U>, nor a Tuple<V>. I'm thinking more and more that Hana is just a way to handle variants, and so it would maybe make sense to have a Tuple<variant<T, U, V>>. To be honest, I haven't figured this out completely yet. 2. We use tag dispatching and data types, which is basically a type system at the library-level. Since we don't have data-type inference, you would need to carry around potentially a lot of data-type information manually. This is analogous to writing metafunctions to compute return types in pre-auto C++; we would now have to write metafunctions to compute return data-types. At least I think. I have already started exploring this [1], but I have not found any satisfying solution yet. That being said, if there was a sound way to introduce parameterized data types, it would be very nice because that would make the library more powerful.
But I don't know what I can put in the body. It is to clear neither how can I declare a variable of type Either string int. I see that I can declare a Left string and a Right int
BOOST_HANA_CONSTEXPR_LAMBDA auto left_value = left("x"); BOOST_HANA_CONSTEXPR_LAMBDA auto right_value = right(1);
I have the impression that the variables are initialized only once and can not be reassigned,or at least we can not assing a Left value to a variable initialized with a Right value. Is this by design?
Yes, do not forget that Hana deals with _heterogeneous_ objects. For example, (using Maybe instead of Either for simplicity) it would not make sense to assign a Maybe containing a string to a Maybe containing an int. In general, assignment would only make sense when trying to assign a Maybe containing T to another Maybe containing T, or when trying to assign a Maybe containing T to another Maybe containing U, with some convertible-to-U hypothesis on T. I agree that this could be useful, but for simplicity I have privileged the "zero-mutation" approach so far.
A last concern related to the applicative lift function. I suspect that it corresponds to the Haskell return function and the more general unit Monad function. As there is a lift function in Haskell, this is a little bit confusing. I have named this function make :) In Haskell, the template parameter is a type constructor. This Monad(Applicative) type constructor should be Either E, not Either. Is the type-constructor feature missing from your design?
A non-nullary type constructor corresponds to what I called a parameterized data type above. So yes, they are missing from the design and like I said I am not sure whether it is (1) possible and (2) desirable to support them.
[...]
To wrap up, I would say that type classes and data types in Hana are really just impostors. They do not _formally_ provide a way to reason about our (meta)programs, which is the case e.g. in Haskell. That's because there's no way to formally reason about a program that manipulates objects of any (read unspecified) type. That being said, using type classes and data types still makes it much easier for the programmer to reason _informally_. An example of this: I think it is pretty natural to think of a std::tuple like a "Functor" because it can be mapped over. However, in Haskell (or in maths), it does not make any sense whatsoever to define fmap on a tuple like applying a function to each of its elements; what should be the domain of the function? TL;DR: We're trading formal correctness for ease of use, and I'm looking for a way to get both. Regards, Louis [1]: https://github.com/ldionne/hana/blob/master/test/sandbox/strong_datatypes.cp... -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-Hana-Maybe-and-Either-data-types-de... Sent from the Boost - Dev mailing list archive at Nabble.com.
participants (2)
-
Louis Dionne
-
Vicente J. Botet Escriba