On Monday, August 15, 2016 at 12:25:49 AM UTC-6, Aaron VonderHaar wrote:
>
> Can you give more details about an example of where doing nested record 
> updates is useful?  When I've run into nested records in real projects, 
> usually it's a better choice to remove the nested update.
>

I tend to prefer nested records when they follow the view callpath.  That 
way I just have to copy, in most of my cases, their Location descriptor and 
the specific view state.  I then mutate the view states in the model.  I 
prefer to have the model match the view so things that are subparts of 
something else make sense, else my main model would by 200+ keys large.


On Monday, August 15, 2016 at 12:25:49 AM UTC-6, Aaron VonderHaar wrote: 

> Here are two ways to do that:
>
> 1) flatten the record
>
> This is appropriate when a single module is dealing with a bunch of things 
> that don't actually need to be nested:
>
> Instead of this:
> type alias Course =
>     { teacher : { id : Int, name : String } }
>
> Try this:
> type alias Course =
>     { teacherId : Int
>     , teacherName : String
>     }
>

This would make my main model on the order **huge**!  Even right now with 
it following the view paths the model has 24 keys in the root model, if 
flattened it would be well over 200.  This is not a small project.


On Monday, August 15, 2016 at 12:25:49 AM UTC-6, Aaron VonderHaar wrote: 

> 2)  make the nested thing into a module
>
> This is appropriate when it makes sense to have functions that manipulate 
> the nested thing.
>
> Instead of this:
> moveSpaceshipEast ship =
>     let
>         oldPosition = ship.position
>         newPosition = { oldPosition | x = oldPosition.x + 1 }
>     in
>         { ship | position = newPosition }
>
> Try this:
> moveSpaceshipEast ship =
>     { ship | position = Position.addX 1 ship.position }
>
> module Position
> addX dx position =
>     { position | x = position.x + dx }
>

Not a game sadly, but I already do use a lot of modules to handle the 
various components and so forth, and that is indeed what I do for most of 
the sub-records, however they have a lot of cross-information 
(notifications incoming have to be updated in the proper room record, 
etc... etc...).  This handles most of the load but everything is still 
*very* verbose for a functional language.


On Monday, August 15, 2016 at 12:25:49 AM UTC-6, Aaron VonderHaar wrote:  

