<div dir="ltr">One option is to use <a href="http://hackage.haskell.org/package/pipes-concurrency">pipes-concurrency</a>. <div><br></div><div><a href="http://hackage.haskell.org/package/pipes-concurrency-2.0.3/docs/Pipes-Concurrent.html#v:spawn-39-">Create</a> a mailbox, and pass to <b>runClient </b>a callback that reads from the Connection and writes to the <span style="color: rgb(0, 0, 0); font-family: sans-serif; line-height: 14.56px;"><a href="http://hackage.haskell.org/package/pipes-concurrency-2.0.3/docs/Pipes-Concurrent.html#t:Output">mailbox</a>. </span></div><div><span style="color: rgb(0, 0, 0); font-family: sans-serif; line-height: 14.56px;"><br></span></div><div><span style="color: rgb(0, 0, 0); font-family: sans-serif; line-height: 14.56px;"><a href="http://hackage.haskell.org/package/pipes-concurrency-2.0.3/docs/Pipes-Concurrent.html#v:fromInput">Build </a>a <b>Producer </b>from the other end of the mailbox and consume it in another thread.</span></div><div><span style="color: rgb(0, 0, 0); font-family: sans-serif; line-height: 14.56px;"><br></span></div><div><span style="color: rgb(0, 0, 0); font-family: sans-serif; line-height: 14.56px;">Coordinate the threads with something like <a href="http://hackage.haskell.org/package/async-2.0.2/docs/Control-Concurrent-Async.html#v:concurrently">concurrently</a> from the async package.</span><br><br>On Thursday, October 22, 2015 at 1:42:37 AM UTC+2, Dimitri DeFigueiredo wrote:<blockquote class="gmail_quote" style="margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<div bgcolor="#FFFFFF" text="#000000">
Hello All,<br>
<br>
I am trying to use both the websockets library and the pipes
library. They seem like a natural fit. However, I wanted to use the
websockets library to build a pipes 'Producer' and that does not
seem possible without some heavy lifting.<br>
<br>
The websockets library does not give me a connection I can read from
and write to. Instead, I need to supply an IO action (called a
clientApp). And execute it using something like:<br>
<br>
--runClient :: String -- ^ Host<br>
-- -> Int -- ^ Port<br>
-- -> String -- ^ Path<br>
-- -> ClientApp a -- ^ Client application --
type ClientApp a = Connection -> IO a<br>
-- -> IO a<br>
<br>
main :: IO ()<br>
main = withSocketsDo $ runClient "<a href="http://echo.websocket.org" target="_blank" rel="nofollow" onmousedown="this.href='http://www.google.com/url?q\75http%3A%2F%2Fecho.websocket.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHo_mrF2j-LVLdozPdgP6gpitPAEQ';return true;" onclick="this.href='http://www.google.com/url?q\75http%3A%2F%2Fecho.websocket.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHo_mrF2j-LVLdozPdgP6gpitPAEQ';return true;">echo.websocket.org</a>" 80 "/" app<br>
<br>
The problem happens when you couple this restriction with the
requirement that ClientApps have type 'Connection -> IO a'. Pipes
producers are Monad transformer stacks. For example, I would like to
build something like: <br>
messageProducer :: Producer' WebsocketMessage IO ()<br>
<br>
But this does not run in the IO monad and at the same time I cannot
get a 'Connection' object unless I use runClient.<br>
<br>
So, it seems I have a catch22 situation. Or have I overlooked
something? I'd rather not have to do "un-lifting" on the monad
transformer stack.<br>
<br>
Has anyone done this before? Any suggestions on how to go about it?<br>
<br>
<br>
Thanks,<br>
<br>
<br>
Dimitri<br>
<br>
<br>
<br>
</div>
</blockquote></div></div>