This works:
import Control
type Broadcast = Int
type BroadcastChan = TChan Broadcast
data SessionState = SessionState
{ _broadcastChan :: BroadcastChan
}
makeLenses ''SessionState
type Session m = StateT SessionState m
type SessionIO = Session IO
-- This function requires the state and IO...
processBroadcast :: Broadcast -> Conduit a SessionIO Packet
processBroadcast b = undefined
-- | Handles networking
protocol :: Conduit Packet SessionIO Packet
protocol = do
ch <- lift $ use broadcastChan
-- line 51:
whileJust_ (liftIO . atomically $ tryReadTChan ch) processBroadcast
liftIO $ putStrLn "End"
As the function processBroadcast only processes a single broadcast (I assumed that), there is no need to limit the conduit's input type to Broadcast. For using it in protocol, the input type of that conduit must match the input type of the protocol Conduit, which is Packet, so in protocol, the a in processBroadcast is instantiated to Packet.