[elm-discuss] Re: List of all members of a union type
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 elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[elm-discuss] Re: List of all members of a union type
Going back to the original question, why couldn't you use a list of records instead of a union type? Every time I dealt with states, I ended up needing more than just the name and ended up putting it in a database, which more naturally maps to a record. type alias UsState = { name : String , code : String , licenseFormat : String } With the usage you describe so far, records seem a better fit. Unions are more valuable when you need to structure to code against rather than data. You could still pick out specific states for special rules using something like: states |> List.filter (\state -> state.code == "AL") |> List.head HTH -- 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 elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[elm-discuss] Re: List of all members of a union type
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 elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[elm-discuss] Re: List of all members of a union type
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 elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[elm-discuss] Re: List of all members of a union type
I think the problem here is that you're using types as an Enum. There's a bit of a difference between types and Enums. Enums are a set of symbolic values that limit the values that variables of that Enum can take on. Types can act like Enums like you've shown, but they can also be functions. So they are really a different animal. What's really missing is a way to limit values a variable can take on at the *language level*. (Then you could use a *case* statement with the variable). I'm no language expert, but I suspect there are languages that have some form of *constraint-based types*. This is the piece that's missing in Elm. I suspect that this feature is either very difficult to do or a low priority since its use case is rare or maybe it's not even on Evan's radar. Whatever the case may be, I've have always wanted *constraint-based types* and would love to see a language properly implement this (assuming it wouldn't bloat the language unnecessarily). On Tuesday, May 2, 2017 at 8:44:34 PM UTC-7, 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 elm-discuss+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.