Closed Gabriella439 closed 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
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.
Right now,
runStateP
,execStateP
,evalStateP
,runWriterP
, andexecWriterP
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:If the arguments went after it would have required the following even more unintelligible code:
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:
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 modifiedrunStateP
to take the arguments afterwords, then I could treat the constructor functions and run functions as simple isomorphisms:I'll probably make the switch in a couple of days but I wanted to invite discussion on this first.