2013-02-23 10 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 } 

正しい方向に私を指し示す提案があれば幸いです。

main = do 
    updateDB "Frank Silver" 40 

+1

'main'の' updateDB'の周りに少なくとも 'runResourceT 'が必要です。私はそれが十分であるかどうかは分かりません。 –

+0

runResourceT $ updateDB "Frank Silver" 40として行を書き直しました!ありがとうございました。あなたは答えとしてあなたのコメントを投稿したいでしょうか? –

+4

私はこの問題を永続的にも使用していましたが、私はMonadLoggerのIO欠落のインスタンスにもエラーがありました。私はそれが他の貧しい人々を助けることを期待してここに残しています。キーは 'runResourceTを使うことです。 Control.Monad.Logger.runNoLoggingT'がMonadLogger IOのインスタンスとして削除されました。 – Khanzor

答えて

8

ことがmainのデフォルトタイプ(それはいくつかのa用タイプIO aを持っている必要があります)ですので、updateDB "Frank Silver" 40の種類は、IO()と推定されます。しかし、その定義から、そのタイプは(おそらくa =()ですが、わかりません)のためにMonadRescource m => m aと推測され、instance MonadResource IOはありません。あなたはIOアクションにupdateDBを変換するために何かを必要とするので、それを行うための通常の方法は、m a(ここではm = IO)へResourceT m aを変換しているので、

main = runResourceT $ updateDB "Frank Silver" 40 

作品runResourceTです。

+0

私はHaskellをほぼ1年間使ってきましたが、私はまだ型システムの使い方を学んでいます。 :Dあなたの助けと返信をもう一度感謝します。 –

関連する問題