[Haskell-beginners] lens-aeson and error messages

Alexey Shmalko rasen.dubi at gmail.com
Fri Jun 12 06:28:16 UTC 2015


Hi, Thomas!

I would come with implementation similar to this:

 instance FromJSON Row where
    parseJSON = withArray "Row" $ \ a ->
      case Vector.length a of
        3 ->
          Row <$> parseJSON (a ! 0)
              <*> parseJSON (a ! 1)
              <*> parseJSON (a ! 2)
        _ -> fail "Invalid Row."

Hope this helps.

On Fri, Jun 12, 2015 at 7:11 AM, Thomas Koster <tkoster at gmail.com> wrote:
> 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
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


More information about the Beginners mailing list