Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added MonadUI typeclass #173

Merged
merged 1 commit into from Apr 25, 2017

Conversation

jerbaroo
Copy link
Contributor

@jerbaroo jerbaroo commented Apr 12, 2017

This is related to using a custom monad stack.

I have found using a custom monad stack useful for storing Behaviors, such that one part of the application can easily emit a new value, or some other part of the application sink that value. Simply by ask ing for the necessary function.

-- |Monad the app runs in.
type FooMonad a = ReaderT Env UI a

-- | Enironment/config the app requires.
data Env = Env {
  , eBarBehavior :: Behavior (Maybe String)
  , eBarEmit     :: Handler  (Maybe String)
  ...
  }

I also use a custom monad stack for a unique ID generator.

-- |Return a unique ID.
uniqueId :: FooMonad String
uniqueId = do
  mId <- eId <$> ask
  id' <- liftIO $ MV.modifyMVar mId (\i -> return (i + 1, i))
  return $ "__unique-id-" ++ show id'

The problem with the approach in #161 is if I choose to edit my monad stack then I'll have to change all uses of lift to perhaps lift $ lift -- and using lift doesn't scale well with the amount of stacked monads. It's easier to make the custom monad stack an instance of MonadUI and use liftUI instead of lift, then if my monad stack changes in the future I will only have to edit the instance of MonadUI, instead of all the uses of lift.

@HeinrichApfelmus
Copy link
Owner

Thanks! I have to admit that I'm not particularly happy that this class is necessary, but it probably can't be helped. In particular, the alternative — everybody implements their own version of MonadUI — is definitely worse. Merged!

@jmickelin
Copy link

I'd like to mention that using liftBase with an instance for MonadBase UI UI from https://hackage.haskell.org/package/transformers-base is an alternative, and arguably cleaner, solution, and comes with instances for all the common transformers for free.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants