Skip to content

Addition of Reader interface#70

Closed
lehins wants to merge 1 commit intointerface-to-performancefrom
reader
Closed

Addition of Reader interface#70
lehins wants to merge 1 commit intointerface-to-performancefrom
reader

Conversation

@lehins
Copy link
Copy Markdown
Collaborator

@lehins lehins commented Apr 3, 2020

No description provided.

@lehins
Copy link
Copy Markdown
Collaborator Author

lehins commented Apr 3, 2020

This PR essentially allows us to forget about passing around the generator and ability to grab it from the reader environment. Here are some examples:

internalMutability :: 
  (HasGen env g, MonadReader env m, MonadRandom g m, PrimMonad m) => m Word
internalMutability = do
  w1  <- uniformEnvM
  ref <- newMutVar w1
  w2  <- uniformEnvM
  modifyMutVar' ref (+w2)
  readMutVar ref


data App = App
  { appGen :: MutGen RealWorld StdGen
  , appDbConnection :: () -- hypothetical
  }

instance HasGen App (MutGen RealWorld StdGen) where
  getGen = appGen


runApp :: App -> ReaderT App m a -> m a
runApp app action = runReaderT action app

data AppPure = AppPure
  { appPureGen :: PureGen StdGen
  , appPureDbConnection :: () -- hypothetical
  }

instance HasGen AppPure (PureGen StdGen) where
  getGen = appPureGen

runAppPure :: AppPure -> ReaderT AppPure m a -> m a
runAppPure app action = runReaderT action app

main :: IO ()
main = do
  let g = mkStdGen 217

  gen <- thawGen $ MutGen g
  runApp (App gen ()) $ do
    v <- internalMutability
    liftIO $ print v
  runReaderT (internalMutability >>= liftIO . print) gen

  runGenStateT_ g $ \pg -> runAppPure (AppPure pg ()) $ do
    v1 <- internalMutability
    liftIO $ print v1
    v2 <- internalMutability
    liftIO $ print v2

  let (v1, v2) =
        runST $ runGenStateT_ g $ \pg -> runAppPure (AppPure pg ()) $ do
          v1' <- internalMutability
          v2' <- internalMutability
          pure (v1', v2')
  print v1 >> print v2

Runnnig this produces:

λ> main
13567046000262619
2533773515975174092
13567046000262619
2533773515975174092
13567046000262619
2533773515975174092

@lehins lehins changed the base branch from instances-and-warnings to interface-to-performance April 4, 2020 20:11
@lehins lehins changed the title Addition of Reader interface WIP: Addition of Reader interface Apr 6, 2020
@curiousleo
Copy link
Copy Markdown
Collaborator

This looks like it allows users to avoid boilerplate if they are using the ReaderT pattern. I'm unsure if that means this should be included here - as an alternative, we could describe how to do this in the documentation.

I've raised a similar point at other occasions. My feeling is that as a core library, random should strive to be minimal and conservative just because of the sheer number of transitive dependencies in the Haskell ecosystem. Any code we add has a maintenance cost, which must be weighed against its benefits.

@lehins lehins changed the title WIP: Addition of Reader interface Addition of Reader interface Apr 8, 2020
@lehins
Copy link
Copy Markdown
Collaborator Author

lehins commented Apr 8, 2020

@curiousleo I am certainly OK with not including this by default and instead make another library handle this case. rio would be the best place for such functionality. That being said, I'd rather not clutter documentation with functionality that random is not planning on supporting.

Closing this PR, but just in case someone complains again about an extra argument to monadic functions being a problem you can point them to this PR ;)

@lehins lehins closed this Apr 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants