持久性selectList导致错误“无法匹配类型'BaseBackend backend0'与'SqlBackend'”

时间:2017-05-29 20:06:47

标签: haskell haskell-persistent

我遇到了以下编译错误:

• Couldn't match type ‘BaseBackend backend0’ with ‘SqlBackend’
    arising from a use of ‘runSqlite’
  The type variable ‘backend0’ is ambiguous
• In the expression: runSqlite ":memory:"
  In the expression:
    runSqlite ":memory:"
    $ do { records <- selectList [UserUsername ==. "abc"] [LimitTo 10];
           liftIO $ print (records :: [Entity User]) }
  In an equation for ‘selectAll’:
      selectAll
        = runSqlite ":memory:"
          $ do { records <- selectList [UserUsername ==. "abc"] [LimitTo 10];
                 liftIO $ print (records :: [Entity User]) }

代码:

selectAll :: IO ()
selectAll = runSqlite ":memory:" $ do
  records <- selectList [UserUsername ==. "abc"] [LimitTo 10]
  liftIO $ print (records :: [Entity User])

查看runSqlite的类型签名:

runSqlite    
:: (MonadBaseControl IO m, MonadIO m, IsSqlBackend backend)  
=> Text 
-> ReaderT backend (NoLoggingT (ResourceT m)) a 
-> m a

我认为我需要为runSqlite指定一个显式类型,虽然我不太确定我在backend中为ReaderT backend (NoLoggingT (ResourceT m)) a设置了什么?

1 个答案:

答案 0 :(得分:3)

您可以在SqlBackend专门化它。

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

selectAll :: IO ()
selectAll = runSqlite ":memory:" . asSqlBackendReader $ do
  records <- selectList [UserUsername ==. "abc"] [LimitTo 10]
  liftIO $ print (records :: [Entity User])

查看runSqlite的类型,需要满足IsSqlBackend backend约束。

IsSqlBackend的定义是:

type IsSqlBackend backend =
  (IsPersistBackend backend, BaseBackend backend ~ SqlBackend)

然后查找IsPersistBackend

在类的定义之下,我们看到它有三个实例:

instance IsPersistBackend SqlWriteBackend
instance IsPersistBackend SqlReadBackend
instance IsPersistBackend SqlBackend

这三种类型指定具有各种功能的后端,SqlBackend是最常用的(未知功能)。如果您需要的话,请随意使用更受限制的一个。