Haskell / Persistent-Sqlite:“没有用于(Control.Monad.Trans.Resource.MonadResource IO)的实例” [英] Haskell / Persistent-Sqlite: "No instance for (Control.Monad.Trans.Resource.MonadResource IO)"

查看:148
本文介绍了Haskell / Persistent-Sqlite:“没有用于(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)的实例
由于使用`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 = IO ),因此

  main = 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 be IO (), since that's the default type for main (it must have type IO a for some a). But from the definition, its type is inferred to be MonadRescource m => m a for some a (probably a = (), but I'm not sure), and there is no instance MonadResource IO. So you need something to transform the updateDB to an IO action, the normal way to do that is runResourceT, which transforms a ResourceT m a into an m a (here m = IO), so

main = runResourceT $ updateDB "Frank Silver" 40

works.

这篇关于Haskell / Persistent-Sqlite:“没有用于(Control.Monad.Trans.Resource.MonadResource IO)的实例”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