我一直试图想出一种简单直观的方法来使用
Haskell数据库.我从
Yesod book中获取了这些代码,并尝试将其清理干净,以便更容易理解和使用.
{-# 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
updateDB“Frank Silver”40的类型被推断为IO(),因为这是main的默认类型(对于某些a,它必须具有类型IO a).但是从定义来看,它的类型被推断为MonadRescource m => m a for some a(可能是a =(),但我不确定),并且没有实例MonadResource IO.因此,您需要将updateDB转换为IO操作,正常的方法是runResourceT,它将ResourceT m a转换为m a(此处为m = IO),因此
main = runResourceT $updateDB "Frank Silver" 40
作品.