<div>Hi all,</div><div><br></div><div>I'm practising my Haskell by writing a simple TCP echo server and finding that getting my program control to be succinct is rather tricky. In particular, I <font class="Apple-style-span" face="'courier new', monospace">have <font class="Apple-style-span" color="#009900">return ()</font></font> everywhere, my error handling is verbose and I'm not entirely sure my recursion is the cleanest way syntactically to get my loops going and terminating.</div>
<div><br></div><div>I must be doing something obviously un-Haskell-like.</div><div><br></div><div>Any suggestions on how I can improve my code? Code below.</div><div><br></div><div>Cheers,</div><div><br></div><div>-John</div>
<div><br></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><font class="Apple-style-span" face="'courier new', monospace">import Control.Concurrent</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">import Control.Exception</font></div><div><font class="Apple-style-span" face="'courier new', monospace">import Control.Monad</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace">import Network</font></div><div><span class="Apple-style-span" style="font-family: 'courier new', monospace; ">import System.IO</span></div>
<div><font class="Apple-style-span" face="'courier new', monospace">import System.IO.Error (isEOFError)</font></div><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div><div>
<font class="Apple-style-span" face="'courier new', monospace">main = withSocketsDo $ do</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> sListen <- listenOn (PortNumber 8000)</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> putStrLn "Listening on Port 8000"</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> forkIO $ forever $ do</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> (sSession, hostname, port) <- accept sListen</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> putStrLn ("Connected to " ++ hostname ++ ":" ++ (show port))</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> let processLine = forkIO $ do</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> lineResult <- try (hGetLine sSession)</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> case lineResult of</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> Right line -> do</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> putStrLn line</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> processLine</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> return ()</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> Left e -></font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> if isEOFError e</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> then putStrLn (show e)</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> else do</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> ioError e</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> return ()</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> return ()</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> processLine</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> return()</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> line <- getLine</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> return ()</font></div></blockquote><div><br></div>