
I have a data structure of data Monad m => NntpConnection m = NntpConnection { input :: ByteString, output :: ByteString -> m () } I'd like to create echo structure such that the goes to output is going to (lazy) input. For sure it is possible to use network and IO monad - is is possible to do it purely? Regards

On Sat, 2009-07-18 at 00:40 +0200, Maciej Piechotka wrote:
I have a data structure of data Monad m => NntpConnection m = NntpConnection { input :: ByteString, output :: ByteString -> m () }
I'd like to create echo structure such that the goes to output is going to (lazy) input. For sure it is possible to use network and IO monad - is is possible to do it purely?
Regards
I come up to with: createEcho :: IO (NntpConnection IO) createEcho = do (r, w) <- runKleisli (Kleisli fdToHandle *** Kleisli fdToHandle) =<< createPipe hSetBuffering r LineBuffering hSetBuffering w LineBuffering c <- hGetContents r return $ NntpConnection c $ hPut w Which have advantage of not involving network stack but is POSIX-specific. Regards

On Sat, Jul 18, 2009 at 12:40:15AM +0200, Maciej Piechotka wrote:
I have a data structure of data Monad m => NntpConnection m = NntpConnection { input :: ByteString, output :: ByteString -> m () }
I'd like to create echo structure such that the goes to output is going to (lazy) input. For sure it is possible to use network and IO monad - is is possible to do it purely?
In words, not code: you may create a Chan of strict ByteStrings. On the output side you just append all the chunks of the lazy ByteString to the Chan, or you may copy the lazy ByteString in one chunk of strict ByteString. On the input side you "getContents" and "fromChunks". Should work, I guess. -- Felipe.

Felipe Lessa
On Sat, Jul 18, 2009 at 12:40:15AM +0200, Maciej Piechotka wrote:
I have a data structure of data Monad m => NntpConnection m = NntpConnection { input :: ByteString, output :: ByteString -> m () }
I'd like to create echo structure such that the goes to output is going to (lazy) input. For sure it is possible to use network and IO monad - is is possible to do it purely?
In words, not code: you may create a Chan of strict ByteStrings. On the output side you just append all the chunks of the lazy ByteString to the Chan, or you may copy the lazy ByteString in one chunk of strict ByteString. On the input side you "getContents" and "fromChunks". Should work, I guess.
-- Felipe.
Sorry - I don't follow: 1. How the output is suppose to get into input? 2. Why combine getContents and fromChunks if getContents is overloaded for ByteString? 3. How to use getContents without IO - either network or posix pipe? Regards

On Sat, Jul 18, 2009 at 10:51:26PM +0000, Maciej Piechotka wrote:
] Felipe Lessa
import Control.Concurrent.Chan import qualified Data.ByteString.Lazy.Char8 as L
data NntpConnection m = NntpConnection { input :: L.ByteString, output :: L.ByteString -> m () }
echoConnIO :: IO (NntpConnection IO) echoConnIO = do chan <- newChan inputChunks <- getChanContents chan -- lazy! return $ NntpConnection { input = L.fromChunks inputChunks, output = mapM_ (writeChan chan) . L.toChunks }
*Main Control.Concurrent> c <- echoConnIO *Main Control.Concurrent> forkIO $ L.putStrLn (input c) ThreadId 65 *Main Control.Concurrent> output c $ L.pack "Hello, world!\n" Hello, world! Note that the input bytestring will never end because NntpConnection doesn't have something like 'close :: m ()'. If you want something robust you'll probably move away from representing you input as a lazy bytestring anyway. -- Felipe.
participants (2)
-
Felipe Lessa
-
Maciej Piechotka