comparison demo/prose @ 421:0767d7ad0c3a

Crud demo
author Adam Chlipala <adamc@hcoop.net>
date Thu, 23 Oct 2008 18:18:51 -0400
parents 9119a5920106
children 0ce90d4d9ae7
comparison
equal deleted inserted replaced
420:9119a5920106 421:0767d7ad0c3a
119 <p>The functor use in <tt>Metaform1</tt> is trivial. The compiler infers the value of the structure member <tt>fs</tt> from the type of the value provided for <tt>names</tt>.</p> 119 <p>The functor use in <tt>Metaform1</tt> is trivial. The compiler infers the value of the structure member <tt>fs</tt> from the type of the value provided for <tt>names</tt>.</p>
120 120
121 metaform2.urp 121 metaform2.urp
122 122
123 <p>This example showcases code reuse by applying the same functor as in the last example. The <tt>Metaform2</tt> module mixes pages from the functor with some new pages of its own.</p> 123 <p>This example showcases code reuse by applying the same functor as in the last example. The <tt>Metaform2</tt> module mixes pages from the functor with some new pages of its own.</p>
124
125 crud1.urp
126
127 <p>This example pulls together much of what we have seen so far. It involves a generic "admin interface" builder. That is, we have the <tt>Crud.Make</tt> functor, which takes in a description of a table and outputs a sub-application for viewing and editing that table.</p>
128
129 <p>The signature of <tt>Crud.Make</tt> is based around a type function <tt>colMeta</tt>, which describes which supporting values we need for each column. This function is declared with the keyword <tt>con</tt>, which stands for "constructor," the general class of "compile-time things" that includes types. An argument to <tt>colMeta</tt> has kind <tt>(Type * Type)</tt>, which means that it must be a type-level tuple. The first type is how the column is represented in SQL, and the second is how we represent it in HTML forms. In order, the components of the resulting record give:
130
131 <ol>
132 <li> A display name</li>
133 <li> A way of pretty-printing values of the column</li>
134 <li> A way of generating an HTML form widget to input this column</li>
135 <li> A way of generating an HTML form widget with an initial value specified</li>
136 <li> A way of parsing values of the column from strings</li>
137 <li> A type class witness, showing that the SQL representation can really be included in SQL</li>
138 </ol></p>
139
140 <p>The function <tt>colsMeta</tt> lifts <tt>colMeta</tt> over type-level records of type pairs. The <tt>Crud</tt> module also defines reasonable default <tt>colMeta</tt> values for some primitive types.</p>
141
142 <p>The functor signature tells us (in order) that an input must contain:
143
144 <ol>
145 <li> A type pair record <tt>cols</tt></li>
146 <li> A proof that <tt>cols</tt> does not contain a field named <tt>Id</tt></li>
147 <li> A SQL table <tt>tab</tt> with an <tt>Id</tt> field of type <tt>int</tt> and other fields whose names and types are read off of <tt>cols</tt></li>
148 <li> A display title for the admin interface</li>
149 <li> A record of meta-data for the columns</li>
150 </ol></p>
151
152 <p>Looking at <tt>crud1.ur</tt>, we see that a use of the functor is almost trivial. Only the value components of the argument structure must be provided. The column row type is inferred, and the disjointness constraint is proved automatically.</p>
153
154 <p>We won't go into detail on the implementation of <tt>Crud.Make</tt>. The types of the functions used there can be found in the signatures of the built-in <tt>Basis</tt> module and the <tt>Top</tt> module from the standard library. The signature of the first and the signature and implementation of the second can be found in the <tt>lib</tt> directory of the Ur/Web distribution.</p>