I wrote this echo server in Haskell as a way to introduced myself to programming with sockets in Haskell and generally practice Haskell. The echo server has a simple purpose: accept connections from a port (provided as a command line argument) and echo data read from the port back one line at a time.
import Control.Applicative
import Control.Concurrent
import Control.Monad
import Network.Socket
import System.Environment
import System.IO
main :: IO ()
main = withSocketsDo $ do
port <- toEnum . read . head <$> getArgs
newSocket <- socket AF_INET Stream defaultProtocol
setSocketOption newSocket ReuseAddr 1
bindSocket newSocket $ SockAddrInet port iNADDR_ANY
listen newSocket 2
runServer echo newSocket
runServer :: (String -> String) -> Socket -> IO()
runServer f s = forever $ do
(usableSocket,_) <- accept s
forkIO $ interactWithSocket f usableSocket
interactWithSocket :: (String -> String) -> Socket -> IO()
interactWithSocket f s = do
handle <- socketToHandle s ReadWriteMode
forever $ f <$> hGetLine handle >>= hPutStrLn handle
echo :: String -> String
echo = id
General review of my Haskell coding is appreciated as well as advice on better or alternate ways to interact with sockets in Haskell. Finally, I plan on implementing more complex servers in Haskell so, I'm looking for tips on how to make my code more extensible.