-
Notifications
You must be signed in to change notification settings - Fork 73
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 releases too early when combined with NonDet #489
Comments
Interesting. I assume it's expected for pure interpreters to distribute over This resembles the interaction with Given that you wrote "too early" rather than "twice", I assume that you expected the distributive semantics – how would you expect the release action to be executed? Should the entire bracket be distributed? I've never thought about this before, so no idea what would be right. #246 is the closest discussion I can find, though its initial focus is different from this issue. In case you actually didn't explore the algebraic properties and just want to do IO with |
Thanks for your response.
I would say that the desirable behaviour is that the release happens exactly once, at the first time at which it is no longer possible to run a continuation that holds the resource.
Unfortunately that's no good either, at least for {-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DataKinds #-}
import Control.Applicative (asum, empty, (<|>))
import Control.Monad (guard)
import Polysemy (embed, runM)
import Polysemy.NonDet (runNonDet, runNonDetMaybe)
import Polysemy.Resource (bracket_, runResource)
example1 :: IO [Int]
example1 =
runM $
runResource $ do
runNonDet $ do
r <-
bracket_
(embed (putStrLn "Acquired"))
(embed (putStrLn "Released"))
( do
r <- (pure 1 <|> pure 2)
embed (putStrLn ("Used: " ++ show r))
pure r
)
guard (r /= 1)
pure r
-- ghci> example1
-- Acquired
-- Used: 1
-- Used: 2
-- Released
-- [2]
example2 :: IO (Maybe Int)
example2 =
runM $
runResource $ do
runNonDetMaybe $ do
r <-
bracket_
(embed (putStrLn "Acquired"))
(embed (putStrLn "Released"))
( do
r <- (pure 1 <|> pure 2)
embed (putStrLn ("Used: " ++ show r))
pure r
)
guard (r /= 1)
pure r
-- ghci> example2
-- Acquired
-- Used: 1
-- Released
-- Nothing
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DataKinds #-}
import Control.Applicative (asum, empty, (<|>))
import Control.Monad (guard)
import Polysemy (embed, embedFinal, runFinal, runM)
import Polysemy.NonDet (runNonDet, runNonDetMaybe)
import Polysemy.Resource (bracket_, resourceToIOFinal, runResource)
example1 :: IO [Int]
example1 =
runFinal $
resourceToIOFinal $ do
runNonDet $ do
r <-
bracket_
(embedFinal (putStrLn "Acquired"))
(embedFinal (putStrLn "Released"))
( do
r <- (pure 1 <|> pure 2)
embedFinal (putStrLn ("Used: " ++ show r))
pure r
)
guard (r /= 1)
pure r
-- ghci> example1
-- Acquired
-- Used: 1
-- Used: 2
-- Released
-- [2]
example2 :: IO (Maybe Int)
example2 =
runFinal $
resourceToIOFinal $ do
runNonDetMaybe $ do
r <-
bracket_
(embedFinal (putStrLn "Acquired"))
(embedFinal (putStrLn "Released"))
( do
r <- (pure 1 <|> pure 2)
embedFinal (putStrLn ("Used: " ++ show r))
pure r
)
guard (r /= 1)
pure r
-- ghci> example2
-- Acquired
-- Used: 1
-- Released
-- Nothing |
When I use
bracket
(or ratherbracket_
, in the example below) inside arunNonDet
block the resource is released too early. Is this expected?(I feel this must be a common question, so apologies if it's answered elsewhere, but I didn't find this precise issue in the documentation, nor from searching the issues here.)
The text was updated successfully, but these errors were encountered: