【发布时间】:2016-05-29 21:40:35
【问题描述】:
我正在使用带有自定义 monad 堆栈的 Servant:
newtype AppHandler a = AppHandler { runHandler :: ReaderT Config (ExceptT ServantErr IO) a }
deriving (Functor, Applicative, Monad, MonadReader Config, MonadError ServantErr, MonadIO)
data Config = Config
{ getPool :: ConnectionPool }
现在,在许多处理程序中,我只需要从 db 获取一些数据(持久性)并对其采取行动,所以我得到了:
runDb :: (MonadReader Config m, MonadIO m) => SqlPersistT IO b -> m b
runDb query = do
pool <- asks getPool
liftIO $ runSqlPool query pool
事实证明,当从 db 中获取时,您必须使用 Maybe,并且通常当 Maybe 是 Nothing 时,您只想抛出错误以便 Servant 服务器将其转换为正确的HTTP 响应。这让我发现了Control.Error.Util 和(!?) :: Applicative m => m (Maybe a) -> e -> ExceptT e m a 助手。所以我尝试了以下操作:
someHandler :: AppHandler NoContent
someHandler = do
entity <- (runDb $ getCompanyByName companyName) !? err400
-- some more logic
return NoContent
但这不会编译,!? 的结果是ExceptT ServantErr m0 (Entity SomeEntity) 但我不再使用这种处理程序类型,它需要AppHandler (Entity SomeEntity)。我如何将这样的值转换回我的处理程序类型?
【问题讨论】:
标签: haskell monad-transformers servant