Open jrp2014 opened 3 years ago
The isue you're having is that you're creating/destroying an InputT
context every time you read user input. Ideally you'd only call runInputT
once, in your main function. (I believe could still keep InputT
at the bottom of your stack as InputT IO
as you have now.)
Adapting the example from the Haddocks: https://hackage.haskell.org/package/haskeline-0.8.1.3/docs/System-Console-Haskeline.html
main :: IO ()
main = runInputT defaultSettings (evalStateT loop 0)
loop :: StateT Int (InputT IO) ()
loop = do
n <- get
minput <- lift $ getInputLine (show n ++ ":")
case minput of
Nothing -> return ()
Just "quit" -> return ()
Just "q" -> return ()
Just s -> do
lift $ outputStrLn ("line " ++ show n ++ ":" ++ s)
modify (+1)
loop
Another option, if you're having issues with the monad transformer, is the System.Console.Haskeline.IO
module:
https://hackage.haskell.org/package/haskeline-0.8.1.3/docs/System-Console-Haskeline-IO.html
That lets you run it in raw IO, at the expense of having to bracket your own initialization/cleanup.
I have started with a n mtl stack
type Forth w a r = ExceptT VMSignal (StateT (VM w a) IO) r
and want to usehaskeline
to provide command line editing to my repl. I've refactored to usetype Forth w a r = CME.ExceptT VMSignal (StateT (VM w a) (InputT IO)) r
.And functions which previously ran the stack now have calls like
and
The program works as before (and the > prompt appears. but I can't scroll back into history and the arrow keys still don't work (you get
> ^[[A
on pushing the up arrow, for example (as before). I don't want to put the InputT on the outside as I'd then have to sprinkle all my code with lifts, which I'd prefer to avoid.What can I do to get command line editing to function, please?