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
Vicente J. Botet Escriba
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
, however I don't think this is the data type of Maybe, is it? Anyway, I don't see a either_detail::either . 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
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