2017-05-30 36 views
0

我有以下幾點:無法與匹配類型「PersistEntityBackend(實體)「SqlBackend」

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

約束添加到的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)) 
+0

哦,對,缺少的約束也應該是簽名的一部分。我會更新一個解釋。 –

相關問題