[Haskell-beginners] Hints on how to remove unsafePerformIO from my function?

David McBride dmcbride at neondsl.com
Mon Jul 19 13:58:19 EDT 2010


Yeah I ended up doing pretty much what they do.  The problem was I thought I
could collect all the IO actions one by one into an array and then just map
some other IO action over the array, but apparently the IO monad doesn't
like being lazy.

What you end up having to do is do one IO action at a time, getting the udp,
then sending it over the tchan immediately before attempting to fetch the
next udp packet.  I ended up with:

fetchUDPSIP :: TChan a -> TChan B.ByteString -> IO ()
fetchUDPSIP commands chan = do
  sock <- getUDPSocket 5060
  forever $ getUDP sock >>= atomically . writeTChan chan

Which is perfectly fine.  Thanks.

On Mon, Jul 19, 2010 at 1:50 PM, aditya siram <aditya.siram at gmail.com>wrote:

> Have you looked at the Real World Haskell example [1] for reading from
> a UDP socket?  In the inner "procMessages" the authors seem to show
> how to read one packet at a time without using unsafePerformIO.
>
> -deech
>
> [1] http://book.realworldhaskell.org/read/sockets-and-syslog.html in
> the section marked "UDP Syslog Server"
>
>
> On Mon, Jul 19, 2010 at 9:07 AM, David McBride <dmcbride at neondsl.com>
> wrote:
> > I am writing a voip server to take advantage of haskells awesome
> threading
> > and parsing ability.  At first everything was going great, but my thread
> > that fetches udp makes use of unsafePerformIO:
> >
> > fetchUDPSIP :: TChan B.ByteString -> IO ()
> > fetchUDPSIP chan = do
> >   sock <- getUDPSocket 5060
> >   let results = (unstrict . repeat . getUDP) sock
> >   mapM_ (atomically . writeTChan chan) results
> >   where
> >     unstrict [] = []
> >     unstrict (x:xs) = unsafePerformIO x:unstrict xs
> >
> >
> > It fetches it from a socket, and then writes it to a TChan.  This results
> in
> > a stream of bytestrings that another thread can read from.  If I don't
> use
> > unsafePerformIO, then it tries to read all possible packets before
> returning
> > anything, and so it never writes to the TChan at all.  The problem with
> > doing it this way is that unsafePerformIO apparently stops every other
> > thread from doing anything while it is waiting for a packet.
> >
> > But I can't think of a way to rewrite this function to do what I want.
> I'm
> > kind of new to this, does anyone have any hints that could help me out?
> >
> > Here's a simple version without any of the implementation details:
> >
> > fetchLine = do
> >   let results = (unstrict . repeat) getLine
> >   mapM_ putStrLn results
> >   where
> >     unstrict [] = []
> >     unstrict (x:xs) = unsafePerformIO x:unstrict xs
> >
> > _______________________________________________
> > Beginners mailing list
> > Beginners at haskell.org
> > http://www.haskell.org/mailman/listinfo/beginners
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20100719/5dfbb49e/attachment.html


More information about the Beginners mailing list