[Ur] type system expressivity

Gergely Buday gbuday at gmail.com
Mon Oct 3 09:33:58 EDT 2011


>> I have a data structure that is a list of records, and in the records
>> there might be lists as fields.
>>
>> Is it possible to write a generic map function in ur/web that applies
>> a function for every basic value in this structure, i.e. those that
>> are not records and not lists?
>>
>
> Could you provide a bit more context?  A single function can't be expected
> to do much useful work on values of arbitrary "basic" types.

Look at the following code. This works on every record:

fun sourceRecord [ r ::: {Type} ] (fl : folder r) (record : $r) :
(transaction $(map source r)) =
	    @Monad.mapR _ [id] [source]  (fn [nm :: Name] [t :: Type]  =>
source  ) fl record

This works on every list:

fun sourceList [t] ( xs : list t ) = @List.mapM _ source xs

This is a record list I was talking about, and that one I would like
to sourcify:

val recordList =  { Count = 2, Number = 3, List = "Joe" :: "Jack" ::
"James" :: [] } :: { Count = 4, Number = 4, List = "Mary" :: "Jane" ::
[] } :: []

I wrote a function for this specfic type of record:

fun sourcify ( r : list { Count : int, Number : int, List : list string } ) :
     transaction (list ( { Count : source int, Number : source int,
List : list (source string) }) )=
    let
        fun src' acc r =
         case r of [] => return (List.rev acc)
       | { Count = count, Number = number, List = lst } :: rest =>
              c <- source count;
              n <- source number;
              listS <- sourceList lst ;
              src' ({ Count = c, Number = n, List = listS } :: acc) rest
     in src' [] r
    end

and it compiles with the following dummy code:

fun main () =
    values <- sourceRecord {A = "A", B = "2", C = 152 };
    ws <- sourceList ( 1 :: 2 :: 3 :: []);
    rs <- sourcify recordList;
    let
        fun loop () =
            set values.A "B";
            sleep 1000;
            set values.A "A";
            sleep 1000;
            loop ()
     in
        return
           <xml>
             <body onload={spawn (loop ())}>
                <dyn signal={s <- signal values.A; return <xml>A =
{[s]}</xml>}/>
             </body>
           </xml>
    end

Now the question is: can this be written in a generic way, so that I
need not specify the field names and which field does contain a list?

- Gergely



More information about the Ur mailing list