Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6870259
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T03:39:43+00:00 2026-05-27T03:39:43+00:00

How could I refactor this so that eventually IORefs would not be necessary? inc

  • 0

How could I refactor this so that eventually IORefs would not be necessary?

inc :: IORef Int -> IO ()
inc ref = modifyIORef ref (+1)

main = withSocketsDo $ do
        s <- socket AF_INET Datagram defaultProtocol
        c <- newIORef 0
        f <- newIORef 0
        hostAddr <- inet_addr host
        time $ forM [0 .. 10000] $ \i -> do
              sendAllTo s (B.pack  "ping") (SockAddrInet port hostAddr)
              (r, _) <- recvFrom s 1024 
              if (B.unpack r) == "PING" then (inc c) else (inc f)
        c' <- readIORef c
        print (c')
        sClose s
        return()
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T03:39:43+00:00Added an answer on May 27, 2026 at 3:39 am

    What’s wrong with using IORefs here? You’re in IO anyways with the networking operations. IORefs aren’t always the cleanest solution, but they seem to do the job well in this case.

    Regardless, for the sake of answering the question, let’s remove the IORefs. These references serve as a way of keeping state, so we’ll have to come up with an alternate way to keep the stateful information.

    The pseudocode for what we want to do is this:

    open the connection
    10000 times: 
      send a message
      receive the response
      (keep track of how many responses are the message "PING")
    print how many responses were the message "PING"
    

    The chunk that is indented under 1000 times can be abstracted into its own function. If we are to avoid IORefs, then this function will have to take in a previous state and produce a next state.

    main = withSocketsDo $ do
      s <- socket AF_INET Datagram defaultProtocol
      hostAddr <- inet_addr host
      let sendMsg = sendAllTo s (B.pack  "ping") (SockAddrInet port hostAddr)
          recvMsg = fst `fmap` recvFrom s 1024
      (c,f) <- ???
      print c
      sClose s
    

    So the question is this: what do we put at the ??? place? We need to define some way to “perform” an IO action, take its result, and modify state with that result somehow. We also need to know how many times to do it.

     performRepeatedlyWithState :: a             -- some state
                                -> IO b          -- some IO action that yields a value
                                -> (a -> b -> a) -- some way to produce a new state
                                -> Int           -- how many times to do it
                                -> IO a          -- the resultant state, as an IO action
     performRepeatedlyWithState s _ _ 0 = return s
     performRepeatedlyWithState someState someAction produceNewState timesToDoIt = do
       actionresult <- someAction
       let newState = produceNewState someState actionResult
       doWithState newState someAction produceNewState (pred timesToDoIt)
    

    All I did here was write down the type signature that matched what I said above, and produced the relatively obvious implementation. I gave everything a very verbose name to hopefully make it apparent exactly what this function means. Equipped with this simple function, we just need to use it.

    let origState = (0,0)
        action = ???
        mkNewState = ???
        times = 10000
    (c,f) <- performRepeatedlyWithState origState action mkNewState times
    

    I’ve filled in the easy parameters here. The original state is (c,f) = (0,0), and we want to perform this 10000 times. (Or is it 10001?) But what should action and mkNewState look like? The action should have type IO b; it’s some IO action that produces something.

    action = sendMsg >> recvMsg
    

    I bound sendMsg and recvMsg to expressions from your code earlier. The action we want to perform is to send a message, and then receive a message. The value this action produces is the message received.

    Now, what should mkNewState look like? It should have the type a -> b -> a, where a is the type of the State, and b is the type of the action result.

    mkNewState (c,f) val = if (B.unpack val) == "PING"
                             then (succ c, f)
                             else (c, succ f)
    

    This isn’t the cleanest solution, but do you get the general idea? You can replace IORefs by writing a function that recursively calls itself, passing extra parameters along in order to keep track of state. The exact same idea is embodied in the foldM solution suggested on the similar question.

    Bang patterns, as Nathan Howell suggests, would be wise, to avoid building up a large thunk of succ (succ (succ ...))) in your state:

    mkNewState (!c, !f) val = ...
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Hi Guys could you please help me refactor this so that it is sensibly
Is there a pattern that I could apply to refactor this code? The only
Given the following code, How would you refactor this so that the method search_word
How could I refactor this code to use only one Dir[ ] call? Dir[
I realize that this is not the best practices for working on individual projects.
Could someone tell me what the units the SetTimeout(int) method in the ICriteria interface
Could somebody please name a few. I could given time, but this is for
I've got this webapp that needs some memory tuning. While I'm already profiling the
I came across a few articles like this one , which suggest that some
I've inherited a rather large application that really could use some cleanup. There is

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.