5

In my Haskell Program I need to work with Strings and ByteStrings:

import Data.ByteString.Lazy as BS  (ByteString)
import Data.ByteString.Char8 as C8 (pack)
import Data.Char                   (chr)

stringToBS :: String -> ByteString
stringToBS str = C8.pack str

bsToString :: BS.ByteString -> String
bsToString bs = map (chr . fromEnum) . BS.unpack $ bs

bsToString works fine, but stringToBS results with following error at compiling:

Couldn't match expected type ‘ByteString’
                with actual type ‘Data.ByteString.Internal.ByteString’
    NB: ‘ByteString’ is defined in ‘Data.ByteString.Lazy.Internal’
        ‘Data.ByteString.Internal.ByteString’
          is defined in ‘Data.ByteString.Internal’
    In the expression: pack str
    In an equation for ‘stringToBS’: stringToBS str = pack str

But I need to let it be ByteString from Data.ByteString.Lazy as BS (ByteString) for further working functions in my code.

Any idea how to solve my problem?

Martin Fischer
  • 697
  • 1
  • 6
  • 27
  • BTW, I hope you know what you are doing. A `ByteString` is a sequence of bytes, and not a string: conversion between them fundamentally depends on a given encoding. In particular, `Char8` assumes that everything is encoded using latin-1, and silently truncates everything else. – chi May 09 '16 at 18:24
  • 1
    Is there a particular reason why you are using `String` and not `Text` the conversion with encoding/decoding is a bit more straightforward. – epsilonhalbe May 09 '16 at 20:09
  • Because my other functions requires String – Martin Fischer May 09 '16 at 22:14

2 Answers2

4

You are working with both strict ByteStrings and lazy ByteStrings which are two different types.

This import:

import Data.ByteString.Lazy as BS  (ByteString)

makes ByteString refer the lazy ByteStrings, so the type signature of your stringToBS doesn't match it's definition:

stringToBS :: String -> ByteString  -- refers to lazy ByteStrings
stringToBS str = C8.pack str        -- refers to strict ByteStrings

I think it would be a better idea to use import qualified like this:

import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString.Char8 as BS

and use BS.ByteString and LBS.ByteString to refer to strict / lazy ByteStrings.

ErikR
  • 51,541
  • 9
  • 73
  • 124
2

You can convert between lazy and non-lazy versions using fromStrict, and toStrict (both functions are in the lazy bytestring module).

jamshidh
  • 12,002
  • 17
  • 31
  • `urlDecode True (stringToBS str)` with `stringToBS str = BS.fromStrict $ C8.pack str` brings me: `Couldn't match expected type ‘Data.ByteString.Internal.ByteString’ with actual type ‘ByteString’` how to solve? – Martin Fischer May 09 '16 at 17:58