haskell Database.PersistentでMySQL使おうとしてハマってた

HaskellでJSON Web APIを作ると幸せになれるかもよを見て、これはすごい!早速作ってみようと意気込んで取り組んだもののハマってハマって仕方がなかった

SqliteじゃなくてMySQL使おうと思ったんだけど、エラーが出続ける

persistent.hs:49:5:
    No instance for (Control.Monad.Logger.MonadLogger IO)
      arising from a use of `runMigration'
    Possible fix:
      add an instance declaration for
      (Control.Monad.Logger.MonadLogger IO)
    In a stmt of a 'do' block: runMigration migrateAll
    In the second argument of `($)', namely
      `do { runMigration migrateAll;
            johnId <- insert $ Person "John Doe" $ Just 32;
            john <- get johnId;
            liftIO $ print (john :: Maybe Person);
            .... }'
    In a stmt of a 'do' block:
      runDB pool
      $ do { runMigration migrateAll;
             johnId <- insert $ Person "John Doe" $ Just 32;
             john <- get johnId;
             liftIO $ print (john :: Maybe Person);
             .... }
 
persistent.hs:50:15:
    No instance for (MonadResource IO) arising from a use of `insert'
    Possible fix: add an instance declaration for (MonadResource IO)
    In the expression: insert
    In a stmt of a 'do' block:
      johnId <- insert $ Person "John Doe" $ Just 32
    In the second argument of `($)', namely
      `do { runMigration migrateAll;
            johnId <- insert $ Person "John Doe" $ Just 32;
            john <- get johnId;
            liftIO $ print (john :: Maybe Person);
            .... }'

調べたところ、monad-logger-0.3.0から(?)はMonadLogger IOのinstanceがないみたい。

http://stackoverflow.com/questions/15448206/yesod-exitfailure-1-when-installing-scaffolded-app/16886380

ここを見て、mysql-loggerのバージョンを下げてみようとしたり、無理矢理instanceにしようとしてみたり色々したけどさっぱりできず。

改めて色々調べると

http://stackoverflow.com/questions/15448206/yesod-exitfailure-1-when-installing-scaffolded-app/16886380#16886380

runHogeLoggingTを使えって書いてある。

とりあえずrunNoLoggingTを試すが、

persistent.hs:50:18:
    Couldn't match type `SqlPersistT m0'
                  with `NoLoggingT (SqlPersistT IO)'
    Expected type: Migration (NoLoggingT (SqlPersistT IO))
      Actual type: Migration (SqlPersistT m0)
    In the first argument of `runMigration', namely `migrateAll'
    In a stmt of a 'do' block: runMigration migrateAll
    In the second argument of `($)', namely
      `do { runMigration migrateAll;
            johnId <- insert $ Person "John Doe" $ Just 32;
            john <- get johnId;
            liftIO $ print (john :: Maybe Person);
            .... }'

となってしまってダメ。

僕にはまだ早かったと諦めかけて、githubで調べてみることにした。

githubでrunNoLoggingT MySQLと調べると!

出てきた!

https://github.com/osak/Kogarasi/blob/9211b813a2e2c6b8c74386941da42715151a60c6/DBSetting.hs

先人は偉大なり!

runSQLAction :: SqlPersistT (ResourceT (NoLoggingT IO)) a -> IO a
runSQLAction = runNoLoggingT . runResourceT . withMySQLConn connectInfo . runSqlConn

なるほど、こういうふうに使うのね・・・

というのがわかって無事DBにつなぐことができたとさ。