Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bracket allows us to observe normal vs abnormal exit #31

Open
tomjaguarpaw opened this issue Dec 6, 2024 · 1 comment
Open

bracket allows us to observe normal vs abnormal exit #31

tomjaguarpaw opened this issue Dec 6, 2024 · 1 comment

Comments

@tomjaguarpaw
Copy link
Owner

I don't know whether this is desirable or not. Does it suggest that bracket should require IOE? Here's a discussion where I came to the conclusion that it shouldn't.

#8

Maybe we should revisit that discussion.

-- ghci> exitedNormally True
-- Normal
-- ghci> exitedNormally False
-- Exception
exitedNormally :: Bool -> IO ()
exitedNormally doNormal = runEff $ \io -> do
  fmap (either id id) $ try $ \ex ->
    evalState False $ \sExitedNormally -> do
      bracket
        (pure ())
        ( \() -> do
            normal <- get sExitedNormally
            effIO io $ putStrLn $ if normal then "Normal" else "Exception"
        )
        ( \() -> do
            unless doNormal (throw ex ())
            put sExitedNormally True
        )
@tomjaguarpaw
Copy link
Owner Author

On the other hand, in any specific case of the body of the bracket I do statically know all exceptions that could be raised (there are any number of Bluefin ones, plus IO ones, if I have IOE) so the exact same behaviour can be simulated without bracket. Perhaps this behaviour then isn't so surprising.

The difference is that bracket somehow detects all exceptions, without statically knowing which ones are possible. That also may be fine, because in theory each use of handle (or its equivalents) could introduce into Eff a dynamic collection of all exceptions in scope.

Let's see how this plays out in practice. It seems like we should recommend against observable behaviours in bracket's "after", but maybe it's not so terrible if it happens.

-- ghci> exitedNormally2 True
-- Normal
-- ghci> exitedNormally2 False
-- Exception
exitedNormally2 :: Bool -> IO ()
exitedNormally2 doNormal = runEff $ \io -> do
  fmap (either id id) $ try $ \ex ->
      handle
        (\exval -> do
            effIO io $ putStrLn "Exception"
            throw ex exval)
        (\ex' -> do
            unless doNormal (throw ex' ())
            effIO io (putStrLn "Normal"))

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

No branches or pull requests

1 participant