[Haskell-cafe] IterIO: How to write use my inumReverse

John Ky newhoggy at gmail.com
Mon Jul 4 12:36:33 CEST 2011


Hi Haskell Cafe,

I've defined the following reverse echo server that echos text back in
reverse:

module Programs.TcpEchoIterServer where

import Control.Concurrent
import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Data.IterIO
import Data.IterIO.Inum
import Network
import System.IO
import System.IO.Error (isEOFError)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as C

iterHandle' :: (MonadIO m) => Handle -> IO (Iter L.ByteString m (), Onum
L.ByteString m a)
iterHandle' = iterHandle

main = withSocketsDo $ do
  sListen <- listenOn (PortNumber 8000)
  putStrLn "Listening on Port 8000"
  forkIO $ forever $ do
    (sSession, hostname, port) <- accept sListen
    hSetBuffering sSession NoBuffering
    putStrLn ("Connected to " ++ hostname ++ ":" ++ show port)
    forkIO $ do
      (iter, enum) <- iterHandle' sSession
      enum |$ inumLines .| inumReverse .| inumUnlines .| iter
  putStrLn "Press <CTRL-D> to quit."
  exitOnCtrlD

iterLines :: (Monad m) => Iter L.ByteString m [L.ByteString]
iterLines = do
  line <- lineI
  return [line]

iterUnlines :: (Monad m) => Iter [L.ByteString] m L.ByteString
iterUnlines = (L.concat . (++ [C.pack "\n"])) `liftM` dataI

iterReverse :: (Monad m) => Iter [L.ByteString] m [L.ByteString]
iterReverse = do
  lines <- dataI
  return (map L.reverse lines)

inumLines = mkInum iterLines
inumUnlines = mkInum iterUnlines
inumReverse = mkInum iterReverse

exitOnCtrlD = try getLine >>= either
  (\e -> unless (isEOFError e) $ ioError e)
  (const exitOnCtrlD)


It all works fine.

My question is: Is it possible to rewrite inumReverse to be this:

iterReverse :: (Monad m) => Iter L.ByteString m L.ByteString
iterReverse = do
  line <- dataI
  return (L.reverse line)

inumReverse = mkInum iterReverse


And still be able to use it in the line:

enum |$ inumLines .| {-- inumReverse goes in here somehow --} .| inumUnlines
.| iter


The reason I ask is that the Haskell function reverse has the type [a] ->
[a], not  [[a]] -> [[a]].

I thought perhaps the alternative inumReverse is cleaner than the original
as it behaves more similarly to Haskell's own reverse function.

Cheers,

-John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110704/17a2bcd0/attachment.htm>


More information about the Haskell-Cafe mailing list