Even more refactoring

master
Abhinav Sarkar 2014-05-25 01:09:31 +05:30
parent 200cc93e1b
commit 816d14109a
11 changed files with 99 additions and 98 deletions

View File

@ -12,7 +12,7 @@ module Network.IRC.Bot
, eventProcessLoop ) , eventProcessLoop )
where where
import qualified Data.Text.Format as TF import qualified Data.Text.Format as TF
import qualified System.Log.Logger as HSL import qualified System.Log.Logger as HSL
import ClassyPrelude import ClassyPrelude
@ -97,10 +97,11 @@ messageProcessLoop lineChan commandChan !idleFor = do
mLine <- readLine lineChan mLine <- readLine lineChan
case mLine of case mLine of
Timeout -> getCurrentTime >>= dispatchHandlers bot . IdleMsg >> return Idle Timeout ->
getCurrentTime >>= \t -> dispatchHandlers bot (Message t "" IdleMsg) >> return Idle
EOF -> infoM "Connection closed" >> return Disconnected EOF -> infoM "Connection closed" >> return Disconnected
Line message -> do Line (message@Message { .. }) -> do
nStatus <- case message of nStatus <- case msgDetails of
JoinMsg { .. } | userNick user == nick -> infoM "Joined" >> return Joined JoinMsg { .. } | userNick user == nick -> infoM "Joined" >> return Joined
KickMsg { .. } | kickedNick == nick -> infoM "Kicked" >> return Kicked KickMsg { .. } | kickedNick == nick -> infoM "Kicked" >> return Kicked
NickInUseMsg { .. } -> NickInUseMsg { .. } ->

View File

