fyusuf-a
fyusuf-a

Reputation: 255

How can I avoid an error involving lazy bytestrings?

I tried the following code :

import Network.HTTP.Types
import Data.Text as T
import Data.ByteString.Builder

it = toLazyByteString $ encodePath (Prelude.map T.pack ["foo","bar"]) [(read "stuff",Nothing)]

main = print it

ghci 7.10.3 accepts to give me a type but somehow cannot compute "it" :

"*** Exception: Prelude.read: no parse

ghc 7.10.3 links but gives :

collect2: error: ld returned 1 exit status

What is wrong with this expression ? I know it is an ugly expression and that it may look better with OverloadedStrings, but still, I am perplexed.

Upvotes: 0

Views: 46

Answers (2)

amalloy
amalloy

Reputation: 91837

The thing that puzzled me was what type you were reading the string "stuff" to, so I looked at the types.

encodePath :: [Text] -> Query -> Builder

where Query is an alias for [(ByteString, Maybe ByteString)]. So in this context you are specializing read to:

read :: String -> ByteString

Looking at the relevant Read instance, we see:

instance Read ByteString where
    readsPrec p str = [ (packChars x, y) | (x, y) <- readsPrec p str ]

and

packChars :: [Char] -> ByteString

So, ByteString just delegates to String for reading, and then packs the result. So your code eventually boils down to:

read "stuff" :: String

which fails, of course. There's no String that Shows itself as the five characters stuff.

Rather, it looks to me like you just want to be using T.pack to convert this to a ByteString, just as you do for your other strings.

Upvotes: 2

AJF
AJF

Reputation: 11913

Your expression is 'correct' in a strict sense, that is to say it is well-typed, but your problem is what you're computing here:

read "stuff"

This is actually communicated in the error message:

"*** Exception: Prelude.read: no parse"
--              ^^^^^^^^^^^^
-- The underlined means the exception is due to the `read` function.

(Note that this is not an error – it is an exception, which arises when running the program, not when compiling it.)

I don't know what you were trying to construct when you wrote read "stuff", but there's nothing that "stuff" can be interpreted as, so it fails to parse.

Examples of valid uses of read are: read "0" :: Int, read "True" :: Bool and so on. read "stuff" is meaningless and will naturally cause an exception.

Perhaps you meant maybeRead :: Read a => String -> Maybe a from Data.(Lazy.)Text.Read?

Upvotes: 1

Related Questions