Skip to content

Changing (>>) in monad to accept consumable first inputs#356

Closed
saolof wants to merge 1 commit intotweag:masterfrom
saolof:patch-1
Closed

Changing (>>) in monad to accept consumable first inputs#356
saolof wants to merge 1 commit intotweag:masterfrom
saolof:patch-1

Conversation

@saolof
Copy link
Copy Markdown

@saolof saolof commented Jan 11, 2022

Currently (>>) has type m () %1-> m b %1-> m b .

This can easily be generalized to (Consumable a) => m a %1-> m b %1-> m b .

This change would make (>>) more similar to the nonlinear prelude and much more ergonomic to work with in effectful code. But it would technically break backwards compatibility for anyone who explicitly implemented (>>) on their types by making it more constraining, since they'd have to revert to using the default impl or sprinkle a consume somewhere.

As far as disadvantages go, I guess it might also make the library less explicit by adding the implicit consume? So in that sense there may be a tradeoff between ergonomics and being explicit.

Currently (>>) has type m () %1-> m b -> m b .

This can easily be generalized to (Consumable a) =>  m a %1-> m b -> m b  .

This change would make (>>) more similar to the nonlinear prelude and much more ergonomic to work with in effectful code. But it would technically break backwards compatibility for anyone who explicitly implemented (>>) on their types by making it more constraining, since they'd have to revert to using the default impl or sprinkle a consume somewhere.
@Divesh-Otwani
Copy link
Copy Markdown
Contributor

LGTM.

@Divesh-Otwani Divesh-Otwani self-requested a review January 11, 2022 20:04
@utdemir
Copy link
Copy Markdown
Contributor

utdemir commented Jan 11, 2022

As far as disadvantages go, I guess it might also make the library less explicit by adding the implicit consume? So in that sense there may be a tradeoff between ergonomics and being explicit.

You're right. To document it here, I think an alternative is to add:

void :: (Control.Functor f, Consumable a) => f a -> f () 

So, one would call void $ explicitly when they need to consume the value.

However, I have no preference either way, I can see how different use cases can choose convenience over explicitness or vice versa. As we have at least your case choosing for convenience, I see no reason choosing the other way :).

@aspiwack
Copy link
Copy Markdown
Member

Thanks for your interest @saolof !

I prefer having a void function and be explicit about it (in fact, it is a bug that we don't have one 🙂 ). I wrote (>>) with the unit type for this reason (I've long had a dislike for the type in base). I think it invites fewer mistakes.

So I'll insist pretty strongly on not changing the type of (>>).

@tbagrel1
Copy link
Copy Markdown
Member

I think that we could close this as soon as #387 is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants