haskell - How to use persistent in a monad stack? -
I'm enjoying learning Haskell and I think I'm making some good progress here with the help of people and #hoschelles. My studies are still mostly on this point where I look at examples and try to apply the techniques that apply to them and apply to my code.
Currently, I have monade piles for various applications and I'm looking to incorporate the functionality of consistent structure in my application. Here's my monade stack:
newtype app a = app {unApp :: StateT AppState (SqlPersistT (ResourceT (LoggingT IO))} deriving (functional, Function, Monad, MonadIO, MonadState AppState)
AppState
There is only one record data type in this example, there is also a single value.
My main function looks like this:
main = runApp "./test.sqlite" (AppState 69) runmigrate
Where runApp
should open all monuments:
runup :: text - & gt; Upstate - & gt; App A - & gt; IO RunAppleTrSource with runAppTs = runStdoutLoggingT RunResourceT RunSqlConn flip evalStateT S UnApp
and RunMeget
to run in app
moded In this case I was shooting to get it to run the migration:
runmegate :: app () runmigrate = return $ liftPersist $ runMigration migrateAll
The compiler tells me that I do not know what I'm doing with the complaint:
Main.lhs: 59: 16 type 'm0 ()' with '() 'Expected type: a () Actual Type: App (M ((M (()) In Expression: Refund $ lift lift $ migrate runmanagement In an equation for 'runmegate': runMigrate = return $ liftPersist $ runMigration migrateAll
Question:
-
What is the correct way to do this?
-
What if I had a < Code> ReaderT ? Seeing how
SqlPersistT
is actually aReaderT
how can I make sure thatask
is actually < Match with code> ReaderT Is notSqlPersistT
?
For your first question: return
Not the right thing --- The point of this return
is that return x
does not work for your mood and just gives a value I think You probably want to:
runmigrate = app $ lift $ runMigration migrateAll
app
your newtype
Definitions in your mind; StateT
in wrapping lift
lifting persistT
.
(Incidentally, I recommend naming AppLife RunMigration
as it is like runMigrationApp
, if you are using it a lot .)