Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

incorrect "fromJSON" parsing of Data.Set.Set #107

Closed
mf59816 opened this Issue · 6 comments

4 participants

@mf59816

sets are rendered as lists, but not parsed back into sets. this may be related to #101, #102. i just pulled the head, but problem persists. to reproduce:

{-# LANGUAGE DeriveDataTypeable          #-}

import Control.Applicative ((<$>))
import Data.Aeson.Generic as A
import Data.Aeson.Parser (value)
import Data.Aeson.Types
import Data.Data
import Data.Set
import Data.Typeable

import Data.Attoparsec.Lazy as Parser

data Document =
    Document
      { fromDocument :: Set String
      }
  deriving (Eq, Ord, Show, Read, Data, Typeable)

x1 = A.encode $ Document empty
y1 = A.decode x1 :: Maybe Document

y2 :: Parser.Result (Data.Aeson.Types.Result Document)
y2 = fmap A.fromJSON $ Parser.parse value x1
*Main> x1
Chunk "{\"fromDocument\":[]}" Empty
*Main> y1
Nothing
*Main> y2
Done Empty Error "Data.Aeson.Generic.parseJSON: NoRep(DataType {tycon = \"Data.Set.Set\", datarep = NoRep})"
@bos
Owner

This looks like a job for @basvandijk! :-)

@sol

This bug only occurs with GHC 7.6.1/7.6.2, 7.4.2 works fine. (edit: I just realized that I had containers-0.5.2.1 installed on GHC 7.4.2).

Here is a minimal way to reproduce it:

import Data.Set
import Data.Aeson.Generic

-- expected: Just (fromList [23, 42])
-- actual: Nothing
foo = decode (encode $ fromList [23 :: Int, 42]) :: Maybe (Set Int)
@sol

Hmm, works with containers-0.5.2.1. Maybe a bug in the Typeable instance of Data.Set from containers-0.5.0.0, @tibbe?

@sol

It works since haskell/containers@f1f58da, containers-0.5.2.0 is the first version that includes this commit.

@basvandijk
Collaborator

The way to fix this is to give Data.Aeson.Generic.parseJSON an extension for parsing Sets just like it has extensions for parsing lists, Vectors, Maps, HashMaps, etc. It appears this is done like:

parseJSON :: (Data a) => Value -> Parser a
parseJSON j = parseJSON_generic j
              ...
              `ext1R` setAny
              ...
  where
    vector :: (Data a) => Parser (V.Vector a)
    vector = case j of
               Array js -> V.mapM parseJSON js
               _        -> myFail

    setAny :: Parser (Set.Set a)
    setAny = fmap (Set.fromList . V.toList) vector

The problem is that this gives:

Could not deduce (Ord a1) arising from a use of `Set.fromList'

Other than giving parseJSON an (Ord a) constraint which we shouldn't do, I have no idea how to fix this.

@basvandijk basvandijk referenced this issue from a commit
@basvandijk basvandijk Deprecated Data.Aeson.Generic
The module is deprecated for the following reasons:

- It has issues: #75, #84, #101, #107.

- It's slow compared to GHC Generics and very, very, very slow
  compared to TH. See some recent benchmark results in #116.

- The encoding/decoding can't currently be configured using the
  encoding Options.

- Related to the previous point: GHC Generics and TH use compatible
  encoders/decoders (if the same Options have been
  used). Data.Aeson.Generic does things slightly differently.

- The original author is not around to work on it.
12ed274
@bos
Owner
bos commented

Won't fix, sorry.

@bos bos closed this
@tolysz tolysz referenced this issue from a commit in tolysz/aeson
@basvandijk basvandijk Deprecated Data.Aeson.Generic
The module is deprecated for the following reasons:

- It has issues: #75, #84, #101, #107.

- It's slow compared to GHC Generics and very, very, very slow
  compared to TH. See some recent benchmark results in #116.

- The encoding/decoding can't currently be configured using the
  encoding Options.

- Related to the previous point: GHC Generics and TH use compatible
  encoders/decoders (if the same Options have been
  used). Data.Aeson.Generic does things slightly differently.

- The original author is not around to work on it.
e14c983
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.