3

I'm having trouble finding a function or workaround to convert a String to Data.ByteString.Lazy.Internal.ByteString

One of the functions in the Aeson Json library is decode and has the following description:

decode :: FromJSON a => bytestring-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString -> Maybe a

I've tried using the pack function in Data.ByteString.Lazy.Char8 but that returns a different ByteString. Any one know how this can be fixed?

The following is the example I'm working on:

import Data.Aeson
import Data.Text
import Control.Applicative
import Control.Monad (mzero)
import qualified Data.ByteString.Lazy.Internal as BLI
import qualified Data.ByteString.Lazy.Char8 as BSL

data Person = Person 
    { name :: Text
    , age :: Int 
    } deriving Show

instance FromJSON Person where 
    parseJSON (Object v) = Person <$>
                   v .: (pack "name") <*>
                   v .: (pack "age")
    parseJSON _          = mzero

I tried using decode (BSL.pack "{\"name\":\"Joe\",\"age\":12}") :: Maybe Person and got the following error message:

Couldn't match expected type `bytestring-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString'
                with actual type `BSL.ByteString'
    In the return type of a call of `BSL.pack'
    In the first argument of `decode', namely
      `(BSL.pack "{\"name\":\"Joe\",\"age\":12}")'
    In the expression:
        decode (BSL.pack "{\"name\":\"Joe\",\"age\":12}") :: Maybe Person

Help!

MathanMV
  • 412
  • 1
  • 5
  • 16
  • 2
    Do you have multiple versions of bytestring installed? Try running `ghc-pkg list bytestring` to check. – bennofs Dec 12 '13 at 21:23
  • The list comes up with two items bytestring-0.10.0.2 and bytestring-.10.4.0 - will this cause an issue? I know I had a GHCI linking error earlier when I was playing around with the code above. – MathanMV Dec 12 '13 at 21:41
  • 1
    Yes, I had to unregister bytestring-10.4.0 to get it to work. – MathanMV Dec 12 '13 at 22:10

2 Answers2

5

You need to convert Char to Word8 using c2w (in Data.ByteString.Internal)

Data.ByteString.Lazy.pack $ map c2w "abcd"

I wrote out the fully qualified name for pack also to guarantee using the correct one, but you can clean this up in the imports section. When I run

> :t Data.ByteString.Lazy.pack $ map c2w "abcd"

I get ":: Data.ByteString.Lazy.Internal.ByteString"

Remember that Data.ByteString.Lazy represents strings of number values (you can't even run its pack on strings, you need to supply an array of numbers "pack [1, 2, 3, 4]"), so you might actually want to use the char equivalent Data.ByteString.Lazy.Char8.

jamshidh
  • 12,002
  • 17
  • 31
  • I managed to get the correct type using this. So I am getting Data.ByteString.Lazy.Internal.ByteString but now its asking for byteString-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString. Hmm I think this might be an issue bennofs commented on the original post because I have two versions of bytestrings? – MathanMV Dec 12 '13 at 22:04
  • There very well might be a version problem, but remember that even within a single version of the libraries, there are four bytestrings- strict/Word8, strict/Char8, lazy/Word8 and strict/Char8.... and pack will only directly work on a string for the Char8 versions. – jamshidh Dec 12 '13 at 22:12
  • Brilliant had another issue with two bytestrings being installed which has also been fixed as mentioned in the comment in the original post. Thank you! – MathanMV Dec 12 '13 at 22:16
0

You can also use for convenience fromString from Data.ByteString.Lazy.UTF8 from utf8-string.

It's a module of functions for the same ByteString type as aeson uses. It relyies on UTF8 as the encoding used in the buffers.

imz -- Ivan Zakharyaschev
  • 4,921
  • 6
  • 53
  • 104