Монада Haskell RIO внутри постоянной с пулом

Аналогичный вопрос: Haskell/Persistent-Sqlite: нет экземпляр для (Control.Monad.Trans.Resource.MonadResource IO)

Я пытаюсь использовать selectSource из persistent для чтения базы данных в потоковом режиме и регистрации значений в консоли с помощью logInfo.

Следующие фрагменты выполняются в шаблоне проекта RIO.

Следующий код содержит части, которые работают и не работают.

{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE EmptyDataDecls             #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE QuasiQuotes                #-}
{-# LANGUAGE StandaloneDeriving         #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE UndecidableInstances       #-}
module Disambiguate.People where

import           Data.Conduit
import qualified Data.Conduit.List       as CL
import           Database.Persist
import           Database.Persist.Sqlite
import           Database.Persist.TH
import           Import                  hiding (on, (^.))
import           Prelude                 (print)

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
    name String
    age Int
    deriving Show
|]

disambiguatePeople :: RIO App ()
disambiguatePeople = do
  -- WORKS!
  runSqlite ":memory:" insertAndRead

  -- DOES NOT COMPILE!
  withSqlitePool ":memory:" 1 $ \pool -> do
    liftSqlPersistMPool insertAndRead pool

 where
  insertAndRead = do
    runMigration migrateAll

    insert_ $ Person "John Doe" 35
    insert_ $ Person "Jane Doe" 50

    runConduit $ selectSource [PersonAge >. 5] [] .| CL.mapM_
      (lift . logInfo . displayShow)

Я получаю следующую ошибку:

src/Run.hs:37:25: error:
    • Couldn't match type ‘RIO App’ with ‘IO’
      Expected type: ReaderT
                       SqlBackend
                       (monad-logger-0.3.35:Control.Monad.Logger.NoLoggingT
                          (Control.Monad.Trans.Resource.Internal.ResourceT IO))
                       ()
        Actual type: ReaderT
                       SqlBackend
                       (monad-logger-0.3.35:Control.Monad.Logger.NoLoggingT
                          (Control.Monad.Trans.Resource.Internal.ResourceT (RIO App)))
                       ()
    • In the first argument of ‘liftSqlPersistMPool’, namely
        ‘insertAndRead’
      In a stmt of a 'do' block: liftSqlPersistMPool insertAndRead pool
      In the expression: do liftSqlPersistMPool insertAndRead pool
   |
37 |     liftSqlPersistMPool insertAndRead pool
   |                         ^^^^^^^^^^^^^

Я понимаю ошибку, так как функция liftSqlPersistMPool жестко запрограммировала тип IO.

Как я могу решить эту проблему, чтобы использовать ее с типом RIO?


person Konstantinos    schedule 17.10.2020    source источник
comment
Вероятно, вам придется применить среду к действию RIO, чтобы превратить его в действие IO. Вероятно, есть причудливые способы сделать это с помощью MonadUnliftIO или MinadBaseControl или чего-то еще, но вы также можете просто сделать это вручную.   -  person dfeuer    schedule 18.10.2020