Proposal: Applicative => Monad: Call for consensus
illissius at gmail.com
Thu Jan 6 21:28:30 CET 2011
2011/1/6 Gábor Lehel <illissius at gmail.com>:
> On Thu, Jan 6, 2011 at 5:42 PM, Iavor Diatchki <iavor.diatchki at gmail.com> wrote:
>> On Wed, Jan 5, 2011 at 3:29 PM, <roconnor at theorem.ca> wrote:
>>> On Wed, 5 Jan 2011, Iavor Diatchki wrote:
>>>> On Wed, Jan 5, 2011 at 8:04 AM, <roconnor at theorem.ca> wrote:
>>>> On Tue, 4 Jan 2011, Iavor Diatchki wrote:
>>>> In my completion monad, "join" is more efficent than "bind id"
>>>> This suggests that your monad will work less efficiently if you use it
>>>> with the do-notation.
>>> No. If I need to use fmap, there is no getting around it. Only if I use
>>> "bind id" is it faster to use "join".
>> I am not familiar with your monad but if you are not making essential use of
>> "bind" (or join and fmap together), then perhaps the monadic structure is
>> not particularly important?
>>>> Join and bind are very similar and, at least in standard Haskell code, I
>>>> think that "bind" has proven to be a lot
>>>> more useful then "join".
>>> AFAIU, In applicative style programming "join" has proven to be a lot more
>>> useful than "bind".
>> I am not sure what you mean here, I find the "do" notation quite useful.
>>>> Also, as I mentioned before, if people find "join" easier to define then
>>>> "bind", then they can define "join", and
>>>> then define "bind" in terms of that---I am still not convinced that we
>>>> need a new method added to the Monad class.
>>> If people find "bind" easier to define "join", then they can define
>>> "bind", and then define "join" in terms of that---Your argument is totally
>>> symetric in the terms "bind" and "join".
>> The situation is not symmetric because we already have a class with ">>="
>> and lots of code which depends on it---so I don't think that replacing ">>="
>> with "join" is really plausible (I would certainly not support such a
>> change). I am not convinced that adding "join" to the class, in addition to
>> ">>=", buys us anything but complexity.
> I'm not sure what you mean here by "replace" -- to _remove_ bind from
> Monad, and add join instead? I don't know of anyone proposing this.
> You're perfectly correct that it's possible to define a standalone
> join function yourself, and then write in what would be the proposed
> default definition for bind manually -- but roconnor is also perfectly
> correct that if the situation were the other way around, the same
> thing would be true in reverse. In other words, the argument is that
> the situation with bind being a method of Monad and join not being
> such is a historical accident, and not one supported by the merits.
> The fact that you can still write the function outside the class and
> define the class method in terms of it manually is true of
> approximately every class method and standalone function ever written.
> We could write all of our classes so that the most complicated and
> impressive functions are the methods, while defining the simple ones
> standalone in terms of those, with perhaps only a small amount of
> annoyance overhead resulting for our users -- but we don't. We tend to
> seek the ability to write minimal class definitions using the simplest
> and most straightforward methods we can find. It sends a message: this
> is the easiest/best way to write an instance. If you resort to writing
> what should've been a method as a standalone function instead and
> defining the method in terms of it, the message it sends is "the
> definition of this class is flawed and I'm working around it". But
> most people probably don't think of doing this, and just define the
> simplest out of whatever methods they are given. After all, writing
> simple functions and then defining the more complex ones as
> combinations of those is what Haskell is all about, isn't it? So we
> should strive to support that, even if it can be done in our spite
> when we don't.
> And as has been argued at length in this thread, for a great many
> types it is easier, cognitively if not physically, to define fmap and
> join than to define bind. (And for the others, like Oleg's example,
> they can just say fmap = liftM and keep merrily on.) It was actually
> thinking about the type signature of join which made the whole Monad
> thing finally 'click' for me, which isn't bad considering that
> Applicative has only about halfway clicked so far. It absolutely feels
> more fundamental as an operation than bind does, even if bind might be
> the more useful combinator.
> There's also the consideration that when defining instances for a new
> type, many (most?) people tend to write an instance for the superest
> class in a hierarchy first, and then to work their way down. (Even
> without the hierarchy being explicit a lot of people, myself included,
> already do this for Functor/Applicative/Monad). So by the time they
> get to Monad they have an fmap already written, and they're like --
> "why do I have to reimplement essentially the same functionality again
> as part of (>>=)? Oh wait, here's join instead, that'll be easier."
As a yet further note, it seems that the comonads package defines
the Comonad class in an analogous way, with the analogues for return,
join, and bind (extract, duplicate, and extend) being the methods,
default definitions given in terms of each other, and also an external
liftW function defined in terms of extend (~bind) which is recommended
as a simple definition for fmap for when extend has already been
defined. So I'm not the only one who feels this structure is logical.
>> Libraries mailing list
>> Libraries at haskell.org
> Work is punishment for failing to procrastinate effectively.
Work is punishment for failing to procrastinate effectively.
More information about the Libraries