Last active
February 9, 2020 16:18
-
-
Save isovector/ee1143862c794eaad3e1a288509fdc34 to your computer and use it in GitHub Desktop.
Design and Interpretation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- The actual IO implementation of the program | |
withFreenode :: (Handle -> IO a) -> IO a | |
withFreenode f = | |
runTCPClient "irc.freenode.net" "6667" $ \sock -> do | |
irc <- socketToHandle sock ReadWriteMode | |
hSetBuffering irc LineBuffering | |
f irc <* hClose irc | |
main :: IO () | |
main = withFreenode $ \irc -> do | |
runApp (Stuff irc) $ do | |
(recv, send) <- connectAndGetStreams "helloworld1234" "Sandy" "#irccat" | |
void | |
. liftIO | |
. forkIO | |
. runApp (Stuff irc) | |
. S.print | |
$ recv | |
send $ S.fromHandle stdin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- The abstract logic of the program | |
connectAndGetStreams | |
:: ( MonadIRC m | |
, MonadFinal m | |
) | |
=> Nick | |
-> String | |
-> Channel | |
-> m ( Stream (Of RecvMsg) m () | |
, Stream (Of String) m b -> m b | |
) | |
-- ^ A pair of streams of (incoming, outgoing) messages | |
connectAndGetStreams nick name chan = do | |
traverse_ sendIRC $ loginFlow nick name [chan] | |
pure | |
( recvMessages | |
, flip finally (sendIRC $ QUIT "leaving") | |
. S.mapM_ sendIRC | |
. S.map (PRIVMSG [RecipientChannel chan]) | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- A test harness for running the abstract program | |
type MockedM = WriterT [IRCCommand] (State [RecvCommand]) | |
data Dicts = | |
Dicts | |
(Improvised (MonadIRC MockedM)) | |
(Improvised (MonadFinal MockedM)) | |
makeImprovCollection ''Dicts | |
mockedIRC | |
:: Improvised (MonadIRC MockedM) | |
mockedIRC = MonadIRC | |
{ _sendIRC = tell . pure | |
, _recvNewMessage = do | |
res <- gets listToMaybe | |
modify $ drop 1 | |
pure res | |
} | |
unsafeFinal :: Improvised (MonadFinal MockedM) | |
unsafeFinal = MonadFinal | |
{ _finally = (<*) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment