如何解决 SqlBackend 和 PersistEntityBackend 之间的类型不匹配?

How to resolve type mismatch between SqlBackend and PersistEntityBackend?

同时使用 servantpersistent 库来创建 REST API 而我 运行 使用 insertUnique 进入类型不匹配错误创建一个新实体。

这是有问题的函数:

createUser :: Entity User -> App Int64
createUser p = do
    maybeNewUser <- runDb (insertUnique (User (userUsername $ entityVal p) (userSpotifyUser $ entityVal p)))
    case maybeNewUser of
        Nothing -> throwError err400
        Just newUser -> return $ fromSqlKey newUser

出现以下错误:

Couldn't match expected type ‘persistent-2.2.4.1:Database.Persist.Sql.Types.SqlBackend’
        with actual type ‘persistent-2.2.4.1:Database.Persist.Class.PersistEntity.PersistEntityBackend
                            (String
                             -> String
                             -> time-1.5.0.1:Data.Time.Clock.UTC.UTCTime
                             -> time-1.5.0.1:Data.Time.Clock.UTC.UTCTime
                             -> User)’
In the first argument of ‘runDb’, namely
[snip]

作为参考,runDb 函数:

runDb :: (MonadReader Config m, MonadIO m) => SqlPersistT IO b -> m b
runDb query = do
    pool <- asks getPool
    liftIO $ runSqlPool query pool

App 新类型:

newtype App a = App
    { runApp :: ReaderT Config (ExceptT ServantErr IO) a } deriving
        (Functor, Applicative, Monad, MonadReader Config, MonadError ServantErr, MonadIO)

我尝试将 insertUnique 的结果类型提示为 SqlBackend,但这会导致同样令人困惑的错误。 SqlBackendPersistentEntityBackend 类型不能互换吗?

或者 monad 格式不正确?

非常感谢任何帮助。

我在 的帮助下弄明白了。

get 和其他人一样,insertUnique 在这种情况下 returns 是普通的 User 而不是 Entity User

createUser :: User -> App Int64
createUser p = do
    user <- (User (userUsername $ entityVal p) (userSpotifyUser $ entityVal p))
    let insertUser = insertUnique user :: SqlPersistT IO (Maybe (Key User))
    maybeNewUserKey <- runDb insertUser
    case maybeNewUserKey of
        Nothing -> throwError err400
        Just newUserKey ->
            return $ fromSqlKey newUserKey

事后看来更有意义,因为 runDb 接受 SqlPersistT 转换后的 monad。