在以下情况下,我可以在initCass' fdsEnv
MonadUnliftIO m
块中直接使用RIO
(类型为do
):
initCass :: RIO FdsEnv ClientState
initCass = do
fdsEnv <- ask
initCass' fdsEnv
initCass' :: MonadUnliftIO m => FdsEnv -> m ClientState
initCass' fdsEnv = do
let config = fdsConfig fdsEnv
let logger = fdsLogger fdsEnv
initCassandra (dbName config) (dbHost config) (dbPort config) logger
但是,当我尝试在此处执行类似操作时:
runClientSafe :: MonadUnliftIO m => (ClientState -> m a) -> RIO FdsEnv a
runClientSafe cliFun = do
fdsEnv <- ask
bracket (runRIO fdsEnv initCass) shutdown cliFun
我得到一个错误:
• Couldn't match type ‘m’ with ‘RIO FdsEnv’
‘m’ is a rigid type variable bound by
the type signature for:
runClientSafe :: forall (m :: * -> *) a.
MonadUnliftIO m =>
(ClientState -> m a) -> RIO FdsEnv a
at src/FDS/Database/Cassandra.hs:75:1-72
Expected type: RIO FdsEnv a
actual type: m a
• In a stmt of a 'do' block:
bracket (runRIO fdsEnv initCass) shutdown cliFun
In the expression:
do fdsEnv <- ask
bracket (runRIO fdsEnv initCass) shutdown cliFun
In an equation for ‘runClientSafe’:
runClientSafe cliFun
= do fdsEnv <- ask
bracket (runRIO fdsEnv initCass) shutdown cliFun
• Relevant bindings include
cliFun :: ClientState -> m a
(bound at src/FDS/Database/Cassandra.hs:76:15)
runClientSafe :: (ClientState -> m a) -> RIO FdsEnv a
(bound at src/FDS/Database/Cassandra.hs:76:1)
|
78 | bracket (runRIO fdsEnv initCass) shutdown cliFun
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我认为差异在于,在第一种情况下,initCass'
的m解析为RIO FdsEnv
,所以这是有道理的。我想真正需要的是一种从MonadUnliftIO m -> RIO e
开始的方法,但不确定是否可行。