[Haskell-cafe] Instance classes and error (also, related to Data.Binary.GET)

Clive Brettingham-Moore haskell at brettingham-moore.net
Thu Jan 3 21:38:54 EST 2008

Like the previous no experience with Data.Binary, but my (rusty) monad
experience is enough to see the source of the problem:
bbrown wrote:
> The issue stems from here, it says I didn't define an instance, but I did:
> instance Binary URLSet where
>     put _ = do BinaryPut.putWord8 0
>     get = do
>       remainingByteData <- BinaryGet.getRemainingLazyByteString
>       i :: URLInfo <- decode remainingByteData
>       j :: TitleInfo <- decode remainingByteData
>       k :: DescrInfo <- decode remainingByteData
>       x :: KeywordsInfo <- decode remainingByteData
>       return (URLSet {urlinfo=i, titleinfo=j, 
>                       descrinfo=k, keywordsinfo=x})
Data.Binary seems to use the Get monad which looks to be a garden
variety parsing monad.

For  line in the do block:

      i :: URLInfo <- decode remainingByteData

Because of the way do notation works x::a <- is expecting a value of M a
for a monad M, above Get URLInfo, inplying a type of ByteString -> (Get
URLInfo) for decode and therefore the comiler is looking for the
corresponding Binary instance (and of course, not finding it since,
quite properly, your binary instance is URLInfo not Get URLInfo). If you
can't follow this, find a monad tutorial and look at how do notation
expands to >>= and >>.

The code you have almost certainly isn't doing what you want/expect
(even if you fix the bad monad nesting you are trying to repeatedly
decode the same data as different types). Not knowing exactly how your
data is encoded it is hard to be certain of the correct code but
something like this seems more likely (untried):

instance Binary URLSet where
    put _ = do BinaryPut.putWord8 0
    get = do
      i :: URLInfo <- get
      j :: TitleInfo <- get
      k :: DescrInfo <- get
      x :: KeywordsInfo <- get
      return (URLSet {urlinfo=i, titleinfo=j,
                      descrinfo=k, keywordsinfo=x})

This assumes that the data contains the structures serialized in order.
In this case for i the type of get is inferred to Get URLInfo - which
will work since URLInfo has a Binary instance.

You also have a similar issue in the SpiderDatabase instance.


More information about the Haskell-Cafe mailing list