h,&%*      !"#$%&'()0.5.0.1None 01.Structural representation of an object field. Structural representation of ". (I.e. a constant string value.) )This allows for recursive specifications.Since the specification is at the type level, and type level haskell is strict, specifying a recursive definition the "naive" way would cause an infinitely sized type.For example this won't work: data Foo = Foo [Foo] instance HasJsonEncodingSpec Foo where type EncodingSpec Foo = JsonArray (EncodingSpec Foo) toJSONStructure = ... can't be writtenUsing  prevents the specification type from being infinitely sized, but what about "structure" type which holds real values corresponding to the spec? The structure type has to have some way to reference itself or else it too would be infinitely sized.In order to "reference itself" the structure type has to go through a newtype somewhere along the way, and that's what this type is for. Whenever the structure type for your spec requires a self-reference, it will require you to wrap the recursed upon values in this type. For example: data Foo = Foo [Foo] instance HasJsonEncodingSpec Foo where type EncodingSpec Foo = JsonLet '[ '("Foo", JsonArray (JsonRef "Foo")) ] (JsonRef "Foo") toJSONStructure (Foo fs) = [ Rec (toJSONStructure f) | f <- fs ] spec is the Haskell type used to contain the JSON data that will be encoded or decoded according to the provided spec.Basically, we represent JSON objects as "list-like" nested tuples of the form: (Field @key1 valueType, (Field @key2 valueType, (Field @key3 valueType, ()))) recursively encode objects, and is mutually recursive with 1. If we tried to "recurse on the rest of the object" directly in 14 we would end up with a partial function, because 2 returns a 3 not an Object.. We would therefore have to pattern match on 3 to get the Object% back out, but we would have to call error if the 3 mysteriously somehow wasn't an Object after all. Instead of calling error because "it can't ever happen", we use this helper so the compiler can prove it never happens.1 This is like 4, but specialized for our custom "json representation" types (i.e. the  type family). It is also closed (i.e. not exported, so the user can't add instances), because our json representation is closed.see StructureFromJSON3 for an explaination about why we don't just use 4.Types of this class can be encoded to JSON according to a type-level  .The encoding specification. Encode the value into the structure appropriate for the specification. Given a raw Haskell structure, directly encode it directly into an aeson Value without having to go through any To/FromJSON instances. See also: .12None 1$  Analog of   , but specialized for decoding our "json representations", and closed to the user because the haskell representation scheme is fixed and not extensible by the user.We can't just use    because the types we are using to represent "json data" (i.e. the  type family) already have ToJSON instances. Even if we were to make a bunch of newtypes or whatever to act as the json representation (and therefor also force the user to do a lot of wrapping and unwrapping), that still wouldn't be sufficient because someone could always write an overlapping (or incoherent) ToJSON instance of our newtype! This way we don't have to worry about any of that, and the types that the user must deal with when implementing  fromJSONRepr can be simple tuples and such.!Types of this class can be JSON decoded according to a type-level  ." The decoding  . #Given the structural encoding of the JSON data, parse the structure into the final type. The reason this returns a 5 a instead of just a plain a is because there may still be some invariants of the JSON data that the   language is not able to express, and so you may need to fail parsing in those cases. For instance,   is not powerful enough to express "this field must contain only prime numbers".$Directly decode some JSON accoring to a spec without going through any To/FromJSON instances.$!"# 6None%x%Helper for defining 4 and 7 instances based on HasEncodingJsonSpec.Use with -XDerivingVia like: data MyObj = MyObj { foo :: Int , bar :: Text } deriving (ToJSON, FromJSON) via (SpecJSON MyObj) instance HasEncodingSpec MyObj where ... instance HasDecodingSpec MyObj where ...($%&'!"#    ( !"#%&'$ 8        !"#$%&'()*+,,,-./0123456789:;<=>?@ABCADEABFGAH json-spec-0.5.0.1-inplace Data.JsonSpec json-specData.JsonSpec.Spec Data.TimeUTCTimeData.JsonSpec.Encode eitherDecodeData.JsonSpec.Decode Data.AesonFromJSONFieldTagRecunRec JSONStructure::?::: FieldSpecRequiredOptional Specification JsonObject JsonStringJsonNumJsonInt JsonArrayJsonBool JsonNullable JsonEitherJsonTag JsonDateTimeJsonLetJsonRefJsonRawunFieldHasJsonEncodingSpec EncodingSpectoJSONStructureencodeStructureFromJSONHasJsonDecodingSpec DecodingSpecfromJSONStructureSpecJSON unSpecJson$fFromJSONSpecJSON$fToJSONSpecJSON ghc-internalGHC.Internal.RecordsHasFieldghc-prim GHC.TypesBoolscientific-0.3.8.0-f4d235e38ca75a3856362d6094726140a95280d098364abf44f90f8bb4b1b694Data.Scientific Scientifictext-2.1.1-ac74Data.Text.InternalTextsymJStruct ToJSONObjectStructureToJSON reprToJSONaeson-2.2.3.0-12b7710b866d4cabb21c48f6fa19dd1c51b4352be3be3ce9a18059c93459e6daData.Aeson.Types.InternalValueData.Aeson.Types.ToJSONToJSONParser reprParseJSONData.Aeson.Types.FromJSON