I am currently reading through (for self studying purpose) the source code of the Bryan O'Sullivan's popular pool
library.
And I have a question in the function takeResource
, which I would like to ask the Haskell experts here. The function is defined as:
takeResource :: Pool a -> IO (a, LocalPool a)
takeResource pool@Pool{..} = do
local@LocalPool{..} <- getLocalPool pool
resource <- liftBase . join . atomically $ do
ents <- readTVar entries
case ents of
(Entry{..}:es) -> writeTVar entries es >> return (return entry)
[] -> do
used <- readTVar inUse
when (used == maxResources) retry
writeTVar inUse $! used + 1
return $
create `onException` atomically (modifyTVar_ inUse (subtract 1))
return (resource, local)
The line I am having problem with is
...
resource <- liftBase . join . atomically $ do
...
Why is here the usage of liftBase
necessary? Can we also write instead
...
resource <- join . atomically $ do
...
The compiler accepts both versions. Am I missing here something trivial or why is liftBase
here necessary?
Thank you in advance for the tips!
I think I'm responsible for that. No, there's no purpose for it to be there, it can be removed. I think it was necessary before some refactoring. You could send a pull request and be part of an awesome library :)
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments