
Hey With the risk of being annoying, I want to point out that the Grace browser does indeed somewhat support your original use case, because I feel like it might not be something obvious (there also is not an example for it, I think). With the term ``` merge { Number: \n -> "The number is " + Real/show n , Check: \b -> if b then "checked" else "unchecked" } ``` which is equivalent to pattern matching on the input and picking a case, we get html with two radio buttons: * Check - when this is selected, the output is based on whether a checkbox is checked * Number - when this is selected, the output is based on the value in an input text field. Of course, this is still suboptimal - the input text field and checkbox are shown at all times, but I feel like I would have misrepresented the language if I did not point out it does support something like this. Cheers, Georgi On 3/2/23 17:01, Olaf Klinke wrote:
On Thu, 2023-03-02 at 15:51 +0200, Georgi Lyubenov wrote:
Hey Olaf,
This is not an answer to your question, but I was reminded of Grace[0], which is a language with a "browser"[1] that allows you to type in terms and get back webpages based on those terms "automagically", which sounds like exactly what you need. I don't know how it's implemented, so I don't know if it is actually relevant to you, but it is worth noting that Grace itself is implemented in Haskell.
Cheers, Georgi
[0] https://github.com/Gabriella439/grace [1] https://trygrace.dev/
On 3/2/23 12:54, Olaf Klinke wrote:
Dear Cafe,
has anyone ever attempted (and maybe succeeded) in building dynamic forms using one of the Haskell web frameworks (Yesod,Servant,...)? By "dynamic" form I mean a form that changes the number of fields based on selections the user makes in other fields of the form.
For example, say one has an algebraic data type
data T = Number Int | Check Bool T
A form for such a type would initially consist of radio buttons or a drop-down list with options "Number" and "Check" that lets the user select the constructor. When "Number" is selected, an <input type="number"> field is shown. When "Check" is selected, an <input type="checkbox"> is displayed next to another form of this kind.
In the end, one would use the GHC.Generics machinery to generate forms for a wide range of algebraic data types. I've seen this in the Clean language's iTask library [1] and it's very convenient. Of course this would involve a lot of JavaScript like document.createElement() as well as book-keeping how to re-asseble the fields into a T value upon submission. At least the latter is already handled by libraries such as yesod-form.
Olaf
[1] https://cloogle.org/src/#itasks/iTasks/UI/Editor/Generic [2] https://github.com/haskell-servant/servant-swagger/issues/80
Thanks for the pointer!
The Grace README says under Notable Omissions:
Recursion or recursive data types
Grace only supports two built-in recursive types, which are List and JSON, but does not support user-defined recursion or anonymous recursion.
User-defined datatypes
All data types in Grace are anonymous (e.g. anonymous records and anonymous unions), and there is no concept of a data declaration The tutorial shows how Grace function inputs are mapped to forms, where functions with List input indeed have a form that is "dynamic" in the sense I defined. Otherwise there is only one input field per function argument. That means complex types are to be input in JSON syntax and parsed. Instead of a DSL, I'd prefer a shallow embedding into Haskell, so that one can leverage all the available machinery. Yet Grace already goes a long way towards what I am after.
Olaf