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
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