[Haskell-cafe] STM rollback?

Jake McArthur jake.mcarthur at gmail.com
Fri Dec 4 22:44:21 UTC 2020


Sorry for the noise. My code is wrong. Here is a corrected version:

possiblyRollback :: STM (Either e a) b -> STM e (Either a b)
possiblyRollback stm = fmap Right stm `orElse` either retry (return . Left)

On Fri, Dec 4, 2020 at 5:38 PM Jake McArthur <jake.mcarthur at gmail.com>
wrote:

> I made an STM implementation for work with the ability to give a "reason"
> for retrying, which I have found very useful. A Haskell version might look
> something like this:
>
> data STM e a
> instance Monad (STM e)
>
> -- These also form a monad, but we'd need a newtype to define the instance.
> retry :: e -> STM e a
> orElse :: STM e1 a -> (e1 -> STM e2 a) -> STM e2 a
>
> With this interface, you could define something like this:
>
> possiblyRollback :: STM (Either e a) b -> STM e (Either a b)
> possiblyRollback stm = fmap stm Right `orElse` either retry (return . Left)
>
> With this, you can retry as normal with `retry (Left e)`, locally rollback
> with `retry (Right a)`, or return as normal with `return b`.
>
> On Mon, Nov 30, 2020 at 3:47 AM Joachim Durchholz <jo at durchholz.org>
> wrote:
>
>>  From a contract design perspective, rolling back means that an
>> operation failed and had to be undone. (If everything was fine, you
>> wouldn't want to rollback, wouldn't you?)
>>
>> So if rollback is the reaction to some failure, then triggering it via
>> an exception is the Right Thing To Do, actually.
>> Oh, and you always want to rollback if there's an exception somewhere.
>>
>> Now that contract thing warrants a few more words.
>> Yes, you can word your contracts so that they include failure. It's just
>> that they get more complicated. Usually so much more complicated that
>> it's not worth it.
>> Also, you want any exception (i.e. breach of contract) to go into a
>> rollback. Now in Haskell, rolling back means just abandoning the
>> computation since things aren't mutable and there is no state that you
>> need to restore. Technically, not even in STM - so there *is* reason to
>> make the rollback non-exceptional here: One could argue that STM is
>> *supposed* to include the rollback in the contract.
>> In the end, it depends on your use case: Do you want the rollback in the
>> contract or not?
>>
>> Now for STM itself, yeah using an exception to trigger a rollback is a
>> bit hacky.
>> OTOH it works.
>> OT3H it might be a good idea to have a rollback function for STM.
>> Technically it would just trigger the same exception, but it would
>> indicate that the rollback is part of the contract.
>> OT4H throwing Rollback is essentially an indicator of non-failure
>> rollback (otherwise you'd be throwing whatever exception is appropriate,
>> or get aborted by some library functionality that throws an exception).
>>
>> Regards,
>> Jo
>>
>> Am 28.11.20 um 22:05 schrieb amindfv--- via Haskell-Cafe:
>> > I'd like to be able to give up on an STM transaction: roll back and
>> don't retry.
>> > I've cooked up something with exceptions but it feels a bit icky to use
>> exceptions for something like this - is there a better way?:
>> >
>> >      data Rollback = Rollback deriving (Show)
>> >      instance Exception Rollback
>> >
>> >      rollback :: STM x
>> >      rollback = throwSTM Rollback
>> >
>> >      atomicallyWithRollback :: STM x -> IO (Maybe x)
>> >      atomicallyWithRollback a =
>> >         (Just <$> atomically a)
>> >            `catch` (\Rollback -> pure Nothing)
>> >
>> > The alternative I've found is something like:
>> >
>> >      otherWay :: STM x -> IO (Maybe x)
>> >      otherWay a =
>> >         atomically $ (Just <$> a) `orElse` pure Nothing
>> >
>> > But this turns any "retry" in "a" into a rollback, and I'd like to have
>> the option to do either (retry or rollback).
>> >
>> > Thanks,
>> > Tom
>> >
>> >
>> > _______________________________________________
>> > Haskell-Cafe mailing list
>> > To (un)subscribe, modify options or view archives go to:
>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> > Only members subscribed via the mailman list are allowed to post.
>> >
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> To (un)subscribe, modify options or view archives go to:
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>> Only members subscribed via the mailman list are allowed to post.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20201204/ae7f92b7/attachment.html>


More information about the Haskell-Cafe mailing list