Search code examples
httphaskellbytestringhttp-conduit

ByteString expects different ByteString


This code doesn't typecheck:

import Network.HTTP.Conduit
import qualified Data.ByteString.Char8 as BS

main :: IO ()
main = do
  resp <- simpleHttp "http://www.google.com"
  putStrLn $ BS.unpack resp

Throws the following error:

Couldn't match expected type `BS.ByteString'
            with actual type `Data.ByteString.Lazy.Internal.ByteString'
In the first argument of `BS.unpack', namely `resp'
In the second argument of `($)', namely `BS.unpack resp'
In a stmt of a 'do' block: putStrLn $ BS.unpack resp
Failed, modules loaded: none.

How to fix this ? Changing to other ByteString variant doesn't work.

The type of simpleHttp function is like this: simpleHttp :: Control.Monad.IO.Class.MonadIO m => String -> m Data.ByteString.Lazy.Internal.ByteString. So I try to get the ByteString within the IO monad and try to unpack it, but this results in an error.


Solution

  • There are two separate ByteString modules, one for lazy ByteStrings and one for strict ByteStrings. simpleHTTP returns a lazy bytestring but you imported the strict bytestring module so unpack is expecting a strict bytestring.

    Try changing

    import qualified Data.ByteString.Char8 as BS
    

    to

    import qualified Data.ByteString.Lazy.Char8 as BS
    

    That said, you need to be careful if you use the Char8 version of the bytestring modules, since the String <-> ByteString conversions only work if you use ASCII encoding. I would recommend converting your bytestrings to Text with an appropriate encoding function and then printing that.