> On Sun, Aug 14, 2016 at 11:28 AM, OvermindDL1 <[email protected] 
> <javascript:>> wrote:
>
>>
>> Lists/Dicts/Records do have different interfaces, however if Elm had 
>> HKT's it would not need to, you could have a generic 'map' function that 
>> works over all of them, a generic fold, etc... and so forth (See Haskell).
>>
>> However note the List Access is what would define the required structure 
>> of the thing that would be passed in, that is resolvable in the type system 
>> quite easily (at least with HKT's, unsure otherwise).
>>
>> However, ignoring other types and just doing it for records you could do 
>> it with the current Elm type system 'if' we get some kind of way to set a 
>> record value via an argument, I.E. we could create all the proposed 
>> getters/setters 'now' on just records if we get a function that acts 
>> something like:
>> ```elm
>> Record.set : RecordID record id -> id_type -> { record | id : id_type }
>> Record.set id val rec = <something perhaps like `{ rec | id=val }`>
>> ```
>> That allows type-safe enforcement of a key ID.
>> Where you could use it like:
>> ```elm
>> model = { something=0 }
>> newModel = Record.set 42 model
>> newModel == { something=42 }
>> ```
>> Basically Elm needs something like Ocaml's Field(s) functions:
>> ```ocaml
>> Field.t # Type declaration for following inputs/outputs
>> Field.name # Get the name of a record field
>> Field.get # Get the value of a record field
>> Field.fset # Functionally set the value of a record field, returning the 
>> new record with the new field value
>> ```
>> Which can be used like (remember Ocaml's type system is exceedingly 
>> strict with no HKT support, it's type system is not as advanced as, say, 
>> Haskell's):
>> ```ocaml
>> module Model = struct
>>   type t = 
>>     { something : int
>>     };;
>> end
>> module Model :
>>   sig
>>     type t =
>>       { something : int;
>>       }
>>   end
>>
>> let model = { Model.
>>               something = 42;
>>             };;
>>
>> let name = Field.name Model.Fields.something model;; # Returns a string 
>> of "something"
>>
>> let val = Field.get Model.Fields.something model;; # Returns an int of 42
>>
>> let newModel = Field.fset Model.Fields.something 3 model # Returns the 
>> structure of { something = 3 }
>> ```
>>
>> So yes it is very possible in the normal Elm type system as Ocaml's is 
>> similarly restricted.  As I recall Ocaml is using the functional idiom 
>> called Lenses in its field work to do that (lot of packaging access up in 
>> functions, but does require a record to have more data, like adding an 
>> implicit RecordName.Fields thing or so, or make better syntax for it).
>>
>> With proper HKT's, like with Haskell, then fully type-safe we could have 
>> very powerful, generic, and simple syntax such as this:
>> ```haskell
>> -- Given these simplified types:
>> data Model = Model { something :: SomeSubData }
>>
>> data SomeSubData = SomeSubData { moreThing :: Integer }
>>
>> -- And given this value
>> where
>>   model = Model (SomeSubData 42)
>>
>>
>> -- You could do the way that Elm does now (although elm has the existing 
>> record inside the {} and haskell has it outside, so this is how haskell 
>> does it):
>> newModel = model {
>>   something = (something model) {
>>     moreThing = moreThing (something model) + 1
>>     }
>>   }
>>
>>
>> -- The above set newModel as { something = { moreThing = 43 } } in Elmish 
>> parlance, and is very similar to how it is done in Elm itself, however 
>> Haskell has HKT's, which allow for a variety of other methods such as:
>>
>>
>> -- references+lenses (not possible to do anything even remotely like this 
>> in Elm right now due to not being able to operate over types, but it is the 
>> most succinct):
>> $(mkLabels [ 'Model, 'SomeSubData ]) -- Only need to do this once
>>
>> newModel = modify (+1) (moreThing . something) model
>>
>>
>> -- SYB (A generic library that handles tasks like this with is, it comes 
>> bundled with Haskell
>> incMoreThing v s@(SomeSubData moreThing) = s { moreThing = moreThing + v 
>> } -- Per change you want to make anywhere in the record path
>>
>> newModel = everywhere (mkT (incMoreThing 1))
>>
>>
>> -- Semantic Editor Combinators (low-level version of SYB, no libraries 
>> needed, and you could make these 'now' in Elm, and I have to an extent, but 
>> it is very easy in haskell to define it from scratch, as doing here, still 
>> very wordy as it requires one function made per key):
>> type SemEdit a = a -> a
>> type Lifter p q = SemEdit p -> SemEdit q
>>
>> onSomething :: Lifter SomeSubData Model
>> onSomething f (Model something) = Model (f something)
>>
>> onMoreThing :: Lifter Integer SomeSubData
>> onMoreThing f (SomeSubData moreThing) = SomeSubData 
>>
>> newModel = (onSomething . onMoreThing) (+1) model
>> ```
>>
>> So yes, it is very possible to perform such things while remaining 
>> strongly typed.  OCaml does it with an interface similar to my first 
>> email.  Haskell can do it with ease in an almost crazy amount of ways and 
>> would be the better ways by far, however most of its ways require HKT's 
>> and/or code that works on types.  My original email proposal for just the 
>> records is something that could be added to Elm with relative ease now 
>> compared to enhancing the entire type system with HKT's.
>>
>> More responses in-line.  :-)
>>
>>
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>>
>>> Also, Lists, Dicts, and Records have different interfaces *because they 
>>> are fundamentally different*
>>>
>>
>> Yes, that was an example and it would be most useful for nested records.  
>> I was showing that example as a 'complete' method that could work over 
>> everything as the API.
>>  
>>
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>
>>> If you are accessing the nth element of a List so often that you need 
>>> special syntax to do so, you are doing something wrong, because list's are 
>>> intended for iteration. You probably want an array.
>>>
>>
>> Normally you'd never ever do that, usually you would use Access.all for 
>> lists, which does indeed iterate over all of them (even nested records 
>> instead nested records instead a list that is inside a record would be 
>> trivial via `[ :something, Access.all, :anotherkey, :yetanotherkey ]`), 
>> just showing it for completion.
>>  
>>
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>
>>> Likewise, if you ever have a time where, at compile-time, you're trying 
>>> to access a field in a record that might not exist, you're doing something 
>>> terribly wrong, since that's not what records are for.
>>>
>>
>> Such code in typed languages would indeed create a compile-time error.  
>> Things like variables that are only known at run-time are not allowed in 
>> the keylist, only constants or sub-types that restrict the value of keys 
>> allowed to the given record are allowed and is type-safe. 
>>
>>
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote: 
>>
>>> I can see why these things look nice coming from Elixr, but Elm is not 
>>> Elixr. We choose types, and there is a degree of awkwardness that comes 
>>> from this, and that is somewhat inherent to the system. These things are 
>>> easy when you have no types, like Elixr, and they are hard when you have 
>>> types, in Elm. There is tons of research going on into how to deal with 
>>> these things in a typed setting, but that's how you get the hundreds of GHC 
>>> extensions like Haskell has, most of which break type inference and require 
>>> you to annotate things yourself.
>>>
>>  
>> This is not purely an Elixir thing, I just used it as is was a more 
>> simple example compared to the complete and type-safe and OCaml code, which 
>> I gave a hint of above (with the `Field(s)` stuff).
>>
>>  
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>
>>> On Sun, Aug 14, 2016 at 9:47 AM, Joey Eremondi <[email protected]> 
>>> wrote:
>>>
>>>> @OvermindDL1: I'm still grokking what you've proposed, but it's 
>>>> problematic for a few reasons. I'm 99% sure that it can't be done in a way 
>>>> that is type safe. 
>>>>
>>>
>> It can, because OCaml does.  If we get a better type system sometime in 
>> Elm then we could use even the better patterns that we do use in Haskell.
>>
>>
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>
>>> What you're doing doesn't need Higher-Kinded types, it's just not type 
>>>> safe, at least not as how it's presented here.
>>>>
>>>> One is that you've got type variables in your Access type that it is 
>>>> not parameterized over. So you need to do something like this:
>>>>
>>>> type Access recordKeyType  dictKeyType
>>>>   = All
>>>>   | At Int
>>>>   | Elem Int
>>>>   | Key recordKeyType {- Whatever recordKeyType might be as an 
>>>> indicator for a key on a record -}
>>>>   | DictKey dictKeyType
>>>>   | Fn (EnumerableType -> EnumerableType) {- This is why I think HKT's 
>>>> might be needed, or special caseing in the compiler -}
>>>>
>>>> or, with Higher-Ranked Types
>>>>
>>>> type Access
>>>>   = All
>>>>   | At Int
>>>>   | Elem Int
>>>>   | Key (forall recordKeyType . recordKeyType) {- Whatever 
>>>> recordKeyType might be as an indicator for a key on a record -}
>>>>   | DictKey (forall dictKeyType . dictKeyType)
>>>>   | Fn (EnumerableType -> EnumerableType) {- This is why I think HKT's 
>>>> might be needed, or special caseing in the compiler -}
>>>>
>>>> but, I'm pretty sure neither of these would do what you want. In the 
>>>> first case, you'd need to know ahead of time what kind of record or Dict 
>>>> you were dealing with, or you'd need to write something that worked with 
>>>> any record/dict type, which is probably too generic to get anything done.
>>>>
>>>
>> It was a quick write-up, not meant as a final API as I am asking about 
>> ideas of the style, not of my specific implementation.  ;-)
>>  
>>
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>
>>> In the second case, you'd have to give a value that is *truly* generic, 
>>>> that matches literally any type you throw at it. There is no such value. 
>>>> This is also problematic, since it causes all sorts of awful with type 
>>>> inference and would require significantly changing Elm's type system.
>>>>
>>>
>> No, rather the types should be compared recursively through value types 
>> specified in the list, it definitely would *not* work as presented, nor was 
>> it meant to be, just given as a possible example of usage.
>>  
>>
>> On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>
>>> Also, I don't think you're quite understanding how the type variables 
>>>> work. Let's look at the signature here:
>>>>
>>>> {-| Sets a value(s) at the given path -}
>>>> putIn
>>>>   : List Access
>>>>   -> newValue
>>>>   -> EnumerableType
>>>>   -> EnumerableType
>>>>
>>>> Every type variable in Elm has an implicit "forall" at the beginning of 
>>>> the signature. So this is really:
>>>>
>>>> {-| Sets a value(s) at the given path -}
>>>> putIn
>>>>   : forall newValue . List Access
>>>>   -> newValue
>>>>   -> EnumerableType
>>>>   -> EnumerableType
>>>>
>>>> so what you're saying is, for *literally any type* T, if you give me a 
>>>> List of Access and a value of type T and an EnumerableType, I can give you 
>>>> an updated EnumerableType. So all of the following would be allowed:
>>>>
>>>>     putIn [At 3] "Hello" {field = False}
>>>>     putIn [Key foo] "Hello" {foo = True}
>>>>     putIn [Key foo] "Hello" {bar ="Goodbye"}
>>>>
>>>> All of these should generate type errors, but they wouldn't with the 
>>>> given types you have.
>>>>
>>>
>> Correct, but as stated, it is not an implementation example, just an idea 
>> for a way of editing records, not a defined API, such a thing could be made 
>> later if so wished, instead of a list of accesses you could have curried 
>> functions (that would even work as-is in elm right now, but would require a 
>> *lot* of boilerplate that elm should be able to generate itself as it knows 
>> the record types). 
>>
>>
>>  On Sunday, August 14, 2016 at 10:54:15 AM UTC-6, Joey Eremondi wrote:
>>
>>> On Sun, Aug 14, 2016 at 8:40 AM, OvermindDL1 <[email protected]> wrote:
>>>>
>>>>> Expressions are not currently allowed to be updated like that, so 
>>>>> would that return a model with the something.more updated on it (seems 
>>>>> surprising) or return model.something with more updated on it (not 
>>>>> surprising, and would allow arbitrary expressions there).
>>>>>
>>>>>
>>>>>
>>>>> On Saturday, August 13, 2016 at 11:51:29 PM UTC-6, Robin Heggelund 
>>>>> Hansen wrote:
>>>>>>
>>>>>> All I really want is:
>>>>>>
>>>>>> ```elm
>>>>>> { model.something |  more = 42 }
>>>>>> ```
>>>>>>
>>>>>> søndag 14. august 2016 02.49.07 UTC+2 skrev OvermindDL1 følgende:
>>>>>>>
>>>>>>> Just a passing idea to perhaps help give ideas for better methods:
>>>>>>>
>>>>>>>
>>>>>>> Updating a nested record is a bit convoluted as something like:
>>>>>>> ```elm
>>>>>>> let
>>>>>>>   something = model.something
>>>>>>> in
>>>>>>>   { model | something = { something | more = 42 } }
>>>>>>> ```
>>>>>>> Excepting the let/in part because Elm does not support an expression 
>>>>>>> as the first argument (`model` and `something` in these cases) for 
>>>>>>> I-have-no-clue-reason, and another language I work often in is Elixir, 
>>>>>>> its 
>>>>>>> syntax for the above would be similar:
>>>>>>> ```elixir
>>>>>>>   %{ model | something: %{ model.something | more: 42 } }
>>>>>>> ```
>>>>>>>
>>>>>>> However, that is painful, so Elixir has a couple of helper functions 
>>>>>>> that simplify that kind of work, let me demonstrate, this does the same 
>>>>>>> as 
>>>>>>> the above:
>>>>>>> ```elixir
>>>>>>>   put_in models, [:something, :more], 42
>>>>>>> ```
>>>>>>> And you can go arbitrarily deep and it returns a new model with the 
>>>>>>> path altered to the given value as necessary.  Elixir also has lispy 
>>>>>>> macros 
>>>>>>> so you can also use the above function via:
>>>>>>> ```elixir
>>>>>>>   put_in models.something.more, 42
>>>>>>> ```
>>>>>>> Basically using 'read' syntax to specify the path, but it gets 
>>>>>>> expanded to the above at compile-time.  It also supports not only 
>>>>>>> records 
>>>>>>> but also maps (dicts in elm), lists (also lists in elm) and anything 
>>>>>>> else 
>>>>>>> that follows the Access protocol (a set of functions of certain types 
>>>>>>> to do 
>>>>>>> basic functions), but those are the default.
>>>>>>>
>>>>>>> It has extra features like this, say `model.something` is a `List 
>>>>>>> Int` in elm parlance:
>>>>>>> ```elixir
>>>>>>> put_in model, [:something, Access.all], 42
>>>>>>> ```
>>>>>>> This will set any and all values in the list at model.something to 
>>>>>>> 42, not terribly useful, however it has a lot more functions as well, 
>>>>>>> such 
>>>>>>> as (I want to use more 'elmy' syntax, so I will now use things like 
>>>>>>> `.something` instead of `:something` and no commas between arguments, 
>>>>>>> only 
>>>>>>> in tuples and lists and such):
>>>>>>> ```elixir
>>>>>>> -- Where model = { something : Dict String (List Int) }
>>>>>>> ( oldValue, newModel ) = get_and_update_in model [ .something, 
>>>>>>> "joe", Access.at(0) ] (\oldValue -> let oldValue = Maybe.withDefault 0 
>>>>>>> in ( 
>>>>>>> oldValue, Just (oldValue+1) ))
>>>>>>> ```
>>>>>>> This will update a value in and let you return a value (anything you 
>>>>>>> wish) within a tuple.  This one will access `Dict.get "joe" 
>>>>>>> model.something` and get the returned list, accessing the first element 
>>>>>>> (`at` for lists, `elem` for a tuple index starting at 0 as well), and 
>>>>>>> the 
>>>>>>> called passed in function returns a tuple where the first element is 
>>>>>>> the 
>>>>>>> first element of the returned tuple and the second element is what the 
>>>>>>> thing at the path will be updated to, so this case will return the 
>>>>>>> `oldValue+1` if it existed, if it did not then it returns 1 due to the 
>>>>>>> `withDefault 0`.
>>>>>>>
>>>>>>> More functions it adds are:
>>>>>>> ```elixir
>>>>>>> -- Where model = { something : Dict String (List Int) }
>>>>>>> value = get_in model [ .something, "joe", Access.at(2) ] -- Returns 
>>>>>>> the value at the path
>>>>>>>
>>>>>>> values = get_in model [ .something, Access.all, Access.at(2) ] -- 
>>>>>>> Returns all of the values 2nd values in the lists in all the values of 
>>>>>>> the 
>>>>>>> dictionary as a list if they exist, else they are skipped
>>>>>>>
>>>>>>> pop_in model [ .something, Access.all, Access.at(2) ] -- Removes the 
>>>>>>> element in the list at position 2 in all the dictionary values if it 
>>>>>>> exists, if it does not exist then it skips it
>>>>>>>
>>>>>>> update_in model [ .something, Access.all, Access.at(2) ] (\oldValue 
>>>>>>> -> Just (( oldValue |> Maybe.withDefault 0 ) + 4)) -- Updates a 
>>>>>>> value(s) 
>>>>>>> in-place
>>>>>>> ```
>>>>>>> Along with macro's for the read-format pathing, which is not needed 
>>>>>>> here.
>>>>>>>
>>>>>>> The keylist (the `[ .something, Access.all, Access.at(2) ]` in the 
>>>>>>> last example) can also take functions, whatever they return (empty 
>>>>>>> list, 
>>>>>>> single-element list, multiple-element list, etc...) will be what is 
>>>>>>> used 
>>>>>>> and what is set back.
>>>>>>>
>>>>>>>
>>>>>>> *Thus*, what would be thought of Elm adding in functions like these 
>>>>>>> (HKT's might be needed, not thought through the implementation yet, 
>>>>>>> only 
>>>>>>> the API):
>>>>>>> ```
>>>>>>> type Access
>>>>>>>   = All
>>>>>>>   | At Int
>>>>>>>   | Elem Int
>>>>>>>   | Key recordKeyType {- Whatever recordKeyType might be as an 
>>>>>>> indicator for a key on a record -}
>>>>>>>   | DictKey dictKeyType
>>>>>>>   | Fn (EnumerableType -> EnumerableType) {- This is why I think 
>>>>>>> HKT's might be needed, or special caseing in the compiler -}
>>>>>>>
>>>>>>> -- You'd need some kind of EnumerableType as well, no doubt opaque 
>>>>>>> or something, or need HKT's, probably need HKT's in general, Elm really 
>>>>>>> badly needs HKT's...
>>>>>>>
>>>>>>> {-| Get a value calculated from the old value and set a new value 
>>>>>>> simultaneously -}
>>>>>>> getAndUpdateIn
>>>>>>>   : List Access
>>>>>>>   -> (Maybe valueType -> ( retValue, Maybe valueType ))
>>>>>>>   -> EnumerableType
>>>>>>>   -> ( List retValue, EnumerableType )
>>>>>>>
>>>>>>>
>>>>>>> {-| Gets a value from an access path -}
>>>>>>> getIn
>>>>>>>   : List Access
>>>>>>>   -> EnumerableType
>>>>>>>   -> List retValue
>>>>>>>
>>>>>>>
>>>>>>> {-| Removes a value from a given path if possible, returning it if 
>>>>>>> it exists -}
>>>>>>> popIn
>>>>>>>   : List Access
>>>>>>>   -> EnumerableType
>>>>>>>   -> ( List retValue, EnumerableType )
>>>>>>>
>>>>>>>
>>>>>>> {-| Sets a value(s) at the given path -}
>>>>>>> putIn
>>>>>>>   : List Access
>>>>>>>   -> newValue
>>>>>>>   -> EnumerableType
>>>>>>>   -> EnumerableType
>>>>>>>
>>>>>>>
>>>>>>> {-| Updates a value in the path and returns the new modified object 
>>>>>>> -}
>>>>>>> updateIn
>>>>>>>   : List Access
>>>>>>>   -> (Maybe oldValue -> Maybe newValue )
>>>>>>>   -> EnumerableType
>>>>>>>   -> EnumerableType
>>>>>>> ```
>>>>>>>
>>>>>>> These could then be used like:
>>>>>>> ```
>>>>>>> -- Where model = { something : Dict String (List Int) }
>>>>>>> -- With values of:  model = { something = Dict.fromList [("joe", [1, 
>>>>>>> 2, 3]), ("beth", [10, 11, 12, 13])] }
>>>>>>>
>>>>>>>
>>>>>>> ( oldValue, newModel ) = model |> getAndUpdateIn [ Key .something, 
>>>>>>> DictKey "joe", All] (\v -> ( v, v |> Maybe.withDefault 0 |> (+) 1 ))
>>>>>>> -- Will return `oldValue == 1`
>>>>>>> -- And returns `newModel == { something = Dict.fromList [("joe", [2, 
>>>>>>> 2, 3]), ("beth", [10, 11, 12, 13])] }`
>>>>>>>
>>>>>>>
>>>>>>> newModel = model |> putIn [ Key .something, All ] [ 42 ]
>>>>>>> -- Will return `newModel == { something = Dict.fromList [("joe", 
>>>>>>> [42]), ("beth", [42])] }````
>>>>>>>
>>>>>>>
>>>>>>> newModel = model |> updateIn [ Key .something, Fn (\dict -> dict |> 
>>>>>>> Dict.filter (\k v -> (String.length k) >= 4 ) ) ] (\v -> v)
>>>>>>> -- Will return `newModel == { something = Dict.fromList [("beth", 
>>>>>>> [10, 11, 12, 13])] }`
>>>>>>> -- This is because we used a Fn to return the set of things we want 
>>>>>>> to operate over and as such will only assign those back, allowing us to 
>>>>>>> filter out things with ease.
>>>>>>> ```
>>>>>>>
>>>>>>> This style makes doing very complex embedded enumerable updating 
>>>>>>> with ease.  However as the above is proposed it would likely require 
>>>>>>> Higher 
>>>>>>> Kind Types in Elm, which does not have those yet, thus for now just 
>>>>>>> implementing the above for just records would be sufficient for a good 
>>>>>>> portion if not the overwhelming majority of program, and that could be 
>>>>>>> done 
>>>>>>> without HKT's.
>>>>>>>
>>>>>> -- 
>>>>> 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.
>>>>>
>>>>
>>>>
>>> -- 
>> 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] <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

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