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)
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 }
Любые предложения, указывающие мне в правильном направлении, будут оценены.
1 ответ
С
main = do
updateDB "Frank Silver" 40
тип updateDB "Frank Silver" 40
предполагается, что IO ()
, так как это тип по умолчанию для main
(должен иметь тип IO a
для некоторых a
). Но из определения, его тип выводится как MonadRescource m => m a
для некоторых a
(наверное a = ()
но я не уверен) а нет instance MonadResource IO
, Так что вам нужно что-то, чтобы преобразовать updateDB
для IO
действие, нормальный способ сделать это runResourceT
, который превращает ResourceT m a
в m a
(Вот m = IO
), так
main = runResourceT $ updateDB "Frank Silver" 40
работает.