最近見かけたHaskell library: unliftio-pool

unliftio-poolはresource-poolMonadUnliftIOにgeneralizeしたバージョン。

resource-poolはその名の通りリソースプールの汎用実装。例えばデータベースコネクションなんかを蓄積しておいて、各スレッドがプールからコネクションを引き抜いて使う。

resource-poolでは以下のようなbracket形式のAPIを提供する。

withResource :: Pool a -> (a -> IO r) -> IO r

Poolからresource aを引き抜き、アクションを実行し、完了したらresourceをプールに戻す。

ただし、このAPIモナドIOに固定されていることが少々厄介だ。これにより、いろいろな機能を積み込んだカスタムモナドで使いづらい状態になっている。特に(a -> IO r)が面倒になる。

一方、unliftio-poolは同じ機能を以下のAPIで提供する。

withResource :: MonadUnliftIO m => Pool a -> (a -> m b) -> m b

これにより、MonadUnliftIO classのインスタンスモナド全般でresource-poolを使える。

MonadUnliftIOunliftio-coreで定義されるtype class。ざっくり言えば、MonadUnliftIO mなるモナドmIOに変換できる、つまりrun :: forall a . m a -> IO aなる関数が存在する、という性質を持つ。このようなモナド(transformer)には、IdentityT, ReaderT, LoggerT, ResourceTがある。