эквивалент Haskell для итерации - это рекурсия. Вам также необходимо будет работать в монаде IO
, если вам нужно прочитать строки ввода. Общая картина:
import Control.Monad
main = do
line <- getLine
unless (line == "q") $ do
-- process line
main
Если вы просто хотите, чтобы аккумулировать все линии чтения в content
, вы не должны делать это. Просто используйте getContents
, который будет получать (лениво) все пользовательские ввод. Просто остановитесь, когда увидите 'q'
. В довольно идиоматической Haskell, все чтение может быть сделано в одной строке кода:
main = mapM_ process . takeWhile (/= "q") . lines =<< getContents
where process line = do -- whatever you like, e.g.
putStrLn line
Если вы читали первую строку кода справа налево, он говорит:
прибудете все, что пользователь будет предоставлять в качестве входных данных (никогда не бойтесь, это лениво);
разделить его на линии, когда он наступит;
принимают только линии, если они не равны «q», останавливаются, когда вы видите такую линию;
и позвоните по номеру process
для каждой строки.
Если вы еще не поняли это, вам необходимо внимательно изучить учебник Haskell!
Теперь, вы действительно напишете это в Haskell? Добавление 'line' в' contents' каждый раз дает вам плохую производительность. «Содержимое», которое вы хотите в конце, является префиксом того, что вам даст один вызов 'getContents'. – nickie
Это справедливый момент, но я подумал, что стоит объяснить, как это сделать «с нуля», чтобы почувствовать работу в монаде IO (что, вероятно, является самой запутанной частью Haskell для новичков). Он также имеет преимущество в том, чтобы отделить пользовательский ввод от обработки, которая будет выполняться во входе, что ваш ответ не делает. Я добавлю приложение о 'getContents.' –
ОК, сделанный пункт, я возвращаю свой начальный -1. Но, образовательные цели остались в стороне, я бы рассмотрел код, как этот плохой Haskell. Для людей, которые заботятся, по крайней мере ... :-) – nickie