[Ur] json implementation - need some help understanding what's happening here?

Adam Chlipala adamc at impredicative.com
Tue Dec 14 11:40:27 EST 2010


Marc Weber wrote:
> val json_record : ts ::: {Type}     -- implicit. is automatically inferred
>      ->  folder ts                    -- first arg?
>      ->  $(map json ts)               -- second arg?
>      ->  $(map (fn _ =>  string) ts)   -- third arg?
>      ->  json $ts                     -- result type?
>    

This is just normal function type syntax, so the questions about 
"argument numbering" aren't particularly interesting.  (Your answers are 
correct.)

> 1) map json?
>    Now: What does "map json" exacly mean?

The built-in constructor function [map] applies a function to every 
field of a type-level record, constructing a new record based on the 
results.  It's really just like normal 'map' from functional programming.

> What does mapping over a class (json is a class?) do?
>    

In Ur, a class is just a type-level function, mapping the indices into 
the class internal implementation.  The answer to your question follows 
from that.  Alternatively, another way of putting it is that the 
constructor [map json ts] denotes a type-level record with a field for 
each entry of [ts], where each field contains a [json] instance for the 
appropriate type.

>    Is map described somewhere? It seems to be a primop because its listed
>    in the syntax files and in the lexer file.
>    

The manual gives a complete description of its syntax and semantics, 
though not necessarily in a form accessible to people without expertise 
in semantics.

>    That also seems to be the reason why map is called mp in all
>    remaining files (eg list.ur)
>    

Right.

> 2) number of arguments? I'm still totally missing the point. json_record
>      is used like this:
>
>          type address = {StreetAddress : string,
>                          City : string,
>                          State : string,
>                          PostalCode : string}
>
>
>          val json_address : json address = json_record {StreetAddress = "streetAddress",
>                                                         City = "city",
>                                                         State = "state",
>                                                         PostalCode = "postalCode"}
>      only one argument is passed - however json_record still has 3
>      explicit ones?
>
>        ->  folder ts                    -- first arg?
>        ->  $(map json ts)               -- second arg?
>        ->  $(map (fn _ =>  string) ts)   -- third arg?
>    

The first two are inferred, because they meet Ur's rules for being 
considered type class witnesses.  A folder is always a type class 
witness, and the second argument qualifies because it is a record of 
type class witnesses, which are considered to be witnesses themselves.

>      Which section of the manual do I have to understand so that I can
>      follow what ur is doing here?
>    

I'm not sure it's all documented, but the closest thing I see now is in 
Section 4.3, in the paragraph beginning "Handling of implicit."

> 3) is it possible to write a generic show function which does not
>     require json_record to be called for each possible record type?
>    

It's only possible if you don't want the output to depend on the record 
field names.  Ur provides no way to introspect on the syntax of field names.



More information about the Ur mailing list