0

I have wasted several hours trying to fix simple Haskell program where I tried to ask the user to enter a string and then display it. The program looks like that:

main = do
  putStrLn "Enter something "
  entered <- getLine
  putStrLn ("You have entered " ++ entered)

After hours of chasing my tail and reading lots of Monad tutorials I have discovered that my program works fine in cmd prompt. Can you imagine my frustration at this point?

This SO question gave me a clue to try it in cmd: https://stackoverflow.com/questions/8361508/execution-order-with-not-what-i-expected?rq=1

Is it possible to fix eshell? If not what is the best way to develop Haskell on Windows with Emacs?

Temporary solution

After a bit of experimenting I decided to start cmd.exe with a customised script that sets my environment for Haskell development. The following script starts my cmd:

set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%
set INCLUDE=c:/msys64/mingw64/include
set XDG_DATA_DIRS=c:/msys64/mingw64/share
set PKG_CONFIG_PATH=c:/msys64/mingw64/lib/pkgconfig
set HASKELL_GI_GIR_SEARCH_PATH=c:/msys64/mingw64/share/gir-1.0

cd C:/Windows/System32/

cmd.exe

Using cmd sets my path correctly. I have tried a similar script that launches powershell, which gives me better autocompletion than cmd, but for some reason I can't make the PATH in powershell accept my script settings, other environment variables seem to be OK.

Another option

Following one commenter's question this is the version that works with eshell on Windows 10

import System.IO (hFlush, stdout)

main = do
  putStrLn "Enter a string"
  hFlush stdout
  ln <- getLine
  putStrLn ("Yo have entered " ++ ln)

Note the use of hFlush stdout after first printing that was causing problems.

  • Surprisingly, this code works just fine in eshell on GNU/Linux. I suspect your problem might be related to cmdproxy.exe. – DoMiNeLa10 Apr 23 '18 at 8:35
  • "This SO question gave me a clue" - did you try the hFlush and/or hSetBuffering suggestions in the answer? – npostavs Apr 23 '18 at 11:27
  • @npostavs - No, it was 3 AM when I found it, so I thought I'd have a break. – ruby_object Apr 23 '18 at 12:48
1

I have found something that works with eshell on Windows 10.

import System.IO (hSetBuffering, stdout, stdin, BufferMode(..))

main = do
  hSetBuffering stdin LineBuffering
  hSetBuffering stdout LineBuffering
  putStrLn "Enter a string"
  ln <- getLine
  putStrLn ("Yo have entered " ++ ln)

I have found further suggestions here: https://stackoverflow.com/questions/19520885/haskell-default-io-buffering

So it is not an eshell problem, but GHCI tries to be clever and is confused by cmdproxy. Toxaris has said the following:

The GHC runtime system tries to be clever when it chooses the default buffering. If it looks like stdin and stdout are directly connected to terminal, they will be line-buffered. If it looks like they are connected to something else, they are block-buffered. This can be problematic if you want to run a program with line-by-line input that doesn't come directly from a terminal.

  • By the way, the reason it works on Unix-like systems is because they provide Pseudoterminals, which Windows lacks. – npostavs Apr 23 '18 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.