I have a function that looks like this
app ::
( MonadReader Config m
, Weather m
, Console m
, MonadError Error m
, MonadState Requests m
)
=> m ()
app = do
host <- fetchHost
port <- fetchPort
pLine $ "Running using service " ++ host ++ ":" ++ show port
forever askAndFetch
it used to run on a StateT ReaderT ExceptT IO and everything was fine
main = do
let config = Config "host" 8080
(runExceptT $ runReaderT (evalStateT app Map.empty) config ) >>= handleErrors
where
handleErrors :: Either Error () -> IO ()
but know I want to remove StateT and provide the MonadState via ReaderT TVar like this
instance (MonadIO m, MonadReader (TVar s) m) => (MonadState s m) where
put s = void $ ask >>= (\tv -> liftIO $ atomically $ swapTVar tv s)
get = ask >>= (liftIO.readTVarIO)
but when I get to the main function, which I changed to look like
main = do
let config = Config "host" 8080
tvar <- newTVarIO (Map.empty :: Requests)
(runExceptT $ runReaderT (runReaderT app config) tvar) >>= handleErrors
where
handleErrors :: Either Error () -> IO ()```
I get
Overlapping instances for MonadState
Requests
(ReaderT Config (ReaderT (TVar Requests) (ExceptT Error IO)))
arising from a use of 'app'
Matching instances:
instance [safe] (MonadIO m, MonadReader (TVar s) m) =>
MonadState s m
-- Defined in 'TaglesFinalApp'
...plus one instance involving out-of-scope types
instance [safe] MonadState s m => MonadState s (ReaderT r m)
-- Defined in 'Control.Monad.State.Class'
Why does it look up for the instance in Control.Monad.State.Class, I’m not asking it to 🙂
btw my imports
import Control.Monad.Trans.Except
import Control.Concurrent.STM.TVar
import qualified Data.Map.Strict as Map