gpt4 book ai didi

sqlite - 在SQLite中使用ReaderT和runReaderT吗?

转载 作者:行者123 更新时间:2023-12-03 15:30:41 26 4
gpt4 key购买 nike

我有以下代码,取自here

type Blog a = ReaderT SQLiteHandle IO a
data BlogDBException = BlogDBException String deriving (Show, Typeable)
instance Exception BlogDBException

run :: Blog a -> IO a
run m = do
db <- openConnection "myblog.db"
runReaderT m db --runReaderT :: ReaderT r m a -> (r -> m a)


sql :: String -> Blog (Either String[[Row Value]])
sql query = do
db <- ask --ask :: Monad m => ReaderT r m r
liftIO $ do
putStrLn query
execStatement db query


dbQuery :: Blog [Int]
dbQuery = do
r <- sql "select UID from UIDS;"
case r of
Right [rows] -> return [fromIntegral uid | [(_, Int uid)] <- rows]
Left s -> liftIO $ throwIO (BlogDBException s)
_ -> liftIO $ throwIO (BlogDBException "Invalid result")


我想了解

1) readerTdata Blog a中的确切角色?

2) runReaderT在这里到底在做什么?

3) ask函数如何工作?

有人有一个简单的解释吗?这是我第一次使用 Reader monad。

最佳答案

1)在此示例中,ReaderT的目的是使类型的SQLiteHandle值可用于函数,而无需向每个函数添加附加参数。

2)runReaderT“打开” ReaderTnewtype ReaderT r m a = ReaderT { runReaderT :: r -> m a}。如您所见,真正的表示形式是r -> m a:从提供的类型为r的项目到您认为直接处理的m a的函数。因此,ReaderT并不能真正避免必须在函数中添加新参数的事实。它只是为您隐藏。

3)runReaderT ask == runReaderT $ ReaderT return == return == r -> m r因此,ask只需将其包装在底层monad中即可提供对“环境” r(附加参数)的访问。

这是一个非常简单的例子(实际上太简单了,难以实现)。

type ModeFlag = Int

g :: ModeFlag -> IO ()
g modeFlag = ... -- take some action based on modeFlag


相当于

h :: ReaderT ModeFlag IO ()
h = do
modeFlag <- ask
... -- take some action based on modeFlag


当我开始学习Haskell时,这种技术的效用对我来说并不是立即显而易见的。但是,请考虑以下情况:您有许多配置参数,或者可以预见需要尽快添加更多配置参数。向函数添加新参数非常不方便。相反,只需将您的配置值打包到一条记录中,然后通过 ReaderT在整个应用程序中提供它。有一个称为 asks的函数,它与 ask类似,但也需要一个函数应用于 r值。这可用于从记录中提取某些字段。

data Config :: Config { param1 :: Int, param2 :: String, ... other fields }

doStuff :: ReaderT Config IO ()
doStuff = do
i <- asks param1
s <- asks param2
undefined -- do some stuff


在文档中(底部的 http://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Reader.html)还有 ReaderReaderT的更多示例,包括 local函数,这很酷,但是我用的并不多。

关于sqlite - 在SQLite中使用ReaderT和runReaderT吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41825686/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com