我目前正在阅读(出于自学目的)Bryan O'Sullivan 的流行pool 库的源代码。
我在函数中有一个问题takeResource,我想在这里询问Haskell专家。该函数定义为:
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)
Run Code Online (Sandbox Code Playgroud)
我遇到问题的线路是
...
resource <- liftBase . join . atomically $ do
...
Run Code Online (Sandbox Code Playgroud)
为什么这里使用liftBasenecessary?我们也可以这样写吗
...
resource <- join . atomically $ do
...
Run Code Online (Sandbox Code Playgroud)
编译器接受这两个版本。我在这里错过了一些琐碎的事情或者为什么liftBase这里是必要的?
预先感谢您的提示!