[Haskell-beginners] Modifications inside a Reader?

Brian Troutwine goofyheadedpunk at gmail.com
Wed Jun 17 23:32:53 EDT 2009


Hello all.

I'm writing a UDP echo server, full source given below. The current
implementation echoes back the "payload" of every incoming message but
I would prefer that only unique payloads be echoed back. To that end
I've started in with Data.BloomFilter but am not sure how to update it
accordingly. I imagine that Reader is probably the wrong monad to be
using though I'm unsure how I might modify my program to use State.
Could someone lead me along a bit?

Also, any general comments on the style of my program?

Thanks,
Brian

--

import Prelude hiding (putStrLn, catch)
import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import Data.ByteString.Char8 hiding (head)
import Control.Monad.Reader
import Control.Monad (forever)
import Control.Exception (bracket)
import Data.BloomFilter
import Data.BloomFilter.Easy
import Data.BloomFilter.Hash (cheapHashes)

data Globals = Globals {
      socketG :: Socket
    , bloomF  :: Bloom ByteString
    }
type Echo = ReaderT Globals IO

run :: Echo ()
run = forever $ do
  s <- asks socketG
  (msg, addr) <- liftIO $ recvFrom s 1024
  let [_, _, _, payload] = split ':' msg
  liftIO $ sendTo s payload addr

main :: IO ()
main = bracket build disconnect loop
  where
    disconnect = sClose . socketG
    loop st    = runReaderT run st

build :: IO Globals
build = do
  addrinfos <- getAddrInfo
               (Just (defaultHints {addrFlags = [AI_PASSIVE]}))
	       Nothing (Just "1514")
  let serveraddr = head addrinfos
  sock <- socket (addrFamily serveraddr) Datagram defaultProtocol
  bindSocket sock (addrAddress serveraddr)
  return $ Globals sock $ emptyB (cheapHashes 3) 1024


More information about the Beginners mailing list