HTTP-клиент Haskell, использующий ByteString

Я делаю несколько HTTP-запросов и хочу получить соответствующие ответы в виде ByteString вместо String. Я использую HTTP-4000.2.18.

Насколько я могу судить, это именно то, что BufferType для:

чтобы дать пользователю свободу в том, как представлен контент запроса и ответа

Тем не менее, я в недоумении, как заставить его работать. Вот что у меня есть: я создаю запросы, используя функцию с именем getLazyRequest, следующим образом:

getLazyRequest
    :: String                   -- ^URL to fetch
    -> Request Lazy.ByteString  -- ^The constructed request

и тогда я смогу передавать запросы напрямую в простой HTTP. Функция getLazyRequest идентична getRequest за исключением того, что он возвращает запрос с типом ByteString вместо String. Но это не работает.

Полный источник:

import Network.HTTP
import Network.URI ( parseURI )
import qualified Data.ByteString.Lazy as Lazy
import Network.BufferType ( BufferOp(..), BufferType(..) )


main = do
    let req = getLazyRequest "http://hackage.haskell.org/"
    rsp <- simpleHTTP req
    line <- fmap (take 100) (getResponseBody rsp)
    putStrLn ""


getLazyRequest
    :: String                   -- ^URL to fetch
    -> Request Lazy.ByteString  -- ^The constructed request
getLazyRequest urlString =
  case parseURI urlString of
    Nothing -> error ("getLazyRequest: Not a valid URL - " ++ urlString)
    Just u  -> mkRequest GET u

Ошибки:

No instance for (HStream Lazy.ByteString)
  arising from a use of `simpleHTTP'
Possible fix:
  add an instance declaration for (HStream Lazy.ByteString)
In a stmt of a 'do' block: rsp <- simpleHTTP req

No instance for (BufferType Lazy.ByteString)
  arising from a use of `mkRequest'
Possible fix:
  add an instance declaration for (BufferType Lazy.ByteString)
In the expression: mkRequest GET u
In a case alternative: Just u -> mkRequest GET u

Я не понимаю, почему эти ошибки, поскольку Lazy.ByteString является экземпляром обоих HStream и ТипБуфера.

ИЗМЕНИТЬ

Действительно, у меня установлены версии bytestring. Возможно ли, что я установил один из них с помощью sudo, а другой - с помощью моего пользователя?

$ ghc-pkg list bytestring
/var/lib/ghc/package.conf.d
   bytestring-0.9.2.1
/home/adizere/.ghc/x86_64-linux-7.4.1/package.conf.d
   bytestring-0.10.4.1

Я не мог отменить регистрацию ни одной из этих двух версий, поэтому вместо этого я адаптировал код, и теперь он работает.


person adizere    schedule 04.12.2014    source источник
comment
вероятно, установлено несколько пакетов bytestring? что ghc-pkg list bytestring выводит?   -  person Yuras    schedule 04.12.2014
comment
Действительно, у меня было установлено две версии bytestring. Я редактирую свой вопрос, чтобы завершить ответ.   -  person adizere    schedule 05.12.2014


Ответы (2)


Поскольку @user5402 подтвердил правильность вашего кода (по модулю take против Lazy.take), я почти уверен, что у вас установлено несколько версий пакета bytestring. Например. вы импортируете одну версию, но HTTP компилируется с другой.

Отметьте ghc-pkg list bytestring и отмените регистрацию/скройте одну ненужную версию.

Или, что лучше, кабализируйте свой код и/или используйте кабальную песочницу.

См. также: Acid-state: экземпляр MonadState для обновления и https://ghc.haskell.org/trac/ghc/ticket/8278#comment: 2

person Yuras    schedule 04.12.2014

Изменять:

    line <- fmap (take 100) (getResponseBody rsp)

to:

    line <- fmap (Lazy.take 100) (getResponseBody rsp)

Ваш код проверяет тип моей системы с этим изменением.

person ErikR    schedule 04.12.2014