I have an exercise to do where:
here is a simplified snippet of the haskell IO loop:
main = do
guess_loop []
guess_loop xs = do
x <- readLn
let new_list = x:xs
putStr $ show $ doSmothing new_list
putStr "\n"
guess_loop new_list
this is the snippet JS that communicate with my program (I think):
//executes the program with the numbers as stdin entries and saves its ouput in `output`
let output
try {
output = execSync(test_file, {
input: values_to_test,
})
} catch (err) {
res.send({ status: 500, msg: 'No file found: ' + guesser })
throw Error('No file found\n' + err)
}
let value = output.toString().split('\n')
value.pop()
let result = 0
let returning = []
let correct = 0
and here is the simplified working golang version snippet
func main() {
reader := bufio.NewScanner(os.Stdin)
var k []float64
for reader.Scan() {
t := reader.Text()
n, err := strconv.Atoi(t)
k = append(k, float64(n))
fmt.PrintLn(do_something(k)) // return []float64
}
}
I have no clue of JS (and do not need any), I know some golang , I am learning haskell
nothing actually happen so no error to share.
I understood that the lazy aspect of haskell regarding IO could be at play, so I added
hSetBuffering stdin LineBuffering hSetBuffering stdout LineBuffering
before the IO loop (below main = do
) in vain.
I tried to put console.log('hint') everywhere is JS code to figure out what is happening with no luck. I also made haskell IO loop to write output in a file to check if it was actually active when called by JS and it did.
My guts tells me there is something off between
try { output = execSync(test_file,inputs}
and
PutStr result
If you can help me in any way: spot an obvious error or put me on the right track; that would be great. Ideally I would rather do something about the haskell and leave untouched the JS one. If you have any clue please share. Thanks
The problem may be that your example program reads input forever, and when it encounters an end of file, it terminates with an error. The Golang version reads input until it encounters an end of file and then gracefully exits.
The Javascript driver appears to provide a finite amount of input from values_to_test
, and it responds to any failure of the program to run successfully with a 500 No File Found
error, ignoring any output that might have been produced before the program fails.
You could try rewriting your Haskell program to check for end-of-file at the start of the loop:
import Control.Monad (when)
import System.IO (isEOF)
main = do
guess_loop []
guess_loop xs = do
eof <- isEOF
when (not eof) $ do
x <- readLn
let new_list = x:xs
putStr $ show $ doSomething new_list
putStr "\n"
guess_loop new_list
This probably looks very awkward, but as you become more experienced with Haskell, you'll discover that a more natural way of writing this program is something like:
import Data.List
main = do
input <- getContents -- read all of stdin, lazily
let values = map read (lines input) -- read one value per line
let output = map doSomething (tail (inits values))
-- run the computation on every initial part of the list
putStr $ unlines (map show output) -- write outputs one per line