@ -35,31 +35,32 @@ mkMsgHandler botConfig eventChan name =
flip (`foldM` Nothing) [ Logger.mkMsgHandler flip (`foldM` Nothing) [ Logger.mkMsgHandler
, SongSearch.mkMsgHandler , SongSearch.mkMsgHandler
, Auth.mkMsgHandler , Auth.mkMsgHandler
, NickTracker.mkMsgHandler ] , NickTracker.mkMsgHandler ] $ \handlers handler ->
$ \acc h -> case acc of case handlers of
Just _ -> return acc Just _ -> return handlers
Nothing -> h botConfig eventChan name Nothing -> handler botConfig eventChan name
pingPong :: MonadMsgHandler m => IORef UTCTime -> Message -> m (Maybe Command) pingPong :: MonadMsgHandler m => IORef UTCTime -> Message -> m (Maybe Command)
pingPong state PingMsg { .. } = do pingPong state Message { msgDetails = PingMsg { .. }, .. } = do
io $ atomicWriteIORef state msgTime io $ atomicWriteIORef state msgTime
return . Just $ PongCmd msg return . Just $ PongCmd msg
pingPong state PongMsg { .. } = do pingPong state Message { msgDetails = PongMsg { .. }, .. } = do
io $ atomicWriteIORef state msgTime io $ atomicWriteIORef state msgTime
return Nothing return Nothing
pingPong state IdleMsg { .. } | even (convert msgTime :: Int) = do pingPong state Message { msgDetails = IdleMsg { .. }, .. }
BotConfig { .. } <- ask | even (convert msgTime :: Int) = do
let limit = fromIntegral $ botTimeout `div` 2 BotConfig { .. } <- ask
io $ do let limit = fromIntegral $ botTimeout `div` 2
lastComm <- readIORef state io $ do
if addUTCTime limit lastComm < msgTime lastComm <- readIORef state
then return . Just . PingCmd . pack . formatTime defaultTimeLocale "%s" $ msgTime if addUTCTime limit lastComm < msgTime
else return Nothing then return . Just . PingCmd . pack . formatTime defaultTimeLocale "%s" $ msgTime
else return Nothing
pingPong _ _ = return Nothing pingPong _ _ = return Nothing
greeter :: MonadMsgHandler m => Message -> m (Maybe Command) greeter :: MonadMsgHandler m => Message -> m (Maybe Command)
greeter ChannelMsg { .. } = greeter Message { msgDetails = ChannelMsg { .. }, .. } =
return . map (ChannelMsgReply . (++ userNick user) . (++ " ")) . find (== clean msg) $ greetings return . map (ChannelMsgReply . (++ userNick user) . (++ " ")) . find (== clean msg) $ greetings
where where
greetings = [ "hi", "hello", "hey", "sup", "bye" greetings = [ "hi", "hello", "hey", "sup", "bye"
@ -67,7 +68,7 @@ greeter ChannelMsg { .. } =
greeter _ = return Nothing greeter _ = return Nothing
welcomer :: MonadMsgHandler m => Message -> m (Maybe Command) welcomer :: MonadMsgHandler m => Message -> m (Maybe Command)
welcomer JoinMsg { .. } = do welcomer Message { msgDetails = JoinMsg { .. }, .. } = do
BotConfig { .. } <- ask BotConfig { .. } <- ask
if userNick user /= botNick if userNick user /= botNick
then return . Just . ChannelMsgReply $ "welcome back " ++ userNick user then return . Just . ChannelMsgReply $ "welcome back " ++ userNick user
@ -76,7 +77,7 @@ welcomer JoinMsg { .. } = do
welcomer _ = return Nothing welcomer _ = return Nothing
help :: MonadMsgHandler m => Message -> m (Maybe Command) help :: MonadMsgHandler m => Message -> m (Maybe Command)
help ChannelMsg { .. } help Message { msgDetails = ChannelMsg { .. }, .. }
| "!help" == clean msg = do | "!help" == clean msg = do
BotConfig { .. } <- ask BotConfig { .. } <- ask
let commands = concatMap mapKeys . mapValues $ msgHandlerInfo let commands = concatMap mapKeys . mapValues $ msgHandlerInfo

View File

@ -5,7 +5,7 @@
module Network.IRC.Handlers.Auth (mkMsgHandler) where module Network.IRC.Handlers.Auth (mkMsgHandler) where
import qualified Data.UUID as U import qualified Data.UUID as U
import qualified Data.UUID.V4 as U import qualified Data.UUID.V4 as U
import ClassyPrelude import ClassyPrelude
@ -46,7 +46,7 @@ issueToken acid user = do
-- handler -- handler
authMessage :: MonadMsgHandler m => IORef (AcidState Auth) -> Message -> m (Maybe Command) authMessage :: MonadMsgHandler m => IORef (AcidState Auth) -> Message -> m (Maybe Command)
authMessage state PrivMsg { .. } authMessage state Message { msgDetails = PrivMsg { .. }, .. }
| "token" `isPrefixOf` msg = map (Just . PrivMsgReply user) . io $ | "token" `isPrefixOf` msg = map (Just . PrivMsgReply user) . io $
readIORef state >>= flip issueToken (userNick user) readIORef state >>= flip issueToken (userNick user)
authMessage _ _ = return Nothing authMessage _ _ = return Nothing
@ -70,7 +70,7 @@ authEvent state event = case fromEvent event of
mkMsgHandler :: BotConfig -> Chan SomeEvent -> MsgHandlerName -> IO (Maybe MsgHandler) mkMsgHandler :: BotConfig -> Chan SomeEvent -> MsgHandlerName -> IO (Maybe MsgHandler)
mkMsgHandler BotConfig { .. } _ "auth" = do mkMsgHandler BotConfig { .. } _ "auth" = do
state <- io (openLocalState emptyAuth >>= newIORef) state <- io $ openLocalState emptyAuth >>= newIORef
return . Just $ newMsgHandler { onMessage = authMessage state return . Just $ newMsgHandler { onMessage = authMessage state
, onEvent = authEvent state , onEvent = authEvent state
, onStop = stopAuth state , onStop = stopAuth state

View File

@ -5,12 +5,12 @@
module Network.IRC.Handlers.Auth.Types where module Network.IRC.Handlers.Auth.Types where
import ClassyPrelude import ClassyPrelude
import Data.Data (Data) import Data.Data (Data)
import Data.SafeCopy (base, deriveSafeCopy) import Data.SafeCopy (base, deriveSafeCopy)
import Network.IRC.Types hiding (user) import Network.IRC.Types hiding (user)
type Token = Text type Token = Text
newtype Auth = Auth { auth :: Map Nick Token } deriving (Eq, Show, Data, Typeable) newtype Auth = Auth { auth :: Map Nick Token } deriving (Eq, Show, Data, Typeable)
emptyAuth :: Auth emptyAuth :: Auth

View File

@ -2,8 +2,8 @@
module Network.IRC.Handlers.MessageLogger (mkMsgHandler) where module Network.IRC.Handlers.MessageLogger (mkMsgHandler) where
import qualified Data.Configurator as C import qualified Data.Configurator as C
import qualified Data.Text.Format as TF import qualified Data.Text.Format as TF
import qualified Data.Text.Format.Params as TF import qualified Data.Text.Format.Params as TF
import ClassyPrelude hiding ((</>), (<.>), FilePath, log) import ClassyPrelude hiding ((</>), (<.>), FilePath, log)
@ -73,7 +73,7 @@ withLogFile action state = do
return Nothing return Nothing
messageLogger :: MonadMsgHandler m => Message -> IORef LoggerState -> m (Maybe Command) messageLogger :: MonadMsgHandler m => Message -> IORef LoggerState -> m (Maybe Command)
messageLogger message = case message of messageLogger Message { .. } = case msgDetails of
ChannelMsg { .. } -> log "<{}> {}" [userNick user, msg] ChannelMsg { .. } -> log "<{}> {}" [userNick user, msg]
ActionMsg { .. } -> log "<{}> {} {}" [userNick user, userNick user, msg] ActionMsg { .. } -> log "<{}> {} {}" [userNick user, userNick user, msg]
KickMsg { .. } -> log "** {} KICKED {} :{}" [userNick user, kickedNick, msg] KickMsg { .. } -> log "** {} KICKED {} :{}" [userNick user, kickedNick, msg]
@ -85,6 +85,6 @@ messageLogger message = case message of
_ -> const $ return Nothing _ -> const $ return Nothing
where where
log format args = withLogFile $ \logFile -> log format args = withLogFile $ \logFile ->
TF.hprint logFile ("[{}] " ++ format ++ "\n") $ TF.buildParams (fmtTime (msgTime message) : args) TF.hprint logFile ("[{}] " ++ format ++ "\n") $ TF.buildParams (fmtTime msgTime : args)
fmtTime = pack . formatTime defaultTimeLocale "%F %T" fmtTime = pack . formatTime defaultTimeLocale "%F %T"

View File

@ -5,8 +5,8 @@
module Network.IRC.Handlers.NickTracker (mkMsgHandler) where module Network.IRC.Handlers.NickTracker (mkMsgHandler) where
import qualified Data.IxSet as IS import qualified Data.IxSet as IS
import qualified Data.UUID as U import qualified Data.UUID as U
import qualified Data.UUID.V4 as U import qualified Data.UUID.V4 as U
import ClassyPrelude import ClassyPrelude
@ -40,7 +40,7 @@ saveNickTrack nt = do
$(makeAcidic ''NickTracking ['getByNick, 'getByCanonicalNick, 'saveNickTrack]) $(makeAcidic ''NickTracking ['getByNick, 'getByCanonicalNick, 'saveNickTrack])
nickTrackerMsg :: MonadMsgHandler m => IORef (AcidState NickTracking) -> Message -> m (Maybe Command) nickTrackerMsg :: MonadMsgHandler m => IORef (AcidState NickTracking) -> Message -> m (Maybe Command)
nickTrackerMsg state message = case message of nickTrackerMsg state Message { .. } = case msgDetails of
ChannelMsg { .. } -> updateNickTrack state user msg msgTime >> handleCommands msg ChannelMsg { .. } -> updateNickTrack state user msg msgTime >> handleCommands msg
ActionMsg { .. } -> updateNickTrack state user msg msgTime >> return Nothing ActionMsg { .. } -> updateNickTrack state user msg msgTime >> return Nothing
JoinMsg { .. } -> updateNickTrack state user "" msgTime >> return Nothing JoinMsg { .. } -> updateNickTrack state user "" msgTime >> return Nothing
@ -66,9 +66,7 @@ updateNickTrack state user message msgTime = io $ do
(message', lastMessageOn', cn) <- case (message, mnt) of (message', lastMessageOn', cn) <- case (message, mnt) of
("", Just (NickTrack { .. })) -> return (lastMessage, lastMessageOn, canonicalNick) ("", Just (NickTrack { .. })) -> return (lastMessage, lastMessageOn, canonicalNick)
(_, Just (NickTrack { .. })) -> return (message, msgTime, canonicalNick) (_, Just (NickTrack { .. })) -> return (message, msgTime, canonicalNick)
_ -> do _ -> newCanonicalNick >>= \cn -> return (message, msgTime, cn)
cn <- newCanonicalNick
return (message, msgTime, cn)
update acid . SaveNickTrack $ update acid . SaveNickTrack $
NickTrack (Nick nck) cn (LastSeenOn msgTime) lastMessageOn' message' NickTrack (Nick nck) cn (LastSeenOn msgTime) lastMessageOn' message'
@ -138,7 +136,7 @@ stopNickTracker state = io $ do
mkMsgHandler :: BotConfig -> Chan SomeEvent -> MsgHandlerName -> IO (Maybe MsgHandler) mkMsgHandler :: BotConfig -> Chan SomeEvent -> MsgHandlerName -> IO (Maybe MsgHandler)
mkMsgHandler BotConfig { .. } _ "nicktracker" = do mkMsgHandler BotConfig { .. } _ "nicktracker" = do
state <- io (openLocalState emptyNickTracking >>= newIORef) state <- io $ openLocalState emptyNickTracking >>= newIORef
return . Just $ newMsgHandler { onMessage = nickTrackerMsg state return . Just $ newMsgHandler { onMessage = nickTrackerMsg state
, onStop = stopNickTracker state , onStop = stopNickTracker state
, onHelp = return helpMsgs } , onHelp = return helpMsgs }

View File

@ -4,13 +4,13 @@
module Network.IRC.Handlers.NickTracker.Types where module Network.IRC.Handlers.NickTracker.Types where
import ClassyPrelude import ClassyPrelude
import Data.Data (Data) import Data.Data (Data)
import Data.IxSet (IxSet, Indexable (..), ixSet, ixFun) import Data.IxSet (IxSet, Indexable (..), ixSet, ixFun)
import Data.SafeCopy (base, deriveSafeCopy) import Data.SafeCopy (base, deriveSafeCopy)
newtype Nick = Nick Text deriving (Eq, Ord, Show, Data, Typeable) newtype Nick = Nick Text deriving (Eq, Ord, Show, Data, Typeable)
newtype CanonicalNick = CanonicalNick Text deriving (Eq, Ord, Show, Data, Typeable) newtype CanonicalNick = CanonicalNick Text deriving (Eq, Ord, Show, Data, Typeable)
newtype LastSeenOn = LastSeenOn UTCTime deriving (Eq, Ord, Show, Data, Typeable) newtype LastSeenOn = LastSeenOn UTCTime deriving (Eq, Ord, Show, Data, Typeable)
data NickTrack = NickTrack { data NickTrack = NickTrack {
nick :: !Nick, nick :: !Nick,
@ -25,14 +25,13 @@ instance Indexable NickTrack where
, ixFun $ (: []) . canonicalNick , ixFun $ (: []) . canonicalNick
, ixFun $ (: []) . lastSeenOn ] , ixFun $ (: []) . lastSeenOn ]
newtype NickTracking = NickTracking { nickTracking :: IxSet NickTrack }
deriving (Eq, Ord, Show, Data, Typeable)
$(deriveSafeCopy 0 'base ''Nick) $(deriveSafeCopy 0 'base ''Nick)
$(deriveSafeCopy 0 'base ''CanonicalNick) $(deriveSafeCopy 0 'base ''CanonicalNick)
$(deriveSafeCopy 0 'base ''LastSeenOn) $(deriveSafeCopy 0 'base ''LastSeenOn)
$(deriveSafeCopy 0 'base ''NickTrack) $(deriveSafeCopy 0 'base ''NickTrack)
newtype NickTracking = NickTracking { nickTracking :: IxSet NickTrack }
deriving (Eq, Ord, Show, Data, Typeable)
$(deriveSafeCopy 0 'base ''NickTracking) $(deriveSafeCopy 0 'base ''NickTracking)
emptyNickTracking :: NickTracking emptyNickTracking :: NickTracking

View File

@ -42,7 +42,7 @@ instance FromJSON Song where
parseJSON _ = mempty parseJSON _ = mempty
songSearch :: MonadMsgHandler m => Message -> m (Maybe Command) songSearch :: MonadMsgHandler m => Message -> m (Maybe Command)
songSearch ChannelMsg { .. } songSearch Message { msgDetails = ChannelMsg { .. }, .. }
| "!m " `isPrefixOf` msg = do | "!m " `isPrefixOf` msg = do
BotConfig { .. } <- ask BotConfig { .. } <- ask
liftIO $ do liftIO $ do

View File

@ -1,4 +1,4 @@
module Network.IRC.Protocol (msgFromLine, lineFromCommand) where module Network.IRC.Protocol (MessageParser, msgFromLine, lineFromCommand) where
import ClassyPrelude import ClassyPrelude
import Data.List ((!!)) import Data.List ((!!))
@ -6,25 +6,27 @@ import Data.Text (split, strip)
import Network.IRC.Types import Network.IRC.Types
msgFromLine :: BotConfig -> UTCTime -> Text -> Message type MessageParser = BotConfig -> UTCTime -> Text -> Message
msgFromLine :: MessageParser
msgFromLine (BotConfig { .. }) time line msgFromLine (BotConfig { .. }) time line
| "PING :" `isPrefixOf` line = PingMsg time (drop 6 line) line | "PING :" `isPrefixOf` line = Message time line $ PingMsg (drop 6 line)
| otherwise = case command of | otherwise = case command of
"PONG" -> PongMsg time message line "PONG" -> Message time line $ PongMsg message
"JOIN" -> JoinMsg time user line "JOIN" -> Message time line $ JoinMsg user
"QUIT" -> QuitMsg time user quitMessage line "QUIT" -> Message time line $ QuitMsg user quitMessage
"PART" -> PartMsg time user message line "PART" -> Message time line $ PartMsg user message
"KICK" -> KickMsg time user kicked kickReason line "KICK" -> Message time line $ KickMsg user kicked kickReason
"MODE" -> if source == botNick "MODE" -> if source == botNick
then ModeMsg time Self target message [] line then Message time line $ ModeMsg Self target message []
else ModeMsg time user target mode modeArgs line else Message time line $ ModeMsg user target mode modeArgs
"NICK" -> NickMsg time user (drop 1 target) line "NICK" -> Message time line $ NickMsg user (drop 1 target)
"353" -> NamesMsg time namesNicks "353" -> Message time line $ NamesMsg namesNicks
"433" -> NickInUseMsg time line "433" -> Message time line NickInUseMsg
"PRIVMSG" | target /= channel -> PrivMsg time user message line "PRIVMSG" | target /= channel -> Message time line $ PrivMsg user message
| isActionMsg -> ActionMsg time user (initDef . drop 8 $ message) line | isActionMsg -> Message time line $ ActionMsg user (initDef . drop 8 $ message)
| otherwise -> ChannelMsg time user message line | otherwise -> Message time line $ ChannelMsg user message
_ -> OtherMsg time source command target message line _ -> Message time line $ OtherMsg source command target message
where where
isSpc = (== ' ') isSpc = (== ' ')
isNotSpc = not . isSpc isNotSpc = not . isSpc
@ -40,8 +42,7 @@ msgFromLine (BotConfig { .. }) time line
kicked = splits !! 3 kicked = splits !! 3
kickReason = drop 1 . unwords . drop 4 $ splits kickReason = drop 1 . unwords . drop 4 $ splits
nickPrefixes :: String nickPrefixes = "~&@%+" :: String
nickPrefixes = "~&@%+"
namesNicks = map stripNickPrefix . words . drop 1 . unwords . drop 5 $ splits namesNicks = map stripNickPrefix . words . drop 1 . unwords . drop 5 $ splits
stripNickPrefix = pack . dropWhile (`elem` nickPrefixes) . unpack stripNickPrefix = pack . dropWhile (`elem` nickPrefixes) . unpack

View File

@ -10,6 +10,7 @@ module Network.IRC.Types
, MsgHandlerName , MsgHandlerName
, User (..) , User (..)
, Message (..) , Message (..)
, MessageDetails (..)
, Command (..) , Command (..)
, Event (..) , Event (..)
, SomeEvent , SomeEvent
@ -45,25 +46,25 @@ type MsgHandlerName = Text
data User = Self | User { userNick :: !Nick, userServer :: !Text } data User = Self | User { userNick :: !Nick, userServer :: !Text }
deriving (Show, Eq) deriving (Show, Eq)
data Message = data Message = Message { msgTime :: !UTCTime, msgLine :: !Text, msgDetails :: MessageDetails}
IdleMsg { msgTime :: !UTCTime} deriving (Show, Eq)
| PingMsg { msgTime :: !UTCTime, msg :: !Text, msgLine :: !Text }
| PongMsg { msgTime :: !UTCTime, msg :: !Text, msgLine :: !Text } data MessageDetails =
| ChannelMsg { msgTime :: !UTCTime, user :: !User, msg :: !Text, msgLine :: !Text } IdleMsg
| PrivMsg { msgTime :: !UTCTime, user :: !User, msg :: !Text, msgLine :: !Text } | NickInUseMsg
| ActionMsg { msgTime :: !UTCTime, user :: !User, msg :: !Text, msgLine :: !Text } | PingMsg { msg :: !Text }
| JoinMsg { msgTime :: !UTCTime, user :: !User, msgLine :: !Text } | PongMsg { msg :: !Text }
| QuitMsg { msgTime :: !UTCTime, user :: !User, msg :: !Text, msgLine :: !Text } | NamesMsg { nicks :: ![Nick] }
| PartMsg { msgTime :: !UTCTime, user :: !User, msg :: !Text, msgLine :: !Text } | ChannelMsg { user :: !User, msg :: !Text }
| NickMsg { msgTime :: !UTCTime, user :: !User, newNick :: !Nick, msgLine :: !Text } | PrivMsg { user :: !User, msg :: !Text }
| NickInUseMsg { msgTime :: !UTCTime, msgLine :: !Text } | ActionMsg { user :: !User, msg :: !Text }
| KickMsg { msgTime :: !UTCTime, user :: !User, kickedNick :: !Nick, msg :: !Text | JoinMsg { user :: !User }
, msgLine :: !Text } | QuitMsg { user :: !User, msg :: !Text }
| ModeMsg { msgTime :: !UTCTime, user :: !User, target :: !Text, mode :: !Text | PartMsg { user :: !User, msg :: !Text }
, modeArgs :: ![Text], msgLine :: !Text } | NickMsg { user :: !User, newNick :: !Nick }
| NamesMsg { msgTime :: !UTCTime, nicks :: ![Nick] } | KickMsg { user :: !User, kickedNick :: !Nick, msg :: !Text }
| OtherMsg { msgTime :: !UTCTime, source :: !Text, command :: !Text, target :: !Text | ModeMsg { user :: !User, msgTarget :: !Text, mode :: !Text , modeArgs :: ![Text] }
, msg :: !Text, msgLine :: !Text } | OtherMsg { msgSource :: !Text, msgCommand :: !Text, msgTarget :: !Text , msg :: !Text }
deriving (Show, Eq) deriving (Show, Eq)
data Command = data Command =
@ -113,11 +114,11 @@ data BotConfig = BotConfig { server :: !Text
, config :: !Config } , config :: !Config }
instance Show BotConfig where instance Show BotConfig where
show BotConfig { .. } = "server = " ++ show server ++ "\n" ++ show BotConfig { .. } = "server = " ++ show server ++ "\n" ++
"port = " ++ show port ++ "\n" ++ "port = " ++ show port ++ "\n" ++
"channel = " ++ show channel ++ "\n" ++ "channel = " ++ show channel ++ "\n" ++
"nick = " ++ show botNick ++ "\n" ++ "nick = " ++ show botNick ++ "\n" ++
"timeout = " ++ show botTimeout ++ "\n" ++ "timeout = " ++ show botTimeout ++ "\n" ++
"handlers = " ++ show (mapKeys msgHandlerInfo) "handlers = " ++ show (mapKeys msgHandlerInfo)
data Bot = Bot { botConfig :: !BotConfig data Bot = Bot { botConfig :: !BotConfig
@ -148,11 +149,11 @@ runIRC bot botStatus = flip runReaderT bot . flip execStateT botStatus . _runIRC
-- Message handlers -- Message handlers
newtype MsgHandlerT a = MsgHandlerT { _runMsgHandler :: ReaderT BotConfig IO a } newtype MsgHandlerT a = MsgHandlerT { _runMsgHandler :: ReaderT BotConfig IO a }
deriving ( Functor deriving ( Functor
, Applicative , Applicative
, Monad , Monad
, MonadIO , MonadIO
, MonadReader BotConfig ) , MonadReader BotConfig )
class (MonadIO m, Applicative m, MonadReader BotConfig m) => MonadMsgHandler m where class (MonadIO m, Applicative m, MonadReader BotConfig m) => MonadMsgHandler m where
msgHandler :: MsgHandlerT a -> m a msgHandler :: MsgHandlerT a -> m a

View File

@ -50,7 +50,7 @@ cabal-version: >=1.10
library library
default-extensions: NoImplicitPrelude, OverloadedStrings, RecordWildCards, ScopedTypeVariables, default-extensions: NoImplicitPrelude, OverloadedStrings, RecordWildCards, ScopedTypeVariables,
BangPatterns, TupleSections BangPatterns, TupleSections, NamedFieldPuns
build-depends: base >=4.5 && <4.8, build-depends: base >=4.5 && <4.8,
text >=0.11 && <0.12, text >=0.11 && <0.12,
@ -93,7 +93,7 @@ executable hask-irc
-- LANGUAGE extensions used by modules in this package. -- LANGUAGE extensions used by modules in this package.
default-extensions: NoImplicitPrelude, OverloadedStrings, RecordWildCards, ScopedTypeVariables, default-extensions: NoImplicitPrelude, OverloadedStrings, RecordWildCards, ScopedTypeVariables,
BangPatterns, TupleSections BangPatterns, TupleSections, NamedFieldPuns
-- Other library packages from which modules are imported. -- Other library packages from which modules are imported.
build-depends: base >=4.5 && <4.8, build-depends: base >=4.5 && <4.8,