[Я могу вернуться и опубликовать код, чтобы следовать этому совету, но если я этого не сделаю, просто попробуйте адаптировать код TomMD, что является шагом в правильном направлении]

ько начал изучать Haskell. Ниже приведен код, написанный в императивном стиле, который реализует простой сервер - он печатает заголовки HTTP-запроса. Помимо того, что мне нужно переосмыслить это в Haskell, работать с отложенными списками и функциями более высокого порядка, я бы хотел ясно видеть, почему он не выполняет то, что я задумал. Он всегда один позади - я нажимаю на него с запросом, ничего не происходит, нажимаю на него снова, он печатает первый запрос, нажимает на него 3 раза, печатает 2-й запрос и т. Д. Почему это так? И каково минимальное изменение в этом коде, которое заставило бы его печатать правильно, когда пришел запрос?

import Network
import System.IO
import Network.HTTP.Headers

acceptLoop :: Socket -> IO ()
acceptLoop s = do
  (handle, hostname, _) <- accept s
  putStrLn ("Accepted connection from " ++ hostname)
  text <- hGetContents handle
  let lns = lines text
      hds = tail lns
  print $ parseHeaders hds
  hClose handle
  acceptLoop s


main :: IO ()
main = do
  s <- listenOn (PortNumber 8080)
  acceptLoop s

спасибо роб

Следовать за

Все ответы были полезны. Приведенный ниже код работает, но пока не использует строки байтов, как это было предложено. Дополнительный вопрос: можетioTakeWhile заменить с помощью некоторых функций из стандартных библиотек, может быть, в Control.Monad?

ioTakeWhile :: (a -> Bool) -> [IO a] -> IO [a]
ioTakeWhile pred actions = do
  x <- head actions
  if pred x
    then (ioTakeWhile pred (tail actions)) >>= \xs -> return (x:xs)
    else return []

acceptLoop :: Socket -> IO ()
acceptLoop s = do
  (handle, hostname, _) <- accept s
  putStrLn ("Accepted connection from " ++ hostname)
  let lineActions = repeat (hGetLine handle)
  lines <- ioTakeWhile (/= "\r") lineActions
  print lines
  hClose handle

Ответы на вопрос(1)

Ваш ответ на вопрос