Code Monkey home page Code Monkey logo

Comments (17)

viboes avatar viboes commented on August 16, 2024

Yes, there are at least 3 major differences
1 the order of parameters
2 monad::bind calls the continuation while std::bind create a functor.

std::experimental::future<T> has `then(), but the continuation takes thefuture`` as parameter and it has an asynchronous connotation.

I suggested the addition of next with a continuation taking Tbut it also has an asynchronous connotation.

apply seems better, but the order of parameters should be changed. This name is also appropriated as a replacement for fmap.

What do you think of overloading apply to cover fmapand bind?

apply :: (a -> b) -> f a -> f b
apply :: (a -> m b) -> m a -> m b

from hana.

ldionne avatar ldionne commented on August 16, 2024

We totally agree that bind is not the right name. However, apply is already used to denote function application (see boost/hana/functional/apply.hpp).

Also, I do not think fmap should be renamed to apply; I think the intent is much more clearly expressed by saying fmap (mapping a function), and that name (or close variations thereof) is already used in other programming languages like Python.

That being said, I am not closed to the idea of renaming bind to apply, and then finding a new name for apply. Or even better: if we could come up with a data type for functions, and if that data type was the instance of a type class which provided a method equivalent to apply, then I would happily use that method instead of apply and we could rename bind to apply. That option might even make us able to generalize (and hopefully rename) some other functions from the Functional module like demux.

As for the idea of overloading the name apply, I am reluctant to do so at first sight. I prefer to keep things more explicit (especially in the case of such similar-looking functions) to avoid confusion. Keeping things explicit forces one to stay honest and keep track of what is inside a Functor and what isn't in a more rigorous way.

from hana.

wolftype avatar wolftype commented on August 16, 2024

extend ?
pipe (cause of | )
fjoin ( that's ugly)

Nice work on this Louis!

from hana.

ldionne avatar ldionne commented on August 16, 2024

extend is already commonly used for Comonads. Since I think there's a nice generalization of the current Logical type class using Comonads, I might need that name later on. Otherwise, it might make sense to use extend; I'll consider that.

pipe might make sense too. I was reluctant at first sight, but it really might make sense.

fjoin is too ugly.

Thanks for the suggestions!

from hana.

pfultz2 avatar pfultz2 commented on August 16, 2024

Actually, I implemented the state monad in C++, just as an exercise(see here). I used for_ for bind and yield for return so there is no double return at the end. I also had a do_ for the then operator. It seems those terms would be more familiar to C++ programmers. I chose for_ since it introduces a new scope and variables, it seemed fitting. Just my two cents.

from hana.

ldionne avatar ldionne commented on August 16, 2024

That's a very interesting gist. I'll have a deeper look at it when I get the time (exams right now), but I think this might be a nice direction to take.

from hana.

ldionne avatar ldionne commented on August 16, 2024

Two new suggestions:

chain(monadic_result, monadic_function)
monadic_apply(monadic_function, monadic_result)

from hana.

ldionne avatar ldionne commented on August 16, 2024

Note that monadic_apply would be consistent with the recently added monadic_fold. I still don't like it as much as chain (or pipe) though.

from hana.

pfultz2 avatar pfultz2 commented on August 16, 2024

Is it possible to combine fold with an overload for monadic_fold? Or perhaps there is a way to annotate a function to signify that it returns a monadic type?

from hana.

ldionne avatar ldionne commented on August 16, 2024

You mean provide only fold and use a monadic variant whenever the function returns a monadic result? This is not possible right now, because we don't know the generalized type returned by functions. It would be possible to annotate functions so we have that knowledge, e.g.:

auto f = monadic_function<Monad>([](auto x) { ... });
fold(xs, state, f); // uses a monadic fold

Is this what you mean?

from hana.

pfultz2 avatar pfultz2 commented on August 16, 2024

Is this what you mean?

Yes. Also, I wonder if Monad could be deduced at a later stage. So essentially you could write:

auto f = monadic_function([](auto x) { ... });
fold(xs, state, f); // uses a monadic fold

from hana.

ldionne avatar ldionne commented on August 16, 2024

I assume you mean that Monad would be deduced when we call monadic_function(f) on an argument. This way, it could deduce it from the return type of the wrapped function f. Is this what you mean?

If so, this is a brilliant idea, but unfortunately it won't work. monadic_fold must know the Monad even when the function is never called, for example in the case of an empty sequence. This is required so it can lift the state into the proper Monad.

It would be possible to wrap the state in a "yet-to-be-determined" Monad, by using e.g. lift(state) instead of lift<M>(state). I'm not exactly sure what that would buy us and what it might complicate, but I would say it is worth thinking about.

I personnally like the fact that monadic_fold must be written explicitly, since they really are two different things. If we can find a nice way (e.g. a proper generalization of folding and monadic folding) to make fold and monadic_fold coincide then I would be interested, but otherwise I don't see this as a defect.

from hana.

pfultz2 avatar pfultz2 commented on August 16, 2024

but unfortunately it won't work. monadic_fold must know the Monad even when the function is never called

Oh yea thats right.

I personnally like the fact that monadic_fold must be written explicitly, since they really are two different things

Yes it does make sense to have two seperate functions, as well. I was just trying to think of a possible different approach.

from hana.

viboes avatar viboes commented on August 16, 2024

An alternative to renaming to avoid syntactic or semantic conflicts with other names is, in C++, to use namespaces to name type classes.

auto x = monad::bind(m, f);
auto y = functor::map(f, m);

As Haskell as no namespaces, it needs to use prefix f, m such as in fmap, mzero, mplus.

I'm not saying that bind and map are the best names, just that adding the type class give us more freedom.

from hana.

ldionne avatar ldionne commented on August 16, 2024

While it technically gives us more freedom, in practice we then have to type monad::bind all around or using namespace boost::hana::monad. I find this unattractive. Also, when you push the concept, you end up with foldable::fold.left, sequence::remove_at, searchable::find_if and so on, which is cumbersome. We don't have major naming conflicts in the library right now as I've managed to name things in such a way that everything fits. Of course, the names are not perfect (as reflected by this thread), but I don't have fmap and mzero and so on either. I'd rather not use namespaces.

from hana.

ldionne avatar ldionne commented on August 16, 2024

I'm about to close this. I decided to rename bind to chain. I also want to thank @pfultz2 for suggesting the monadic_function thing; this made me realize that I could remove template parameters in some cases by deferring the computation, which I just did with mcompose (now called monadic_compose by the way).

from hana.

ldionne avatar ldionne commented on August 16, 2024

fixed by fb518d8

from hana.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.