<div dir="ltr"><div>Hi,<br><br>I am studying how to do metaprogramming in Ur/Web. After reading the "Type-Level Computation" tutorial (<a href="http://www.impredicative.com/ur/tutorial/tlc.html">http://www.impredicative.com/ur/tutorial/tlc.html</a>), part of the "Ur: Statically-Typed Metaprogramming with Type-Level Record Computation" paper (<a href="http://adam.chlipala.net/papers/UrPLDI10/UrPLDI10.pdf">http://adam.chlipala.net/papers/UrPLDI10/UrPLDI10.pdf</a>) and also looking into the "Ur/Web People Organizer" source code (<a href="https://github.com/achlipala/upo">https://github.com/achlipala/upo</a>) I was able to define a functor that receives three tables as arguments:<br><br>con unitify recordType = map (fn _ => ()) recordType<br><br>functor Make (M : sig<br>          con groupTablePrimaryKeyColumns :: {Type}<br>          con groupTableOtherColumns :: {Type}<br>          constraint groupTablePrimaryKeyColumns ~ groupTableOtherColumns                 <br>          con groupTableOtherConstraints :: {{Unit}}<br>          constraint [Pkey = unitify groupTablePrimaryKeyColumns] ~ groupTableOtherConstraints<br>          val groupTable : sql_table (groupTablePrimaryKeyColumns ++ groupTableOtherColumns)<br>                         ([Pkey = unitify groupTablePrimaryKeyColumns] ++ groupTableOtherConstraints)<br><br>          con rowTablePrimaryKeyColumns :: {Type}<br>          con rowTableOtherColumns :: {Type}<br>          constraint rowTablePrimaryKeyColumns ~ rowTableOtherColumns                 <br>          con rowTableOtherConstraints :: {{Unit}}<br>          constraint [Pkey = unitify rowTablePrimaryKeyColumns] ~ rowTableOtherConstraints<br>          val rowTable : sql_table (rowTablePrimaryKeyColumns ++ rowTableOtherColumns)<br>                       ([Pkey = unitify rowTablePrimaryKeyColumns] ++ rowTableOtherConstraints)<br><br>          con groupRowTablePrimaryKeyColumns :: {Type}<br>          con groupRowTableOtherColumns :: {Type}<br>          constraint groupRowTablePrimaryKeyColumns ~ groupRowTableOtherColumns<br>                 <br>          con groupRowTableOtherConstraints :: {{Unit}}<br>          constraint [Pkey = unitify groupRowTablePrimaryKeyColumns] ~ groupRowTableOtherConstraints<br><br>          val groupRowTable : sql_table (groupRowTablePrimaryKeyColumns ++ groupRowTableOtherColumns)<br>                         ([Pkey = unitify groupRowTablePrimaryKeyColumns] ++ groupRowTableOtherConstraints)<br>          end) = struct<br>end<br><br>table projectTable : {Id : int, Nm : string} PRIMARY KEY Id<br><br>table taskTable : {Id : int, Nm : string} PRIMARY KEY Id<br><br>table projectTaskTable : {ProjectId : int, TaskId : int} PRIMARY KEY (ProjectId, TaskId),<br>      CONSTRAINT PROJECT_ID_IS_FOREIGN_KEY FOREIGN KEY ProjectId REFERENCES projectTable (Id),<br>      CONSTRAINT TASK_ID_IS_FOREIGN_KEY FOREIGN KEY TaskId REFERENCES taskTable (Id)<br><br>structure M = Make (struct<br>            val groupTable = projectTaskTable<br>            val rowTable = taskTable<br>            val groupRowTable = projectTaskTable<br>            end)<br><br></div><div>However, this functor is too permissive, because one can pass to it any three tables. Does the Ur/Web type system allow me to require that groupRowTable contains foreign keys to the group and row tables? If so, could you show me how or point me to a similar example?<br><br></div><div>Sincerely,<br></div><div>Saulo Araujo<br></div></div>