If the methods are separated from the type classes, they can't have a default definition which depends on the MCD that's used. For example, let's pretend I have two MCDs for Foldable; `fold_mcd` and `unpack_mcd`. `fold_mcd` requires both `foldl` and `foldr`, and `unpack_mcd` requires `unpack`. Now, there are multiple ways to implement `sum`. Two of them are:
auto sum = [](auto xs) { return foldl(_+_, int_<0>, xs); };
auto sum = [](auto xs) { return unpack(some_very_fast_sum_on_variadic_packs, xs); };
where `some_very_fast_sum_on_variadic_packs` would put the `xs` in an array and then return a `int_
`. However, in `fold_mcd`, `unpack` is implemented inefficiently, and in `unpack_mcd`, `fold` is decent but it is still likely not as efficient as a user-provided one. Which implementation for `sum` do I choose? If I pick the first one, it's going to be suboptimal with objects that used `unpack_mcd`. If I pick the second one, it's going to be suboptimal with objects that used `fold_mcd`.
But as user if I was defining my own `sum` function, how would I do it? I can't change the typeclass, since it is in another library. Is there a way for me as an user to optimize my sum function based on which MCD was implemented? And if so, couldn't the library do the same?
If you go look at the Foldable type class in Haskell, you'll see that there are a bunch of related functions provided with the type class, yet they are not included in it. My opinion is that they might just as well be included in the type class, as you could then redefine them for improved performance. I just searched online for a rationale or at least some insight about this decision, but I did not find anything.
I think the rational is similar to the rational for using non-member functions. One reason is consistency. People are going to add new algorithms, but they won't be added to the typeclass. Futhermore, if they want to allow overloading the algorithm for optimization, they will create new typeclasses. So now you have two different ways to accomplish the same thing. Another reason, is it will make the typeclass simpler and improve encapsulation. A typeclass is defined by the minimum necessary and not by another 50 algorithms.
That being said, Monads are a common hurdle for people learning FP (I myself am super new to this stuff, BTW) and I'm not sure changing the name would do any good. To grok Monads, you have to bang your head a bit, not think of them as one particular metaphor[1]. Also, FWIW, I think that defining Monads with `join` (as in Hana) instead of `bind` (as in Haskell) makes them easier to understand, but that's just me.
I do agree that `join` is easier than `bind`.
Yup, you're missing `cons` and `nil`. But you're right that `List` can be refactored, and I plan to do it. For example, `filter` can be implemented if you give me `nil` and a `Monad`, which makes a `MonadZero` (a Monad with a neutral element):
// pseudo code auto filter = [](auto pred, auto xs) { auto go = [=](auto x) { return pred(x) ? lift(x) : nil; }; return join(fmap(go, xs)); };
You get `fmap` from Functor, `lift` from Applicative and `nil` from MonadZero. Then you can filter Maybes, with `nil` being `nothing`!
Awesome.
- It's important to note that the `decltype_` function will only work for constexpr-friendly types.
I don't get it? Can you please expand?
I should clarify that I'm referring to the use of `decltype_` within the context of constexpr. It will work outside of that. So, for example, if I were to static_assert that two types were the same, as a simple example: template<class T> void foo(T x) { auto y = bar(); static_assert(decltype_(x) == decltype_(y), "Not matching types"); } This won't work for if types are not a literal type nor have a constexpr constructed. This will fail even if `decltype_` was to take the expression by reference. Ultimately, I believe the language should be changed to allow for this. -- View this message in context: http://boost.2283326.n4.nabble.com/Re-GSoC-Boost-Hana-Formal-review-request-... Sent from the Boost - Dev mailing list archive at Nabble.com.