<div dir="ltr"><div>Dear Sumit,</div><div><br></div><div>You are right that there's something's fishy about the free monadic modeling of accept.</div><div><br></div><div>The following parallel construction will prove instructive:</div><div><br></div><div>The native effect:</div><div><br></div><div>   send :: chan -> ByteString -> IO Bool</div><div><br></div><div>is modeled in the free monad by the constructor for the base functor</div><div><br></div><div>   Send :: chan -> ByteString -> (Bool -> next) -> NetworkActivity chan next</div><div>   </div><div>which is the data wrapping used in the value level</div><div><br></div><div>   sendit :: chan -> ByteString -> Free (NetworkActivity chan) Bool</div><div>   sendit chan buf = liftF (Send chan buf identity)</div><div>   </div><div>Analogously, the native</div><div><br></div><div>   accept :: chan -> IO chan</div><div><br></div><div>is modeled by</div><div><br></div><div>   Accept :: chan -> (chan -> next) -> NetworkActivity chan next</div><div><br></div><div>used in</div><div><br></div><div>   acc :: chan -> Free (NetworkActivity chan) chan</div><div>   acc chan = liftF (Accept chan identity)</div><div><br></div><div>Except that you used a different constructor for the base functor. Not</div><div><br></div><div>   Accept :: chan -> (chan -> next) -> NetworkActivity chan next</div><div><br></div><div>but</div><div><br></div><div>   Accept :: chan -> next -> (chan -> next) -> NetworkActivity chan next</div><div><br></div><div>which is equivalent to</div><div><br></div><div>   Accept :: chan -> (Maybe chan -> next) -> NetworkActivity chan next</div><div>   </div><div>The new free monadic term that substitutes for the native accept is the same like before</div><div><br></div><div>   acc chan = liftF (Accept chan identity)</div><div><br></div><div>only with a different type</div><div><br></div><div>   acc :: chan -> Free (NetworkActivity chan) (Maybe chan)</div><div><br></div><div>modeling a native</div><div><br></div><div>   accept :: chan -> IO (Maybe chan)</div><div><br></div><div>Given a native API, its free monad encoding is entirely boilerplate. I wrote about the boilerplate process here (skip the sections that don't concern you):</div><div><br></div><div><a href="http://www.atamo.com/articles/free-monads-wont-detox-your-colon/">http://www.atamo.com/articles/free-monads-wont-detox-your-colon/</a><br></div><div><br></div><div>Best, Kim-Ee<br></div><div class="gmail_extra"><div><div class="gmail_signature" data-smartmail="gmail_signature"><br></div><div class="gmail_signature" data-smartmail="gmail_signature">-- Kim-Ee</div></div>
<br><div class="gmail_quote">On Fri, Oct 14, 2016 at 6:44 AM, Sumit Raja <span dir="ltr"><<a href="mailto:sumitraja@gmail.com" target="_blank">sumitraja@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">> I would really like to help you, but without your imports, packages, etc,<br>
> it is really hard to interpret your program.  Like where does decodeUtf8<br>
> come from, or receive, or TCPSocket?  If they are functions you wrote, I<br>
> don't need their code, the types would be sufficient.<br>
><br>
</span>Imports are:<br>
<br>
import Protolude<br>
import Control.Monad.Free<br>
import System.Socket<br>
import System.Socket.Family.Inet<br>
import System.Socket.Type.Stream<br>
import System.Socket.Protocol.TCP<br>
import Control.Exception ( bracket, catch )<br>
import Data.ByteString as BS (uncons)<br>
<br>
    decodeUtf8 :: ByteString -> Text<br>
    encodeUtf8 :: Text -> ByteString<br>
<br>
I'm using the socket library for the actual networking<br>
(<a href="https://hackage.haskell.org/package/socket-0.6.0.1" rel="noreferrer" target="_blank">https://hackage.haskell.org/<wbr>package/socket-0.6.0.1</a>)<br>
<br>
    type TCPSocket = Socket Inet Stream TCP<br>
    receive :: Socket f t p -> Int -> MessageFlags -> IO ByteString Source<br>
    send :: Socket f t p -> ByteString -> MessageFlags -> IO Int<br>
    accept :: (Family f, Storable (SocketAddress f)) => Socket f t p<br>
-> IO (Socket f t p, SocketAddress f)<br>
<br>
If it helps the full source is at<br>
<a href="https://bitbucket.org/sumitraja/network-free/src/a4fcbc74c9e178e81d8b10b60d912b32c542b661/src/Lib.hs" rel="noreferrer" target="_blank">https://bitbucket.org/<wbr>sumitraja/network-free/src/<wbr>a4fcbc74c9e178e81d8b10b60d912b<wbr>32c542b661/src/Lib.hs</a>.<br>
<br>
Looking forward to your assistance.<br>
<div class="HOEnZb"><div class="h5"><br>
Thanks<br>
<br>
Sumit<br>
______________________________<wbr>_________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br></div></div>