Haskell / Persistent-Sqlite:“没有用于(Control.Monad.Trans.Resource.MonadResource IO)的实例” [英] Haskell / Persistent-Sqlite: "No instance for (Control.Monad.Trans.Resource.MonadResource IO)"
问题描述
我一直在想出一个简单直观的方法来使用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)
共享[mkPersist sqlSettings,mkMigratemigrateAll] [persist |
Person - 表名
name String - 字符串值
age Int Maybe - 数值
|]
updateDB xy = withSqliteConndata .db$ runSqlConn $ do
runMigration migrateAll - 创建Person表(如果不存在)
insert $ Person x $只是y - 将值插入到.db文件中
main = do
updateDBFrank Silver40 - 为data.db文件添加名称Frank Silver和年龄40
此代码几乎可以正常工作,但我收到以下错误,我无法解决。
没有(Control.Monad.Trans.Resource.MonadResource IO)的实例
$ p $
由于使用`updateDB'
可能的修复:
为
添加一个实例声明(Control.Monad.Trans.Resource.MonadResource IO)
在'do'块的一个stmt:updateDBFrank Silver40
在表达式:do {updateDBFrank Silver40}
在'main'的等式中:main = do {updateDBFrank Silver40}
解决方案任何建议指向正确的方向。
main = do
updateDBFrank Silver40
updateDB的类型Frank Silver40
被推断为IO ($
(
)对于某些
),因此a
)。但是从定义,它的类型被推断为MonadRescource m => ma
对于一些a
(可能a =()
,但我不确定),并且没有实例MonadResource IO
。所以你需要一些东西来将updateDB
转换为IO
操作,正常的做法是runResourceT
,它将ResourceT ma
转换为ma
$ c> m = IOmain = runResourceT $ updateDBFrank Silver40
有效。
I've been trying to come up with a simple and intuitive way to use databases with Haskell. I've taken this code from the Yesod book and tried to clean it up so that it can be easier to understand and use.
{-# 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
This code almost works, but I get the following error which I haven't been able to resolve.
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 }
Any suggestions pointing me in the right direction would be appreciated.
解决方案With
main = do updateDB "Frank Silver" 40
the type of
updateDB "Frank Silver" 40
is inferred to beIO ()
, since that's the default type formain
(it must have typeIO a
for somea
). But from the definition, its type is inferred to beMonadRescource m => m a
for somea
(probablya = ()
, but I'm not sure), and there is noinstance MonadResource IO
. So you need something to transform theupdateDB
to anIO
action, the normal way to do that isrunResourceT
, which transforms aResourceT m a
into anm a
(herem = IO
), somain = runResourceT $ updateDB "Frank Silver" 40
works.
这篇关于Haskell / Persistent-Sqlite:“没有用于(Control.Monad.Trans.Resource.MonadResource IO)的实例”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!