Home > database >  Purescript: How to read a string from stdin and save it?
Purescript: How to read a string from stdin and save it?

Time:12-08

I'm quite new to Purescript and I am trying to process some user input (received from stdin) but my best approach is this one:

processInput :: String -> Effect Unit
processInput input = do
  let
    arr = split (Pattern " ") input
    player1 = unsafeIndex arr 0
    player2 = unsafeIndex arr 1
    result = checkGame player1 player2
  log $ "You typed: " <> player1 <> " " <> player2 <> ":" <> show (result)

lineHandler :: Interface -> String -> Effect Unit
lineHandler interface s  = do
  if s == "quit"
    then do
      close interface
    else do
        processInput s
        prompt interface

main :: Effect Unit
main = do
  interface <- createConsoleInterface noCompletion
  setPrompt "> " interface
  setLineHandler (lineHandler interface) interface
  prompt interface

In which I use the Node.ReadLine package to create an interface, ask for input and process it in another method. This is meant for a rock-scissors-paper game and I managed to obtain the result of a single move and log it to the user. But I'm stuck at adding that result to a total outside the lineHandler function.

Is there any other way of obtaining string input from user at main scope (without a lineHandler)? Or is there a way I can define a parameter points which accumulates over the lineHandler executions?

I thought about State but I still don't understand it very well. Thanks in advance

CodePudding user response:

If you want to structure your program as an Interface from Node.ReadLine, you'll have to keep your game state (whatever it may be) in a mutable memory cell, which is represented by the Ref type. You can create such cell with the new function, and then read from and write to it with the read and write functions respectively.

You'll have to create the memory cell in main and then tunnel it through lineHandler to processInput.

processInput :: Ref.Ref Int -> String -> Effect Unit
processInput total input = do
  let
    arr = split (Pattern " ") input
    player1 = unsafePartial $ unsafeIndex arr 0
    player2 = unsafePartial $ unsafeIndex arr 1
    result = checkGame player1 player2
  currentTotal <- Ref.read total  -- Read from the cell
  let newTotal = currentTotal   42 
  Ref.write newTotal total        -- Write new value to the cell
  log $ "You typed: " <> player1 <> " " <> player2 <> ": " <> show (result) <> ", current total is " <> show newTotal

lineHandler :: Ref.Ref Int -> Interface -> String -> Effect Unit
lineHandler total interface s  = do
  if s == "quit"
    then do
      close interface
    else do
        processInput total s
        prompt interface

main :: Effect Unit
main = do
  total <- Ref.new 0  -- Create a new memory cell with initial value of 0
  interface <- createConsoleInterface noCompletion
  setPrompt "> " interface
  setLineHandler (lineHandler total interface) interface
  prompt interface
  • Related