Я только начал изучать Haskell. Ниже приведен код, написанный в императивном стиле, который реализует простой сервер - он распечатывает заголовки HTTP-запроса. Помимо того факта, что мне нужно переосмыслить его в Haskell, чтобы работать с ленивыми списками и функциями более высокого порядка, я хотел бы четко понять, почему он не делает то, что я планировал. Он всегда один позади - я нажимаю на него запрос, ничего не происходит, нажимаю снова, он печатает первый запрос, нажимает его в третий раз, он печатает второй запрос и т. Д. Это почему? И какое минимальное изменение в этом коде привело бы к тому, что он печатал сразу, когда поступил запрос?
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