2011-10-03 3 views
11

Podpis typ dla http jest:Dlaczego `http` w wyliczniku http jest Iteratee?

http :: MonadIO m 
    => Request m 
    -> (W.Status -> W.ResponseHeaders -> Iteratee S.ByteString m a) 
    -> Manager 
    -> Iteratee S.ByteString m a 

Dlaczego nie jest to zamiast?

http :: MonadIO m => … -> m a 

Jeśli dobrze rozumiem, Iteratee x m a jest jak monadycznej parsera, który zużywa strumień przedmiotów typu x. Ma to sens, aby wywołanie zwrotne http było Iteratee, ponieważ zużywa ciało odpowiedzi.

Sam w sobie nie wydaje się jednak, aby wprowadzono jakiekolwiek dane wejściowe. Funkcja httpLbs wykonuje http z run_ (zdefiniowane w Data.Enumerator). Z tego, co mogę powiedzieć, run uzna to za błąd, jeśli iteratee podane do niego oczekuje wejścia:

-- | Run an iteratee until it finishes, and return either the final value 
-- (if it succeeded) or the error (if it failed). 
run :: Monad m => Iteratee a m b 
    -> m (Either Exc.SomeException b) 
run i = do 
    mStep <- runIteratee $ enumEOF ==<< i 
    case mStep of 
     Error err -> return $ Left err 
     Yield x _ -> return $ Right x 
     Continue _ -> error "run: divergent iteratee" 

Więc jeśli http nie zużywa wejście, to dlaczego z niego iteratee? Dlaczego nie jest to akcja po prostu MonadIO?

+1

W jaki sposób 'http' nie zużywa danych z połączenia TCP? –

+0

Argumenty pominięte przy użyciu '...' są ważne. Jedna to funkcja, która zwraca Iteratee. – luqui

+0

@luqui: Edytowałem post, aby dołączyć pełny podpis 'http' i wyjaśnić, że jego argument wywołania zwrotnego pochłania dane wejściowe (z tego, co wiem). Dzięki. –

Odpowiedz

6
  1. To nie jest błąd, aby przejść run (lub run_) jest Iteratee że oczekuje wejścia; dlatego najpierw przejdziemy w enumEOF. Jest nieważne, aby Iteratee mógł nadal oczekiwać wejścia po otrzymaniu EOF.
  2. Po pozostawieniu wyniku http w monadzie Iteratee można wykonać wiele akcji w tym samym potoku, na przykład przesyłając dwie odpowiedzi HTTP do pliku.