Skip to content

Instantly share code, notes, and snippets.

@agocorona
Created July 12, 2016 09:37
Show Gist options
  • Save agocorona/a72eba8bddbe7894e19076261000a886 to your computer and use it in GitHub Desktop.
Save agocorona/a72eba8bddbe7894e19076261000a886 to your computer and use it in GitHub Desktop.
Simple Haskell IRC client in "two lines of code"
import Transient.Base
import Network
import System.IO
import Control.Monad.IO.Class
import Control.Applicative
-- taken from Pipes example
-- https://www.reddit.com/r/haskell/comments/2jvc78/simple_haskell_irc_client_in_two_lines_of_code/?st=iqj5yxg1&sh=0cb8cc11
-- Simple Haskell IRC client in "two lines of code"
--
--main = withSocketsDo $ connect "irc.freenode.net" "6667" $ \(s, _) ->
-- forkIO (runEffect $ PBS.stdin >-> toSocket s) >> runEffect (fromSocket s 4096 >-> PBS.stdout)
main = do
h <- withSocketsDo $ connectTo "irc.freenode.net" $ PortNumber $ fromIntegral 6667
keep' $ (waitEvents getLine >>= liftIO . hPutStrLn h) <|> (waitEvents (hGetLine h) >>= liftIO . putStrLn )
@agocorona
Copy link
Author

agocorona commented Jul 12, 2016

Better add threads 1 to avoid mixing of messages in the console:

  keep' $ (waitEvents getLine >>= liftIO . hPutStrLn h) <|> (threads 1 $ waitEvents (hGetLine h) >>= liftIO . putStrLn )

@agocorona
Copy link
Author

agocorona commented Jul 12, 2016

Note that only keep', waitEvents and threads are primitives from transient. The rest are standard Haskell packages, primitives and combinators.

Transient is "non invasive". It add basic effect to the bottom of the hierarchy that are general purpose, like waitEvents (reactivity), in order to be used in very different scenarios.

@agocorona
Copy link
Author

agocorona commented Jul 15, 2016

Factorization of the second line:

keep' $ process socket stdout <|> process stdin socket
  where 
  process in out= threads 1 $ waitEvents in  >>= liftIO . hPutStrLn out

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