Ответ 1
Аргумент String → String
заданный для interact
должен принимать строку, содержащую все входные данные, и возвращать строку, содержащую все выходные данные. Причина, по которой вы видите выходные данные после нажатия клавиши enter с interact (map toUpper)
заключается в том, что map toUpper
действует лениво - он может начать выдавать выходные данные до того, как все входные данные map toUpper
известны. Нахождение длины строки не таково - вся строка должна быть известна до того, как будет получен какой-либо вывод.
Вам нужно либо подать сигнал EOF, чтобы сказать, что вы закончили ввод ввода (в консоли это Control-D в системах Unix/Mac, я полагаю, что это Control-Z в Windows), тогда он даст вам длину. Или вы можете найти длину каждой строки, сказав так:
interact (unlines . map (show . length) . lines)
Это всегда будет ленивым в каждой строке, поэтому вы знаете, что вы можете получить один вывод после каждого ввода.
Так как работа со строками - такой распространенный шаблон, я хотел бы определить небольшую вспомогательную функцию:
eachLine :: (String -> String) -> (String -> String)
eachLine f = unlines . map f . lines
Тогда вы можете сделать:
main = interact (eachLine inputLength)