OCaml has a set of extension points.  You can write OCaml code, add it to 
an extension point (`derived` is precisely the use case of this) and it 
receives the AST of the expression and can transform it or add new code or 
whatever as you wish.  Like a very common one for auto-json conversion 
works like (example taken from docs):
```ocaml
type geo = {
  lat : float;
  lon : float;
}
[@@deriving yojson]
```
And this generates two functions in the module with the types of:
```ocaml
val geo_of_yojson : Yojson.Safe.json -> (ty, string) Result.result
val geo_to_yojson : ty -> Yojson.Safe.json
```
And they have a set of options so you can override the key names in the 
json or override the variant names or change the encoding of things like, 
oh, integers or specify a default value if it is missing and so forth. 
 Extension points like this in Elm would save on *so* much manually made 
code in so many cases...


On Friday, May 5, 2017 at 11:57:35 PM UTC-6, Simon wrote:
>
> I had a different use case for the same basic idea. With GraphQL we have a 
> sort-of typed query language that returns clearly defined json structures. 
> In an ideal world therefore you should be able to define an Elm data 
> structure (sum or union type) and for library functions to be able to 
> create the query string and the json decoder for you. I may be over 
> optimistic, and such things may not even be possible in other ML-family 
> languages, but it felt like something that should be automatable
>
>
>
> On Thursday, 4 May 2017 04:14:03 UTC+2, Matt Hughes wrote:
>>
>> At first I wondered if a type is really what you need for this 
>> application, as opposed to say a list of strings. Anyway one idea is to 
>> write a function to explicitly convert the type to a string. I think this 
>> is better than simply taking the type name and making it a string because 
>> the string representation may need spaces or other punctuation. Using an 
>> explicit case means the compiler won't let you forget if you add a new 
>> type. 
>>
>> module Main exposing (..)
>>
>> import Html exposing (Html, text)
>>
>> type Province = Alberta | BritishColumbia | Saskatchewan
>>
>> toString : Province -> String
>> toString p =
>>     case p of
>>         Alberta -> "Alberta"
>>         BritishColumbia -> "British Columbia"
>>         Saskatchewan -> "Saskatchewan"
>>
>> main : Html a
>> main =
>>     text (toString Alberta)
>>
>> mch
>>
>> On Tuesday, May 2, 2017 at 9:44:34 PM UTC-6, Matthew Buscemi wrote:
>>>
>>> I have run into a problematic use case a couple of times, and based on 
>>> Slack discussions earlier today, it seems I'm not alone.
>>>
>>> The situation occurs when, for some reason, I need to maintain a list of 
>>> all constructors of a union type. The example given in Slack by mltsy:
>>>
>>> type State = Alabama | Alaska | Arizona | Arkansas | ...
>>>
>>> allStates = [ Alabama, Alaska, Arizona, Arkansas, ...]
>>>
>>> stateSelectBox : List State -> Html Msg
>>> stateSelectBox states =
>>>   let stateValues = List.map toString states
>>>   in ...
>>>
>>> In the example above, simply turning allStates into a list of strings 
>>> would be fine for this particular use case, but in the context of a larger 
>>> system, it could be inadequate–other functions besides stateSelectBox may 
>>> want to utilize the power of performing a case over the union type. 
>>> However, the above solution is also structurally undesirable–if a new type 
>>> is added to State, then the programmer must also remember to update 
>>> allStates separately. The duplication and tight coupling are disconcerting, 
>>> and yet I can't see a viable alternative that preserves the power of types 
>>> without incurring the duplication.
>>>
>>> I have wondered if a language-level construct that takes a union type 
>>> and returns a list of all constructors for that type would be appropriate 
>>> for Elm. Just a thought.
>>>
>>> - Matt
>>>
>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to