0

I'll get right to it (I removed a bunch of extraneous code, in case this looks a little funny -- trying to make this a MCVE):

import System.IO
import Control.Monad
import Data.IORef

main :: IO ()
main = do
    hSetBuffering stdout NoBuffering 

    input_line <- getLine
    let input = words input_line
    let x0 = read (input!!0) :: Int
    x <- newIORef x0
    loop

loop :: IO ()
loop = do
    input_line <- getLine
    let the_dir = input_line :: String 

    putStrLn x

    loop

Just to test it I tried outputting x and it's saying it's out of scope. Why? How do I fix it so it is in scope? I need to access the variables but I also need to have them initialized before I enter the loop for the first time.

5
  • Can you make loop accept an input parameter and pass x to it? Commented Nov 13, 2017 at 7:53
  • I don't know how, but I would assume that is a valid way to do it Commented Nov 13, 2017 at 7:55
  • 4
    More important, what are you trying to do that needs IORef and such? Commented Nov 13, 2017 at 7:56
  • I have a game loop that runs over and over again and I need to read input and update values / output accordingly, I have no idea how you're supposed to do that if everything is immutable Commented Nov 13, 2017 at 7:59
  • I see. Perhaps you can update your question with the above, and provide some sample data so that we could see another solution to this? Commented Nov 13, 2017 at 8:15

1 Answer 1

1

You can make x a parameter.

import System.IO
import Control.Monad
import Data.IORef

main :: IO ()
main = do
    hSetBuffering stdout NoBuffering 

    input_line <- getLine
    let input = words input_line
    let x0 = read (input!!0) :: Int
    x <- newIORef x0
    loop x

loop :: Int -> IO ()
loop x = do
    input_line <- getLine
    let the_dir = input_line :: String 

    putStrLn $ show x

    loop

Or simply use forever.

import Control.Monad

...

    x <- newIORef x0
    forever $ do
        input_line <- getLine
        let the_dir = input_line :: String 

        putStrLn $ show x
Sign up to request clarification or add additional context in comments.

6 Comments

This won't type check. Above, x is an IORef Int, then is used as a String. With slightly more work it should work, though.
@chi I changed the parameter to IORef Int -- how do I get it to print? I tried print $ x and print (readIORef x) etc, nothing is working
@user8930358 Try print =<< readIORef x or split the read and the print: as in do .... ; xVal <- readIORef x ; print xVal
@chi I have to print two of them on the same line with a space separator, to be specific, will print =<< readIORef x syntax let me do that or do I have to do some string conversion thing using your second method?
Looks like printf "%d %d" x_out y_out works after doing x_out <- readIORef x and importing Text.Printf although I don't know if this is nonstandard
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.