Я получил проблему с IO, не выполняющимся в порядке, даже в действительно создают.
В следующем коде я просто отслеживаю то, какие карты оставляют, где карта является кортежем символов (один для иска и один для значения) затем, пользователя непрерывно спрашивают, для которого игрались карты. Я хочу putStr
выполняться между каждым входом, а не в самом конце как он теперь.
module Main where
main = doLoop cards
doLoop xs = do putStr $ show xs
s <- getChar
n <- getChar
doLoop $ remove (s,n) xs
suits = "SCDH"
vals = "A23456789JQK"
cards = [(s,n) | s <- suits, n <- vals]
type Card = (Char,Char)
remove :: Card -> [Card] -> [Card]
remove card xs = filter (/= card) xs
absz ответ правильный, буферизованный ввод-вывод Haskell - это то, что вызывает у вас проблемы. Вот один из способов переписать ваш doLoop
, чтобы получить желаемый эффект:
doLoop xs = do putStrLn $ show xs
input <- getLine
let s:n:_ = input
doLoop $ remove (s,n) xs
Два изменения: используйте putStrLn
для добавления новой строки и сброса вывода (что, вероятно, что вы хотите) и используйте getLine
, чтобы получать ввод по строке за раз (опять же, возможно, что вы хотите).
Буферизация в форме putStr - это ваша проблема, как указывали другие.
Кроме того, точка стиля: putStrLn $ show xs
совпадает с print xs
Если проблема в том, что я думаю, ваша проблема в том, что ввод-вывод Haskell буферизуется: этот вопрос объясняет, что происходит. Когда вы запускаете скомпилированную программу на Haskell, GHC сохраняет вывод в буфере и только периодически выводит его на экран; это происходит, если (а) буфер слишком заполнен, (б) если выводится новая строка, или (в) если вы вызываете hFlush stdout
.
Другая проблема, с которой вы можете столкнуться, заключается в том, что getChar
может не срабатывать до тех пор, пока не будет прочитана новая строка, но тогда она находится в вашем входном потоке; возможно, вы могли бы решить эту проблему с помощью дополнительного getChar
, чтобы проглотить новую строку, но, вероятно, должен быть способ получше.