Haskell does not return from getLine - haskell

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

Related

Reading stdin in ghci on Linux is broken

Comming from Windows, I have recently installed linux distribution named Peppermint and Haskell-Platform via bash (ghc 7.10) but there must be something wrong with ghci stdin in ghci because :
interact $ take 0
throws an error but
interact $ take 1
does not.
Furthermore, if I use backspace, arrows or any other control button when writing into stdin, it enters the char symbol. For example backspace enters ^? into ghci instead of deleting the last char typed...
...#... ~ $ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> interact $ take 0
Prelude>
<stdin>: hGetChar: illegal operation (handle is closed)
...#... ~ $ ghci
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Prelude> readLn :: IO String
euoe^?^?^[[1;5C^[[D^[[B -- here I tried to delete 'euoe'
Regarding the control code literals, this is because you've managed to escape all of the line editors (readline, Haskeline) that would usually interpret your key presses.
I don't know the particulars, but invoking GHCi is something like starting a subshell with bash --noediting. This allows GHCi to receive raw key presses without interference from the readline library. This is done because Haskeline—which GHCi uses in place of readline—can be configured with things like tab completion for available functions more easily (you knew GHCi provided tab completion, right?).
Calling getLine from GHCi then effectively drops through a trap door and dodges Haskeline completely by going straight to stdin. There is, after all, only one stdin. You're now typing directly into an unbuffered terminal.
Getting back to your first concern, there being only one stdin is also why GHCi immediately keels over after printing the Prelude> prompt. interact (which uses hGetContents behind the scenes) claims that it will address all of the input that will ever come through the handle (stdin) as one big lazy String. Effectively there can be no remaining input on the handle that interact hasn't already claimed to deal with, so the handle is immediately put into a “semi-closed” state. It's not closed (there could still be more input that will be read as part of that lazy String interact gets!) but it is closed to any newcomers, otherwise input would get duplicated (interact and new readers of the handle such as getLine would get the same line!).
Back to GHCi, after having used interact, stdout is still fine so the prompt gets printed as usual, then GHCi leans on Haskeline to return a line for processing. Haskeline (as a line editor) calls a blocking getChar (iirc) to either add a character to the line or perform some line editing command and dies because it's addressing a semi-closed handle. Thus a weaker creature does fall and the great wheel of life rolls on.

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.

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.

Emacs hangs in haskell-mode with inferior-haskell-load-file call

When in a Haskell file, I use C-c C-l to run the command inferior-haskell-load-file which is intended to load the current file into the GHCI interpreter but Emacs just hangs until I hit C-g. Anyone know how I can get this to work?
GNU Emacs 23.3.1 (x86_64-pc-linux-gnu, GTK+ Version 2.24.5) of 2011-08-14 on allspice, modified by Debian
Using haskell-mode version v2.7.0
inferior-haskell-mode does some parsing based upon the expected ghci prompt. As such, if you change the prompt in a .ghci file, then it can't detect it.
For more information, see where haskell-ghci.el sets the comint-prompt-regexp value to determine what a prompt is.
;; GHCi prompt should be of the form `ModuleName> '.
(setq comint-prompt-regexp
"^\\*?[[:upper:]][\\._[:alnum:]]*\\( \\*?[[:upper:]][\\._[:alnum:]]*\\)*> ")
If you want to keep the setting in your .ghci file, then it may be possible to customise this settings.
Old question, but as I just ran into this today, I wanted to share how to actually customize comint-prompt-regexp since I had to figure it out.
This customization will recognize λ> prompts, or actually any single character before >), but it doesn't break the existing regex. In your .emacs:
(load-library "inf-haskell")
(defun my-inf-haskell-hook ()
(setq comint-prompt-regexp
(concat comint-prompt-regexp "\\|^.> ")))
(add-to-list 'inferior-haskell-mode-hook 'my-inf-haskell-hook)
You can add more dots to "\\|^.> " to recognize a longer prompt, but I wanted to keep it fixed-length for simplicity.
I had a similar problem caused by GHCi reporting some kind of error on startup, causing the Emacs haskell mode to wait for the GHCi prompt indefinitely (GHCi didn't show the standard prompt (Prelude>), but rather just showed >). You can try running GHCi externally and see if it reports any errors.
I got the same error message when I tried to use stack with emacs. For me, adding this line to my .emacs/init.el resolved the problem:
(setq haskell-program-name "stack ghci")

Haskell Console IO in notepad++

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

Resources