[Haskell-beginners] lens-aeson and error messages

Thomas Koster tkoster at gmail.com
Fri Jun 12 04:11:21 UTC 2015


Hi list,

tl;dr - I am using aeson and have an unusual JSON data structure to
parse, so I have implemented the parseJSON function using the prisms
and traversals in the lens-aeson package. Unfortunately, the only error
message I ever get from my parser is "mempty". How can my parser give
better error messages when using lens-aeson?

Consider a need to implement parseJSON for the following type.

  data Row = Row [Text] Int Text

The twist is that the values are in a JSON list, not an object.

  [["a","b","c"], 4, "a title"]

The JSON above should be decoded to the following Haskell value.

  Row ["a", "b", "c"] 4 "a title"

My first FromJSON instance was naive.

  instance FromJSON Row where
    parseJSON = withArray "Row" $ \ a ->
      case Vector.toList a of
        (x : y : z : []) ->
          Row <$> parseJSON x
              <*> parseJSON y
              <*> parseJSON z
        _ -> fail "Invalid Row."

Then I decided that pattern matching a vector like that via an
intermediate list was probably rookie stuff, so I tried lenses (this is
my first attempt at lenses, btw).

  instance FromJSON Row where
    parseJSON v =
      Row <$> (v ^. nth 0 . to parseJSON)
          <*> (v ^. nth 1 . to parseJSON)
          <*> (v ^. nth 2 . to parseJSON)

This looks like it works but now the only error message I get is
"mempty". I think this is because the lens operators are folding with
the Monoid Parser instance where mempty = fail "mempty".

Can I continue to use lenses but produce better error messages? If so,
how? The lens package haddocks baffle me.

Any suggestions to improve my use of lenses are also welcome (e.g. the
expression "to parseJSON" seems so useful that I thought it might be
named in the lens-aeson package. But it isn't, so its absence makes me
suspect that I'm using it incorrectly).

Alternative, non-lens-based suggestions for de-constructing a Vector,
pattern matching its elements, without too many intermediate lists or
tuples are also welcome.

Thanks in advance.

--
Thomas Koster


More information about the Beginners mailing list