Skip to content

Instantly share code, notes, and snippets.

@EncodePanda
Created November 13, 2018 11:22
Show Gist options
  • Select an option

  • Save EncodePanda/afe05d84d0bf773919efacbf759c9fdc to your computer and use it in GitHub Desktop.

Select an option

Save EncodePanda/afe05d84d0bf773919efacbf759c9fdc to your computer and use it in GitHub Desktop.

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 :slightly_smiling_face:
btw my imports

```import Control.Monad.Reader
import Control.Monad.Trans.Except
import Control.Concurrent.STM.TVar
import qualified Data.Map.Strict as Map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment