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.