Я пытаюсь научиться чему-то Haskell, но столкнулся с проблемой, я понятия не имею, как вообще объяснить. Проблемным моментом является некоторый код для обработки, позволяющий пользователю выбирать порядок посещений пунктов меню и изменять их так часто, как они хотят, до подтверждения. Первый выбор проходит гладко, и последующие выборки той же опции тоже делают, но как только будет сделан другой выбор, каждый l oop с этой точки, независимо от того, введен ли 1 или 2, выполнение будет go вниз обе опции в функции modeSelectParse (см. код ниже). Эти ветви являются единственными вызовами либо collectSettings , либо mart в программе, и такое поведение сохраняется, даже когда они оба были заглушены просто оператором print.
Когда я добавил больше веток, все ранее посещенные ветви запускались один раз на каждой итерации, в фиксированном порядке все время, независимо от того, как я перетасовывал порядок ветвей в modeSelectParse , или какое число соответствует какому варианту.
Я подозревал, что буферизация стандартного ввода-вывода была ошибочной, поэтому я попытался отключить это, и различные другие тесты на входе, в который я вошел. Но ничего не показалось в данных, когда я пытался распечатывать его в разных точках программы.
Первоначальный вызов modeSelectInit также находится не там, где он может когда-либо вызываться более одного раза.
Я могу дать больше объяснений и код при необходимости.
modeSelectInit :: DatabaseStruct -> IO (IO Settings, IO Order)
modeSelectInit db = do
putStrLn "A lot of text"
hFlush stdout
let select = (return emptySettings, return [])
input <- awaitChar ['1', '2']
modeSelect db (modeSelectParse db input select)
modeSelect :: DatabaseStruct -> (IO Settings, IO Order) -> IO (IO Settings, IO Order)
modeSelect db select = do
settings <- fst select
order <- snd select
putStrLn "A lot of text"
hFlush stdout
input <- awaitChar ['1', '2', '3']
if input == '3'
then return select
else modeSelect (modeSelectParse db input select)
modeSelectParse :: DatabaseStruct -> Char -> (IO Settings, IO Order) -> (IO Settings, IO Order)
modeSelectParse db '1' (_, o) = (gatherSettings, o)
modeSelectParse db '2' (s, _) = (s, mart db)
awaitChar :: [Char] -> IO Char
awaitChar chars = do
input <- getLine
awaitChar2 input chars
awaitChar2 :: String -> [Char] -> IO Char
awaitChar2 [] chars = awaitChar chars
awaitChar2 (x: _) chars = ifThenElse (x `elem` chars) (return x) (awaitChar chars)