我一直在享受學習Haskell,我認爲我在這裏和#haskell的幫助下取得了一些很好的進展。我的學習大部分時間還處於觀察示例的階段,並試圖抽象出應用在那裏的技術並將其應用到我自己的代碼中。如何在monad堆棧中使用持久化?
目前,我已經開始研究開發用於各種應用程序的monad堆棧,我期待將持久框架的功能集成到我的應用程序中。
這裏是我的單子堆棧:
newtype App a = App { unApp :: StateT AppState (SqlPersistT (ResourceT (LoggingT IO))) a }
deriving (Applicative
, Functor
, Monad
, MonadIO
, MonadState AppState
)
AppState
僅僅是一個記錄數據型保持在這個例子中一個int值。
我的主要功能是這樣的:
main = runApp "./test.sqlite" (AppState 69) runMigrate
其中runApp
應該解開所有的單子:
runApp :: Text -> AppState -> App a -> IO a
runApp t s a =
runStdoutLoggingT . runResourceT . withSqliteConn t . runSqlConn . flip evalStateT s . unApp
和runMigrate
是在App
單子運行應用程序。在這種情況下,我在拍攝的只是得到它運行遷移:
runMigrate :: App()
runMigrate = return $ liftPersist $ runMigration migrateAll
編譯器指出,我不知道我該投訴做:
Main.lhs:59:16:
Couldn't match type ‘m0()’ with ‘()’
Expected type: App()
Actual type: App (m0())
In the expression: return $ liftPersist $ runMigration migrateAll
In an equation for ‘runMigrate’:
runMigrate = return $ liftPersist $ runMigration migrateAll
問題:
什麼是正確的方法來做到這一點?
如果在我的monad堆棧中會引入
ReaderT
會發生什麼?鑑於SqlPersistT
真的是ReaderT
我如何確保ask
與真正的ReaderT
匹配,而不是SqlPersistT
?