1

servantとライブラリの両方を使用しpersistentて 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)

insertUniqueasの結果をタイプヒントしようとしましSqlBackendたが、同様に紛らわしいエラーが発生します。SqlBackendPersistentEntityBackendタイプは互換性がありませんか?

それとも、モナドの形式が間違っているのでしょうか?

どんな援助も大歓迎です。

4

1 に答える 1

1

this answerの助けを借りてそれを理解することができました。

getなどと同様に、このコンテキストでは ではなくinsertUniqueプレーンを返します。UserEntity 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

于 2016-11-23T06:07:39.573 に答える