
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.