Haskell Console IO in notepad++ - haskell

I've recently started to learn Haskell. I have this code
module Main
where
import IO
main = do
hSetBuffering stdin LineBuffering
putStrLn "Please enter your name: "
name <- getLine
putStrLn ("Hello, " ++ name ++ ", how are you?")
I'm using the GHC compiler together with the notepad++ editor. The problem is the interaction goes like this:
Process started >>>
Vlad
Please enter your name:
Hello, Vlad, how are you?
<<< Process finished.
As you can see, output is only written after I input something. This was a bit unexpected, as I was sure the program would first ask for my name, then I'd get to enter it and then it would say hello. Well, that's exactly what happens if I run the exe manually, yet not if I run it with notepad++ and use its console wrapper...
How can I make notepad++ display the output when it should, and not all of it just before the program terminates? Is this even possible?

Try setting stdout to LineBuffering! Also, loading your program in ghci instead runnign the compiled version doesn't seem to need any buffering at all...
By the way, I didn't know about the console in NPP - thanks for pointing me to it!

I'm not familiar with notepad++, but a quick and hacky method would probably be to do
hFlush stdout
after each putStrLn. You could even make the following method:
nppPutStrLn s = putStrLn s >> hFlush stdout

Related

Haskell does not return from getLine

For some reason, Haskell on my machine does never return from any getLine call. For instance, I tried to run the following code straight from Learn You a Haskell for Great Good:
main = do
putStrLn "Hello, what's your name?"
name <- getLine
putStrLn ("Hey " ++ name ++ ", you rock!")
When I run it, the first line is printed, and I see my input when I type a name, however when I press Enter the program just blocks there and never prints the final line.
How should I fix this?
edit: I am running it from the Sublime IDE, maybe that has something to do with it
After doing a quick search on how Sublime runs programs, I found a youtube video (edit: and this SO post) which says that Sublime's "run program" functionality can only show output and isn't capable of reading input.
So it looks like you'll have to run your program from the command line or from within GHCi using :main. The latter might be the most convenient as Sublime actually supports a GHCi tab, so you can still do everything from within Sublime.
This seems to be a limitation in Sublime's Build command (assuming that this is what you're using).
Sublime executes the script using runhaskell, but apparently, it doesn't capture STDIN (which makes kind of sense - build results are usually read-only and not an interactive session).
Workaround: run your script from the command line with
runhaskell script.hs
and everything works as expected

Use stdin from within R studio

When I try the following:
f<-file("stdin")
lines<-readLines(f)
from within R-studio on Ubuntu I can input text but unable to terminate it. Ctr+C/D, random hitting keyboard won't help. It simply hangs
I only found the followin so far
How to input EOF in stdin in R?
but no help there - had to kill R-studio.
Anybody have explanation what is wrong?
Presumably, Rstudio is redirecting stdin, so that it cannot be properly accessed as "stdin" or "/dev/stdin" any longer. However, stdin() still works.
I was still unable to actually type Ctrl+D. But it is possible to read a fixed number of lines:
> a <- readLines(stdin(), n=2)
Hello
World
> a
[1] "Hello" "World"
I've also discovered a hack that may help for interactive debugging. Let's say, you have at most 10 lines in your manual examples. Then you can do
> a <- readLines(stdin(), n=10)
abc
def
ghi
# and now just keep pressing ENTER
...
> a <- a[a != ""]
> a
[1] "abc" "def" "ghi"
If you run the same code in an environment where Ctrl+D is available, it also properly terminates the input.
Caveats: but stdin() does not work with Rscript: you'd have to switch back to file("stdin"). Furthermore, in some environments, if you use readLines with n=1 to read the file line-by-line, you may end up reopening the file and getting the first line every time. It seems that putting everything into a file and reading the whole file at once with e.g. read.table is a much more robust way of developing with Rstudio.

Haskell Compiled IO-Action order and Flushing [duplicate]

