<div dir="ltr"><div><font face="monospace, monospace">Summary:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Adam's initial guess is totally correct: this is indeed "one of the standard 'newbie' problems with monadic IO, in common with Haskell."</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Specifically, given a "parent" table which contains the following records...</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">     Id  |  Nam</font></div><div><font face="monospace, monospace">  -----------------</font></div><div><font face="monospace, monospace">     1   |  One!</font></div><div><font face="monospace, monospace">     2   |  Two!</font></div><div><font face="monospace, monospace">     3   |  Three!</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">...I want to use monadic IO to run an SQL SELECT transaction to get the above "parent" records, and then use the result to generate the <xml> for a <select> widget (on the "child" record form) that would look like this:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  Widget = (fn [nm :: Name] => </font></div><div><font face="monospace, monospace">    <xml></font></div><div><font face="monospace, monospace">      <select{nm}></font></div><div><font face="monospace, monospace">         <option>One!</option></font></div><div><font face="monospace, monospace">         <option>Two!</option></font></div><div><font face="monospace, monospace">         <option>Three!</option></font></div><div><font face="monospace, monospace">      </select></font></div><div><font face="monospace, monospace">   </xml>)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">My incorrect code looks like this:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  Widget = (fn [nm :: Name] =></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  statusOptions <-</font></div><div><font face="monospace, monospace">    queryX1 (SELECT Id, Nam FROM status ORDER BY Nam)</font></div><div><font face="monospace, monospace">    (fn r => <xml><coption value={r.Id}>{r.Nam}</coption></xml>);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    return;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  (* Another incorrect alternative which I attempted for the above line:</font></div><div><font face="monospace, monospace">     </font></div><div><font face="monospace, monospace">     return statusOptions;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">     I also tried simply OMITTING the above line involving 'return' *)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    <xml></font></div><div><font face="monospace, monospace">      <select{nm}></font></div><div><font face="monospace, monospace">        {statusOptions}</font></div><div><font face="monospace, monospace">      </select></font></div><div><font face="monospace, monospace">    </xml>)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">I understand that the above code needs to be corrected to somehow "separate":</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">- the chunk of monadic IO SQL SELECT transactional code </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">from </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">- the chunk of code used to build the <xml></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">However, I can't figure out where to situate the first, transactional chunk in the context of the above function definition.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Relevance:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">The task at hand (building a data-bound <select> widget to enable users to easily edit a foreign-key field) is:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(a) extremely urgent (because without such a widget, Ur/Web cannot be used to create practical web database applications); and</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(b) probably relatively straightforward (all that is needed is to get the monadic syntax right, in order to grab a value from the SQL SELECT transaction and then use it to build the <xml>).</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Given (a) and (b), I trust that such a question is appropriate to this list, and I hope that someone will eventually be able to provide the correct syntax needed in this case. </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">This will not only help a monadic newbie like me learn the correct syntax - it will also allow me to contribute this urgently needed data-bound <select> widget.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Without a data-bound <select> (or auto-complete / type-ahead widget, which I would also like to work on later), Ur/Web will continue to be unusable for practical web database application development.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Details:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">My attempts to produce the above <xml> from the above SQL include the 3 incorrect examples below:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Widget = (fn [nm :: Name] =></font></div><div><font face="monospace, monospace">statusOptions <-</font></div><div><font face="monospace, monospace">  queryX1 (SELECT Id, Nam FROM status ORDER BY Nam)</font></div><div><font face="monospace, monospace">  (fn r => <xml><coption value={r.Id}>{r.Nam}</coption></xml>);</font></div><div><font face="monospace, monospace">  return;</font></div><div><font face="monospace, monospace">  <xml></font></div><div><font face="monospace, monospace">    <select{nm}></font></div><div><font face="monospace, monospace">      {statusOptions}</font></div><div><font face="monospace, monospace">    </select></font></div><div><font face="monospace, monospace">  </xml>)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Widget = (fn [nm :: Name] =></font></div><div><font face="monospace, monospace">statusOptions <-</font></div><div><font face="monospace, monospace">  queryX1 (SELECT Id, Nam FROM status ORDER BY Nam)</font></div><div><font face="monospace, monospace">  (fn r => <xml><coption value={r.Id}>{r.Nam}</coption></xml>);</font></div><div><font face="monospace, monospace">  return statusOptions;</font></div><div><font face="monospace, monospace">  <xml></font></div><div><font face="monospace, monospace">    <select{nm}></font></div><div><font face="monospace, monospace">      {statusOptions}</font></div><div><font face="monospace, monospace">    </select></font></div><div><font face="monospace, monospace">  </xml>)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Widget = (fn [nm :: Name] =></font></div><div><font face="monospace, monospace">statusOptions <-</font></div><div><font face="monospace, monospace">  queryX1 (SELECT Id, Nam FROM status ORDER BY Nam)</font></div><div><font face="monospace, monospace">  (fn r => <xml><coption value={r.Id}>{r.Nam}</coption></xml>);</font></div><div><font face="monospace, monospace">  <xml></font></div><div><font face="monospace, monospace">    <select{nm}></font></div><div><font face="monospace, monospace">      {statusOptions}</font></div><div><font face="monospace, monospace">    </select></font></div><div><font face="monospace, monospace">  </xml>)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(See also Note [1] at the end of this post.)</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">The type error from the compiler produced by the first fragment above can be seen here:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><a href="https://github.com/StefanScott/urweb-crud2foreign/issues/1">https://github.com/StefanScott/urweb-crud2foreign/issues/1</a><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Survey of the Ur/Web literature, searching for relevant similar examples:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">For the current use case (extracting a value from an SQL SELECT transaction in order to build an <xml> fragment compatible with the Crud2 demo), I searched for any Ur/Web examples which might provide something close to the syntax I needed. </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">The closest examples I could find in Ur/Web are the Crud2 demo, and the chat room PDF (as mentioned in my original post here:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><a href="http://www.impredicative.com/pipermail/ur/2015-July/002064.html">http://www.impredicative.com/pipermail/ur/2015-July/002064.html</a> </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Also, the UPO jfac example (excerpted below) seems highly relevant.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">A more complete list of relevant (and possibly relevant) examples is shown below:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Relevant - the "Crud2 demo":</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(1) <a href="http://www.impredicative.com/ur/demo/crud2.html">http://www.impredicative.com/ur/demo/crud2.html</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(2) <a href="https://github.com/urweb/urweb/blob/master/demo/crud.urs">https://github.com/urweb/urweb/blob/master/demo/crud.urs</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(3) <a href="https://github.com/urweb/urweb/blob/master/demo/crud.ur">https://github.com/urweb/urweb/blob/master/demo/crud.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(4) <a href="https://github.com/urweb/urweb/blob/master/demo/crud2.ur">https://github.com/urweb/urweb/blob/master/demo/crud2.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Relevant - the "chat room PDF":</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(5) <a href="http://adam.chlipala.net/papers/UrWebPOPL15/UrWebPOPL15.pdf">http://adam.chlipala.net/papers/UrWebPOPL15/UrWebPOPL15.pdf</a> - the "chat room PDF"</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Relevant - the "jfac" example from UPO:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(6) <a href="https://github.com/achlipala/upo/blob/master/examples/jfac.ur">https://github.com/achlipala/upo/blob/master/examples/jfac.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Possibly relevant:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(7) <a href="https://github.com/urweb/urweb/blob/master/demo/form.ur">https://github.com/urweb/urweb/blob/master/demo/form.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(8) <a href="https://github.com/urweb/gui/blob/master/select.ur">https://github.com/urweb/gui/blob/master/select.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(9) <a href="https://github.com/urweb/urweb/blob/master/tests/cselect.ur">https://github.com/urweb/urweb/blob/master/tests/cselect.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(10) <a href="https://github.com/achlipala/upo/blob/master/chooseForeign.urs">https://github.com/achlipala/upo/blob/master/chooseForeign.urs</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(11) <a href="https://github.com/achlipala/upo/blob/master/chooseForeign.ur">https://github.com/achlipala/upo/blob/master/chooseForeign.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Note: I expect (8) and (9) to be relevant only *later*: when I attempt build on the results of the <select> widget, in order to create an auto-complete or type-ahead widget. This is also highly relevant for using Ur/Web to create practical web database applications, as it a type-ahead / auto-complete widget would support vastly more items in the drop-down. However, it will be more complicated to create, because (a) instead of relying on the HTML5 <select> element, it will instead need to use something like two separate elements: one where the user can enter some characters, and another to display the results, and (b) it will involve using Ur/Web's FRP facilities, including syntax such as source, signal, set, and get.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Difficulties:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(1) The types involved in the three most relevant examples (the Crud2 demo, the chat room PDF and the UPO jfac example) are not compatible, so the output from the SQL SELECT transaction needs to be modified somehow in order to be able to use it to build the <xml> fragment. </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(2) The UPO jfac example (shown below) effectively separates the monadic SQL SELECT transaction from the <xml> fragment - with lots of further-indented intervening code in between. I have been able to figure out how to do a similar kind of "separation" in my code.</font></div><div><br></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Possibly very relevant code from the UPO jfac example, here:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><a href="https://github.com/achlipala/upo/blob/master/examples/jfac.ur">https://github.com/achlipala/upo/blob/master/examples/jfac.ur</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  restaurants <- queryX1 (</font></div><div><font face="monospace, monospace">    SELECT restaurant.RestaurantName, restaurant.Neighborhood</font></div><div><font face="monospace, monospace">    FROM restaurant</font></div><div><font face="monospace, monospace">    ORDER BY restaurant.RestaurantName, restaurant.Neighborhood)</font></div><div><font face="monospace, monospace">    (fn r => <xml></font></div><div><font face="monospace, monospace">               <coption value={r.RestaurantName ^ "^" ^ r.Neighborhood}>{[r.RestaurantName]}</font></div><div><font face="monospace, monospace">                 {case r.Neighborhood of</font></div><div><font face="monospace, monospace">                      "" => <xml/></font></div><div><font face="monospace, monospace">                    | s => <xml>({[s]})</xml>}</coption></xml>);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">[ ... many more lines of further-indented code ... ]</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  <div class="form-group"></font></div><div><font face="monospace, monospace">  <label>Where?</label></font></div><div><font face="monospace, monospace">  <cselect source={whichR} class="form-control"></font></div><div><font face="monospace, monospace">  {restaurants}</font></div><div><font face="monospace, monospace">  </cselect></font></div><div><font face="monospace, monospace">  </div></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">I naively tried to model my code on the above UPO jfac example, while also taking into account the code from the Crud2 demo and the chat room PDF.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">I now see that the "many more lines of further-indented code" in the middle of the UPO jfac example are somehow essential, in that they perform the necessary "separation" of the transactional SQL code from the <xml> fragment being built.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">My code is incorrectly lumping everything together into one sequence, doing the following:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">- running the SQL transaction and assigns the resulting value to identifier 'statusOptions'</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">- using (a 'return' and) a semi-colon</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">- immediately attempting to return the <xml></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">So I need to somehow completely separate the transactional code which assigns a value to 'statusOptions' from the code which generates the <xml>.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">I just can't figure out how to do this.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Further information:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">In my original post, I did the following:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(a) created a github repo containing an initial, oversimplified (and working!) test case, just to make sure I wrote the non-monadic part of the code correctly:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><a href="https://github.com/StefanScott/urweb-crud2local">https://github.com/StefanScott/urweb-crud2local</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(b) created a separate (non-working!) github repo adding the monadic code:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><a href="https://github.com/StefanScott/urweb-crud2foreign">https://github.com/StefanScott/urweb-crud2foreign</a></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">(c) copied the compiler error message from (b) into an Issue in the same github repo, to help with diagnosis (while also trying to avoid cluttering this list with lengthy compiler output):</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><a href="https://github.com/StefanScott/urweb-crud2foreign/issues/1">https://github.com/StefanScott/urweb-crud2foreign/issues/1</a> </font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">I understand that people are busy, so my goal has been to present the question as clearly and conveniently as possible, in order to make it as painless as possible for someone in the Ur/Web community to provide an answer, so that I can create a data-bound <select> to allow users to easily edit foreign-key fields, which is essential in order for programmers to be able to use Ur/Web to be used to develop practical web database applications.</font></div><div><font face="monospace, monospace"><br></font></div><div><br></div><div><font face="monospace, monospace">Note [1]:</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">More generally, we would want the following <xml> fragment which includes the 'value' attribute. </font></div><div><font face="monospace, monospace"><br></font></div><div><span style="font-family:monospace,monospace">  Widget = (fn [nm :: Name] => </span><br></div><div><font face="monospace, monospace">    <xml></font></div><div><font face="monospace, monospace">      <select{nm}></font></div><div><font face="monospace, monospace">         <option value="1">Local One!</option></font></div><div><font face="monospace, monospace">         <option value="2">Local Two!</option></font></div><div><font face="monospace, monospace">         <option value="3">Local Three!</option></font></div><div><font face="monospace, monospace">      </select></font></div><div><font face="monospace, monospace">   </xml>)</font></div><div><font face="monospace, monospace"><br></font></div><div><span style="font-family:monospace,monospace">But in this case we actually don't need the 'value' attribute shown above, because...</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">- the uniqueness of the 'Nam' column in "parent" table; and </span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">- the way the Parse function happens to work in this case of Crud2 (obtaining Nam from Id)</span></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">... avoids the need for this. </span><font face="monospace, monospace"><br></font></div><div><span style="font-family:monospace,monospace"><br></span></div><div><font face="monospace, monospace">###</font></div><div><br></div></div>