Idiomatic getLine

Sorry for a beginner question. I’m a very novice in PS and JS at all. Could you suggest the most idiomatic way of stdin reading? Something the most similar to:

main :: Effect Unit
main =
  line <- getLine
  log ("you said: " ++ line)
1 Like

You can find a working example in node-readline’s test suite:

import Node.ReadLine (prompt, close, setLineHandler,  noCompletion, createConsoleInterface)

main :: Effect Unit
main = do
  interface <- createConsoleInterface noCompletion
  -- [*]
  -- ask for input
  prompt interface
  -- handle input
  setLineHandler interface \s -> log s *> close interface

Looks complicated cause purescript doesn’t itself has any built-in way to do it. Instead it uses node bindings. There’s also an aff version.

It isn’t too complicated if you break it down and keep in mind how it all depends on node's event loop. We just have to do it via an interface and line handler, hence setLineHandler.

Also we can write instead (of [*]):

-- question :: question -> lineHandler             -> interface -> Effect Unit
-- question :: String   -> (String -> Effect Unit) -> Interface -> Effect Unit
question "> " (\s -> log s *> close interface) interface

These two are equivalent.

Apparently this is the bare minimum:

main :: Effect Unit
main = do
  interface <- createConsoleInterface noCompletion
  setLineHandler interface \s -> log s *> close interface

edit#1: Updated with simplest case, as the question was put initially.

edit#2: The more you know…

4 Likes

Just to build off @razcore-rad’s answer, it’s not possible to create a getLine :: Effect String that does what you want if you’re using the JS backend, because of JS’s event loop model. That’s why you have to use a callback (as in node-readline) or Aff.

3 Likes