9

Haskell でデータベースを使用するためのシンプルで直感的な方法を考え出そうとしてきました。このコードはYesod ブックから引用し、理解しやすく、使いやすいようにクリーンアップしようとしました。

{-# 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 }

私を正しい方向に向ける提案は大歓迎です。

4

1 に答える 1

9

main = do
    updateDB "Frank Silver" 40

の型は でupdateDB "Frank Silver" 40あると推測されますIO ()。これは の既定の型であるためです(一部のmainには型が必要です)。しかし、定義から、そのタイプは一部のものであると推測され(おそらく、しかし私にはわかりません)、 はありません。したがって、 をアクションに変換する何かが必要です。これを行う通常の方法は、 aを(ここでは) に変換することです。IO aaMonadRescource m => m aaa = ()instance MonadResource IOupdateDBIOrunResourceTResourceT m am am = IO

main = runResourceT $ updateDB "Frank Silver" 40

動作します。

于 2013-02-24T00:13:23.260 に答える