[Haskell-cafe] dynamic web form generation for algebraic data types

Georgi Lyubenov godzbanebane at gmail.com
Fri Mar 3 07:58:07 UTC 2023


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
>
>
>
>   
>
>


More information about the Haskell-Cafe mailing list