2013-02-23 80 views
8

我一直在想出一個簡單而直觀的方式來使用Haskell數據庫。我已從Yesod book中獲取此代碼,並嘗試進行清理,以便更易於理解和使用。Haskell/Persistent-Sqlite:「沒有(Control.Monad.Trans.Resource.MonadResource IO)的實例」

{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings #-} 
{-# LANGUAGE GADTs, FlexibleContexts #-} 

import Database.Persist 
import Database.Persist.Sqlite (withSqliteConn, runSqlConn, runMigration) 
import Database.Persist.TH (share, mkPersist, mkMigrate, sqlSettings, persist) 

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist| 
Person        -- Table name 
    name String      -- String value 
    age Int Maybe     -- Numerical value 
|] 

updateDB x y = withSqliteConn "data.db" $ runSqlConn $ do 
    runMigration migrateAll   -- Creates "Person" table if one doesn't exist 
    insert $ Person x $ Just y  -- Inserts values into .db file 

main = do 
    updateDB "Frank Silver" 40  -- adds name "Frank Silver" and age "40" to data.db file 

此代碼幾乎的作品,但我得到了下面的錯誤,我一直沒能解決。

No instance for (Control.Monad.Trans.Resource.MonadResource IO) 
     arising from a use of `updateDB' 
    Possible fix: 
     add an instance declaration for 
     (Control.Monad.Trans.Resource.MonadResource IO) 
    In a stmt of a 'do' block: updateDB "Frank Silver" 40 
    In the expression: do { updateDB "Frank Silver" 40 } 
    In an equation for `main': main = do { updateDB "Frank Silver" 40 } 

任何建議指出我在正確的方向將不勝感激。

+1

你至少需要''main'中'updateDB'的'runResourceT'。不過,我不確定這是否足夠。 – 2013-02-24 00:01:09

+0

將行重寫爲runResourceT $ updateDB「Frank Silver」40工作!謝謝。也許你想發表你的評論作爲答案? – 2013-02-24 00:07:28

+4

我有這個問題使用持久性,但我也有一個MonadLogger的IO缺失實例的錯誤。我希望它能幫助其他可憐的靈魂。關鍵是使用'runResourceT。 Control.Monad.Logger.runNoLoggingT',因爲MonadLogger IO的實例已被刪除。 – Khanzor 2013-05-28 21:56:06

回答

8

隨着

main = do 
    updateDB "Frank Silver" 40 

updateDB "Frank Silver" 40類型被推斷爲IO(),因爲這是爲main(它必須有一些aIO a)的默認類型。但是從定義來看,其類型推斷爲MonadRescource m => m a對於某些a(可能是a =(),但我不確定),並且沒有instance MonadResource IO。所以,你需要的東西到updateDB轉變成IO行動,以正常的方式做到這一點是runResourceT,其將一個ResourceT m am a(這裏m = IO),所以

main = runResourceT $ updateDB "Frank Silver" 40 

作品。

+0

我一直在使用Haskell近一年,我仍然在學習如何使用類型系統。 :D再次感謝您的幫助和答覆。 – 2013-02-24 01:51:14