无法将'PersistEntityBackend(实体a)'与'SqlBackend'匹配

时间:2017-05-30 21:38:29

标签: haskell haskell-persistent

我有以下内容:

asSqlBackendReader :: ReaderT SqlBackend m a -> ReaderT SqlBackend m a
asSqlBackendReader = id

insertEnt :: (Entity a) -> IO (Key (Entity a))
insertEnt x = runWithDb $ do
  insert $ x
  where runWithDb = runSqlite "test.db" . asSqlBackendReader

asSqlBAckendReader的目的是Persistent selectList causing error of "Couldn't match type ‘BaseBackend backend0’ with ‘SqlBackend’"

我遇到了以下错误:

• Couldn't match type ‘PersistEntityBackend (Entity a)’
                 with ‘SqlBackend’
    arising from a use of ‘insert’
• In a stmt of a 'do' block: insert $ x
  In the second argument of ‘($)’, namely ‘do { insert $ x }’
  In the expression: runWithDb $ do { insert $ x }

1 个答案:

答案 0 :(得分:1)

将约束添加到insertEnt的签名中。您还需要PersistEntity约束。

insertEnt
  :: ( PersistEntity (Entity a)
     , PersistEntityBackend (Entity a) ~ SqlBackend)
  => Entity a -> IO (Key (Entity a))

要推断出(除了给编译器间接询问的内容),你可以看一下the type of insert

insert
  :: ( PersistStoreWrite backend
     , MonadIO m
     , PersistRecordBackend record backend)
  => record -> ReaderT backend m (Key record)

我们也有

type PersistRecordBackend record backend =
  ( PersistEntity record
  , PersistEntityBackend record ~ BaseBackend backend)

此外,在您的应用程序中,您有一些具体的类型:

backend ~ SqlBackend
m ~ (some concrete transformer stack on top of IO)
record ~ Entity a

这些具体类型会释放PersistStoreWrite backendMonadIO m,并且由于Entity a仍然主要是抽象的,因此您将留下定义PersistRecordBackend的两个约束。事实上,您可以将该同义词用作简写:

insertEnt
  :: PersistRecordBackend (Entity a) SqlBackend
  => Entity a -> IO (Key (Entity a))