Не удалось сопоставить тип «PersistEntityBackend U» с «SqlBackend» - PullRequest
0 голосов
/ 19 февраля 2020

Следующий код выдает ошибку компиляции Couldn't match type ‘PersistEntityBackend U’ with ‘SqlBackend’ arising from a use of ‘insertUser’ из-за закомментированной строки:

sampleUser :: Entity User
sampleUser = Entity (toSqlKey 1) $ User
  { userName = "admin"
  , userEmail = "admin@test.com"
  }

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 ()

Насколько я вижу, я специализировал все типы в insertUser и добавил все необходимые ограничения (прочитав связанный вопрос SO ). Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

Задавая ghci :info User дал мне правильный совет: он показывает свои экземпляры классов. Оказывается, неправильно использовать Entity User напрямую. Я подозреваю, что, хотя это создает сущность, все экземпляры класса, сгенерированные Database.Persist.TH.share, отсутствуют в нем. Следующий код компилируется, также удалив избыточное ограничение, как упомянуто Bjartur:

sampleUser :: User
sampleUser = User
  { userName = "admin"
  , userEmail = "admin@test.com"
  }

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 ()
0 голосов
/ 19 февраля 2020

У вас есть ограничение PersistRecordBackend U SqlBackend. Я не знаю, нужно ли вам это, но я подозреваю, что вам нужно ограничение PersistEntityBackend U ~ SqlBackend для insertUser. Или так предлагает компилятор.

См. Не удалось сопоставить тип 'PersistEntityBackend (Entity a)' с 'SqlBackend'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...