numberten / zhenya_bot

irc bot and official Haskell feature creep
Other
5 stars 1 forks source link

Generalize stateful, et al. to allow for stacking multiple Monad Transformers. #4

Closed fimad closed 11 years ago

fimad commented 11 years ago

Currently the type for stateful is stateful :: (String -> StateT s Bot ()) -> Bot s -> Bot BotComponent

It would be nice to have something like statefulT :: MonadBot b => (String -> StateT s b ()) -> b s -> Bot BotComponent

This would allow for stacking multiple stateful components in the way that commandT does. It would be nice if the solution allowed component combinators to work on these more complex bot components.

fimad commented 11 years ago

Idea for how to define MonadBot and Component.

class MonadBot b where -- | Anything required to turn an instance of b a into Bot a data MonadBotDrop b :: *

-- | Similar to liftIO liftBot :: Bot a -> b a

-- | Escape out of the monad tranformer stack down to a plain ol' Bot monadic value dropBot :: MonadBotDrop b -> b a -> Bot a

-- | A component is any function that takes a String and returns a Component in a MonadBot, along with a value that is able to drop the b Component value down to a Bot a newtype Component b = Component (MonadBotDrop b, String -> b Component)

-- | Then statefulT can have the following type? statefulT :: MonadBot b => (String -> StateT s b ()) -> Bot s -> Component (StateT s b)

instance MonadBot b => MonadBot (StateT s b) where data MonadBotDrop (StateT s b) = (MonadBotDrop b, s) -- and so on

fimad commented 11 years ago

Implemented.

Added a ComponentPart type that can be stacking using the >>+ combinator.

See fizzBuzz in Loop.hs for an example.