Reputation: 603
The following code produces a compile error Couldn't match type ‘PersistEntityBackend U’ with ‘SqlBackend’ arising from a use of ‘insertUser’
due to the commented line:
sampleUser :: Entity User
sampleUser = Entity (toSqlKey 1) $ User
{ userName = "admin"
, userEmail = "[email protected]"
}
type U = Entity User
connectInfo :: MySQLConnectInfo
connectInfo = undefined
runAction :: (MonadUnliftIO m, IsPersistBackend r, BaseBackend r ~ SqlBackend) => MySQLConnectInfo -> ReaderT r (LoggingT m) a -> m a
runAction connectInfo action = runStdoutLoggingT $ withMySQLConn connectInfo $ \backend ->
runReaderT action backend
insertUser :: (PersistEntity U, PersistRecordBackend U SqlBackend) =>
U -> ReaderT SqlBackend (LoggingT IO) (Key U)
insertUser = insert
doDBStuff :: IO ()
doDBStuff = do
runAction connectInfo (runMigration migrateAll)
runAction connectInfo (insertUser sampleUser) -- compile error
return ()
As far as I can see, I've specialized all the types in insertUser
and have added all necessary constraints (having read the related SO question). What am I missing?
Upvotes: 0
Views: 169
Reputation: 603
Asking ghci :info User
gave me the right hint: It shows its class instances. It turns out that it is wrong to use Entity User
directly. I suspect that while this creates the entity, all the class instances generated by Database.Persist.TH.share
are missing from it. Following code compiles, having also removed the redundant constraint as mentioned by Bjartur:
sampleUser :: User
sampleUser = User
{ userName = "admin"
, userEmail = "[email protected]"
}
type U = User
connectInfo :: MySQLConnectInfo
connectInfo = undefined
runAction :: (MonadUnliftIO m, IsPersistBackend r, BaseBackend r ~ SqlBackend) => MySQLConnectInfo -> ReaderT r (LoggingT m) a -> m a
runAction connectInfo action = runStdoutLoggingT $ withMySQLConn connectInfo $ \backend ->
runReaderT action backend
insertUser :: (PersistRecordBackend U SqlBackend) =>
U -> ReaderT SqlBackend (LoggingT IO) (Key U)
insertUser = insert
doDBStuff :: IO ()
doDBStuff = do
runAction connectInfo (runMigration migrateAll)
runAction connectInfo (insertUser sampleUser) -- compile error fixed
return ()
Upvotes: 0
Reputation: 804
You have a PersistRecordBackend U SqlBackend
constraint I don't know if you need, but I suspect you need a PersistEntityBackend U ~ SqlBackend
constraint for insertUser
. Or so the compiler suggests.
See Couldn't match type ‘PersistEntityBackend (Entity a)’ with ‘SqlBackend’
Upvotes: 0