This question already has answers here:
IO happens out of order when using getLine and putStr
(3 answers)
Closed 8 years ago.
I'm encountering strange behaviour with IO, within compiled Haskell code. Here's what's going on:
-- MyScript.hs
main = do
putStr "Enter your name: "
a <- getLine
putStrLn (a ++ " - that's a nice name!")
I run this in GHCi by calling main and it works as one would expect, first printing Enter your name: and then doing whatever it's to do afterwards. However, when I compile it with GHC (With and without --make), it first prompts for a line, and then prints everything at once, like this:
$ ./MyScript
Jimmy Johnson
Enter your name: Jimmy Johnson - That's a nice name!
To clarify, I want it to occur in the following sequence:
$ ./MyFixedScript
Enter your name: Jimmy Johnson
Jimmy Johnson - That's a nice name!
Could someone explain why this happens as it is, and how to sequence the IO the way that I would expect it to.
Note also that I've tried changing the first line of the do statement to _ <- putStr "Enter your name: ", but that still doesn't work.
The IO actions are happening in the correct order, the problem lies in how input and output pipes work. The string "Enter your name: " is written to the output buffer by putStr before the getLine, but the buffer hasn't necessarily been flushed. Adding hFlush stdout after the putStr will flush the buffer.
import System.IO
-- MyScript.hs
main = do
putStr "Enter your name: "
hFlush stdout
a <- getLine
putStrLn (a ++ " - that's a nice name!")
I have the exact same problem today, and it appears that it worked well when I was using putStrLn but stopped when I changed it to putStr. As other people said, it's not related to Haskell or GHC but how IO are flushed. According to the System.IO documentation there are 3 buffering mode :
line-buffering: the entire output buffer is flushed whenever a newline is output, the buffer overflows, a System.IO.hFlush is issued, or the handle is closed.
block-buffering: the entire buffer is written out whenever it overflows, a System.IO.hFlush is issued, or the handle is closed.
no-buffering: output is written immediately, and never stored in the buffer.
The default buffering mode is said to besystem dependent, but it seems that normal program are in line-buffering mode, whereas GHCI is in no-buffering mode. This explain because using putStrLn or putStr will flush or not.
To solve your problem, you can use hFlush stdout to flush explictitey (see Cirdec answer) or change the buffering mode once by doing hSetBuffering stdout NoBuffering. Obvioulsly the NoBuffering mode is not optimal but is probably enough for small toy program.

GHCi and compiled code seem to behave differently

I have a very strange problem. The following code gives different results when compiled as compared to running in ghci,
main = do
putStr "Please enter your name: "
name <- getLine
putStr ("Hello, " ++ name ++ ", how are you?")
When run it in ghci it does as one would expect,
Please enter your name: dglmoore
Hello, dglmoore, how are you?
However, when I compile the code to an executable it requires that I provide the input before any output is generated so I end up with this,
dglmoore
Please enter your name: Hello, dglmoore, how are you?
I've seen a similar problem before, but I cannot seem to find it again.
I am using ghc version 7.4.1 from the Haskell Platform version 2012.2.0.0.
Anyone have any idea why they give different results and how I can get both versions to do the "correct" thing?
It's a buffering issue. Usually IO is line buffered (i.e. the output doesn't actually show up on the screen until you print a new line or exceed the buffer size) unless you explicitly flush the buffer. In ghci it isn't, so the issue doesn't show up.
You can use hFlush stdout to flush stdout, causing the output to be printed to the screen, before you call getLine.
Alternatively you can use hSetBuffering NoBuffering to disable buffering altogether, removing the need for hFlush. That could have a negative impact on IO performance though.

How can I get input right when it is typed in Haskell?

I have written a Brainfuck interpreter in Haskell, but it only operates on the input once I hit Ctrl-D to signal EOF. How can I make the program act on each character when it is typed?
Here is the source. To use the program, give a file to interpret as an argument or type your program in the first line of stdin.
It sounds like your input is being buffered. You can modify the buffering mode of a file handle with System.IO.hSetBuffering. If you are reading from standard input, for instance, then you could disable buffering with:
import System.IO
hSetBuffering stdin NoBuffering
getLine waits for a newline character to be typed (\n), because what if the user typed a bunch of characters, but never pressed enter? Then it would be an error if some of the "line" had already be processed, if that "line" wasn't a line after all.
You should use getContents instead which will return everything that is typed at the terminal.
Also, you are using the following line:
then hGetContents =<< openFile (head args) ReadMode
This will open a file and never close it. This is fine for your short program, but it might be a better idea for the future to get used to doing this:
then readFile $ head args

Resources