Gabriella439 / pipes

Compositional pipelines
BSD 3-Clause "New" or "Revised" License
489 stars 72 forks source link

Switch `runStateP` and friends to put arguments after the proxy #75

Closed Gabriella439 closed 11 years ago

Gabriella439 commented 11 years ago

Right now, runStateP, execStateP, evalStateP, runWriterP, and execWriterP differ from their transformers counterparts by taking all arguments before the body of the monad to run.

The original rationale for doing this was back when everything was a Kleisli arrow in the pipes-3.* series, and they made it possible to write code like this:

(runStateP someState) . someProxy

If the arguments went after it would have required the following even more unintelligible code:

(`runStateP` someState) . someProxy

However, now that the unidirectional API does not use Kleisli arrows it may be worth switching them back to place the arguments afterwards because it is much cleaner now:

-- What things would look like after the change
runStateP someProxy someState

This would make the API more consistent with transformers.

The other reason I would like to do this is because of issue #72, which adds support for the constructor analogs of these run functions (i.e. maybeP / stateP). If I modified runStateP to take the arguments afterwords, then I could treat the constructor functions and run functions as simple isomorphisms:

runStateP . stateP = id
stateP . runStateP = id

I'll probably make the switch in a couple of days but I wanted to invite discussion on this first.

Shimuuar commented 11 years ago

I think current order of arguments is better and transformers got it wrong, I usually end up flipping arguments order. Consider following contrived examples:

runStateT s0 $ runWriterT $ runMaybeT $ do {....}

runStateT (runWriterT (runMaybeT $ do {...})) s0

It's not possible to write do block after run* functions and initial state is very far from runStateT which hurts readability

Also nothing stops you from treating them as isomorphism now

flip runStateP . stateP = id

Gabriella439 commented 11 years ago

I've decided that you're right. Putting the arguments after the body of the function is a big inconvenience, even if it is consistent with transformers, so I'm closing this issue.