Re: [elm-discuss] Sending messages up the component tree in Elm 0.17

2016-07-09 Thread Mark Hamburg
Here is a quick sketch (untested) of a generic container class for children
whose views support generating a remove message. I left out the logic for
passing commands up through update for brevity:

type alias Model childModel =
  { nextId : Int, children : List (Int, childModel) }


type Message childModel childMessage
  = Child Int childMessage
  | Remove Int
  | Append childModel


type RemovableMessage childMessage
  = ToThis childMessage
  | RemoveThis


update :
  (childMessage -> childModel -> childModel)
  -> Message childModel childMessage -> Model childModel -> Model childModel
update childUpdate message model =
  case message of
Child id childMessage ->
  { model
  | children =
  model.children
  |> List.map (\((childId, childModel) as entry) ->
if childId == id then
  (childId, childUpdate childMessage childModel)
else
  entry)
  }
Remove id ->
  { model
  | children = List.filter (fst >> ((/=) id)) model.children
  }
Append child ->
  { model
  | nextId = model.nextId + 1
  , children = List.append model.children [ ( model.nextId, child ) ]
  }


view :
  (childModel -> Html.Html (RemovableMessage childMessage))
  -> Model childModel
  -> Html.Html (Message childModel childMessage)
view viewChild model =
  Html.div [] <| List.map (viewEntry viewChild) model.children


viewEntry :
  (childModel -> Html.Html (RemovableMessage childMessage))
  -> (Int, childModel)
  -> Html.Html (Message childModel childMessage)
viewEntry viewChild (childId, childModel) =
  Html.App.map (translateRemovableMessage childId) <| viewChild childModel


translateRemovableMessage :
  Int -> RemovableMessage childMessage -> Message childModel childMessage
translateRemovableMessage childId removableMessage =
  case removableMessage of
ToThis childMessage -> Child childId childMessage
RemoveThis -> Remove childId


The RemovableMessage type essentially serves as our interface to the child
view function and could in fact be part of the declaration for that
function or stored elsewhere as a generally useful concept that might work
with multiple container and contained types.

This case is arguably cleaner than the Elm 0.16 solution. On the other
hand, it's going to get a bit messy if one has to pass values up through
several layers. In Elm 0.16, that could be handled by providing a
Signal.Message to handle the message that needed to go somewhere other than
the "corresponding" model. But maybe the strength here is in putting some
separation between the model hierarchy and the view hierarchy and weakening
the notion that there is a one-to-one correspondence all the way down.

Mark

On Sat, Jul 9, 2016 at 2:27 PM, Mark Hamburg  wrote:

> On Jul 7, 2016, at 6:22 PM, Alex Lew  wrote:
> >
> > I wrote about a generalization of that pattern a week or so ago, in case
> you're interested:
> https://medium.com/@alex.lew/the-translator-pattern-a-model-for-child-to-parent-communication-in-elm-f4bfaa1d3f98
>
> I like this approach. It emphasizes that the tagger can be a somewhat more
> arbitrary translator function — something that common usage patterns
> obscure. Furthermore, it could be extended to reflect the fact that the
> translator needed for update results might be different from the translator
> needed for view results. In particular, the view function in the counter
> example can be typed as returning an Html (Removable.Msg Counter.Msg) for
> which it is then the job of the parent view to provide a translator into a
> parent message.
>
> Mark

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


Re: [elm-discuss] Sending messages up the component tree in Elm 0.17

2016-07-09 Thread Mark Hamburg
On Jul 7, 2016, at 6:22 PM, Alex Lew  wrote:
> 
> I wrote about a generalization of that pattern a week or so ago, in case 
> you're interested: 
> https://medium.com/@alex.lew/the-translator-pattern-a-model-for-child-to-parent-communication-in-elm-f4bfaa1d3f98

I like this approach. It emphasizes that the tagger can be a somewhat more 
arbitrary translator function — something that common usage patterns obscure. 
Furthermore, it could be extended to reflect the fact that the translator 
needed for update results might be different from the translator needed for 
view results. In particular, the view function in the counter example can be 
typed as returning an Html (Removable.Msg Counter.Msg) for which it is then the 
job of the parent view to provide a translator into a parent message.

Mark

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


Re: [elm-discuss] Sending messages up the component tree in Elm 0.17

2016-07-08 Thread Wouter In t Velt
A solution I am currently experimenting with is to wrap the Msg of each 
component into a union type:

type AddressedMsg =
  ToSelf Msg
  | ToParent OutMsg
  | ToRoot RootMsg

All relevant functions of the component which output ( Model, Cmd Msg ) change 
to ( Model, Cmd AddressedMsg )

The update function (of any component in the tree) is now:

update : AddressedMsg -> Model -> ( Model, AdressedMsg )
update msg model =
  case msg of
ToSelf msg' ->
   handleMsg msg' model
ToParent outMsg ->
   -- translate outMsg to new message for parent

Inside the view, I bundled my taggers to include the address, e.g. 'ToSelf 
Increment' to increase counter 'ToParent RemoveMe' to notify parent counter 
needs to be removed.

Inside parent's update function is similar and the confidentiality is 
preserved. Whenever the parent of this component is called (e.g Modify 5 msg in 
case of the counter).
When the Msg is of type ToSelf, then the parent calls the update of the child.

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


Re: [elm-discuss] Sending messages up the component tree in Elm 0.17

2016-07-07 Thread Alex Lew
I wrote about a generalization of that pattern a week or so ago, in case 
you're 
interested: 
https://medium.com/@alex.lew/the-translator-pattern-a-model-for-child-to-parent-communication-in-elm-f4bfaa1d3f98

Another pattern that seems very popular is to have the child's update 
return the signal to the parent (in your case, a Bool might work -- should 
I or shouldn't I be removed?) -- Brian Hicks has a great & entertaining 
blog post about it 
here: 
https://www.brianthicks.com/post/2016/06/23/candy-and-allowances-parent-child-communication-in-elm/

best,
Alex

On Thursday, July 7, 2016 at 7:51:01 PM UTC-4, Mark Hamburg wrote:
>
> Yes, the view would return Html parentMsg. The signature would be 
> something like:
>
> view: (ChildMessage -> parentMsg) -> parentMsg -> ChildModel -> Html 
> parentMsg
>
> Note that parentMsg is parameterized.
>
> Mark
>
> On Jul 7, 2016, at 3:27 PM, Sandi Dušić > 
> wrote:
>
> Thank you Mark!
>
> One way to do this is to extend the view function with two arguments: one 
>> is a function to map the counter messages to the parent message space and 
>> the other is the parent message that the remove button should send.
>
> Would the child view then return Html ParentMsg? In reality, my components 
> are more separated in depth, by four levels. Bit ugly, but seems it's all 
> we have right now. It actually appears elegant in contrast to my approach.
>
> 2016-07-07 21:18 GMT+02:00 Mark Hamburg >
> :
>
>> We're still awaiting an official answer from Evan. In the meantime, the 
>> best answer I've seen from the standpoint of not contaminating the counter 
>> messages and update function with something that they don't care about is 
>> to put the complexity in the view function which is, I would argue, where 
>> it belongs since this it's a view layout issue that forces the remove 
>> button to be included in the counter view. One way to do this is to extend 
>> the view function with two arguments: one is a function to map the counter 
>> messages to the parent message space and the other is the parent message 
>> that the remove button should send.
>>
>> Mark
>>
>> On Jul 7, 2016, at 10:50 AM, Sandi Dušić > 
>> wrote:
>>
>> In Elm 0.16 the Architecture tutorial had one more button list example 
>> 
>>  (I 
>> dug that up from an old commit), aside from this one 
>> .
>>  
>> Each counter would have it's own remove button which would remove that 
>> exact one when clicked, unlike in the simpler example with a sole remove 
>> button that removes the first counter. This was accomplished by passing two 
>> addresses to the counter view, one for it's own actions and another which 
>> it's father component (CounterList) handled, used for signaling removal. 
>>
>> I did the exact same thing in my application. I have a bunch of small 
>> components in a big component, and the big component needs to know when one 
>> of the small ones has been clicked. How do you do this in 0.17? Is it 
>> impossible, since they removed the example which is supposed to implement 
>> it?
>>
>> This is the only thing I can think of: Add the message that needs to be 
>> sent upwards to the big component to the message union of the small 
>> component (in the CounterList, this would mean Counter.Msg has Remove). 
>> When the big component gets a small component action, it would first check 
>> with an if whether it's the one it needs to handle (if msg == 
>> Counter.Remove then ...). If so, it can handle it (remove the Counter), 
>> otherwise it would just regularly pass it to Counter.update.
>>
>> To me that seems like it goes against the principles of Elm Architecture. 
>> You can no longer treat components (and especially their actions) like 
>> black boxes, but rather you have to tear them apart in a way. They cannot 
>> fully define their interface. I don't know, it's just weird.
>>
>> If there's a way to define custom subscriptions they might be leveraged 
>> to solve this, but I don't see a way to do that in the API. I apologize if 
>> this is a silly question, 0.17 is still new to me.
>>
>> -- 
>> 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...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "Elm Discuss" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/elm-discuss/H1AUQelu78c/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to 
>> elm-discuss...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> -- 
> You recei

Re: [elm-discuss] Sending messages up the component tree in Elm 0.17

2016-07-07 Thread Mark Hamburg
Yes, the view would return Html parentMsg. The signature would be something 
like:

view: (ChildMessage -> parentMsg) -> parentMsg -> ChildModel -> Html parentMsg

Note that parentMsg is parameterized.

Mark

> On Jul 7, 2016, at 3:27 PM, Sandi Dušić  wrote:
> 
> Thank you Mark!
> 
>> One way to do this is to extend the view function with two arguments: one is 
>> a function to map the counter messages to the parent message space and the 
>> other is the parent message that the remove button should send.
> Would the child view then return Html ParentMsg? In reality, my components 
> are more separated in depth, by four levels. Bit ugly, but seems it's all we 
> have right now. It actually appears elegant in contrast to my approach.
> 
> 2016-07-07 21:18 GMT+02:00 Mark Hamburg :
>> We're still awaiting an official answer from Evan. In the meantime, the best 
>> answer I've seen from the standpoint of not contaminating the counter 
>> messages and update function with something that they don't care about is to 
>> put the complexity in the view function which is, I would argue, where it 
>> belongs since this it's a view layout issue that forces the remove button to 
>> be included in the counter view. One way to do this is to extend the view 
>> function with two arguments: one is a function to map the counter messages 
>> to the parent message space and the other is the parent message that the 
>> remove button should send.
>> 
>> Mark
>> 
>>> On Jul 7, 2016, at 10:50 AM, Sandi Dušić  wrote:
>>> 
>>> In Elm 0.16 the Architecture tutorial had one more button list example (I 
>>> dug that up from an old commit), aside from this one. Each counter would 
>>> have it's own remove button which would remove that exact one when clicked, 
>>> unlike in the simpler example with a sole remove button that removes the 
>>> first counter. This was accomplished by passing two addresses to the 
>>> counter view, one for it's own actions and another which it's father 
>>> component (CounterList) handled, used for signaling removal. 
>>> 
>>> I did the exact same thing in my application. I have a bunch of small 
>>> components in a big component, and the big component needs to know when one 
>>> of the small ones has been clicked. How do you do this in 0.17? Is it 
>>> impossible, since they removed the example which is supposed to implement 
>>> it?
>>> 
>>> This is the only thing I can think of: Add the message that needs to be 
>>> sent upwards to the big component to the message union of the small 
>>> component (in the CounterList, this would mean Counter.Msg has Remove). 
>>> When the big component gets a small component action, it would first check 
>>> with an if whether it's the one it needs to handle (if msg == 
>>> Counter.Remove then ...). If so, it can handle it (remove the Counter), 
>>> otherwise it would just regularly pass it to Counter.update.
>>> 
>>> To me that seems like it goes against the principles of Elm Architecture. 
>>> You can no longer treat components (and especially their actions) like 
>>> black boxes, but rather you have to tear them apart in a way. They cannot 
>>> fully define their interface. I don't know, it's just weird.
>>> 
>>> If there's a way to define custom subscriptions they might be leveraged to 
>>> solve this, but I don't see a way to do that in the API. I apologize if 
>>> this is a silly question, 0.17 is still new to me.
>>> -- 
>>> 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.
>> 
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "Elm Discuss" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/elm-discuss/H1AUQelu78c/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to 
>> elm-discuss+unsubscr...@googlegroups.com.
>> 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 elm-discuss+unsubscr...@googlegroups.com.
> 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 elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Sending messages up the component tree in Elm 0.17

2016-07-07 Thread Sandi Dušić
Thank you Mark!

One way to do this is to extend the view function with two arguments: one
> is a function to map the counter messages to the parent message space and
> the other is the parent message that the remove button should send.

Would the child view then return Html ParentMsg? In reality, my components
are more separated in depth, by four levels. Bit ugly, but seems it's all
we have right now. It actually appears elegant in contrast to my approach.

2016-07-07 21:18 GMT+02:00 Mark Hamburg :

> We're still awaiting an official answer from Evan. In the meantime, the
> best answer I've seen from the standpoint of not contaminating the counter
> messages and update function with something that they don't care about is
> to put the complexity in the view function which is, I would argue, where
> it belongs since this it's a view layout issue that forces the remove
> button to be included in the counter view. One way to do this is to extend
> the view function with two arguments: one is a function to map the counter
> messages to the parent message space and the other is the parent message
> that the remove button should send.
>
> Mark
>
> On Jul 7, 2016, at 10:50 AM, Sandi Dušić  wrote:
>
> In Elm 0.16 the Architecture tutorial had one more button list example
> 
>  (I
> dug that up from an old commit), aside from this one
> .
> Each counter would have it's own remove button which would remove that
> exact one when clicked, unlike in the simpler example with a sole remove
> button that removes the first counter. This was accomplished by passing two
> addresses to the counter view, one for it's own actions and another which
> it's father component (CounterList) handled, used for signaling removal.
>
> I did the exact same thing in my application. I have a bunch of small
> components in a big component, and the big component needs to know when one
> of the small ones has been clicked. How do you do this in 0.17? Is it
> impossible, since they removed the example which is supposed to implement
> it?
>
> This is the only thing I can think of: Add the message that needs to be
> sent upwards to the big component to the message union of the small
> component (in the CounterList, this would mean Counter.Msg has Remove).
> When the big component gets a small component action, it would first check
> with an if whether it's the one it needs to handle (if msg ==
> Counter.Remove then ...). If so, it can handle it (remove the Counter),
> otherwise it would just regularly pass it to Counter.update.
>
> To me that seems like it goes against the principles of Elm Architecture.
> You can no longer treat components (and especially their actions) like
> black boxes, but rather you have to tear them apart in a way. They cannot
> fully define their interface. I don't know, it's just weird.
>
> If there's a way to define custom subscriptions they might be leveraged to
> solve this, but I don't see a way to do that in the API. I apologize if
> this is a silly question, 0.17 is still new to me.
>
> --
> 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.
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Elm Discuss" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/elm-discuss/H1AUQelu78c/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> elm-discuss+unsubscr...@googlegroups.com.
> 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 elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Sending messages up the component tree in Elm 0.17

2016-07-07 Thread Mark Hamburg
We're still awaiting an official answer from Evan. In the meantime, the best 
answer I've seen from the standpoint of not contaminating the counter messages 
and update function with something that they don't care about is to put the 
complexity in the view function which is, I would argue, where it belongs since 
this it's a view layout issue that forces the remove button to be included in 
the counter view. One way to do this is to extend the view function with two 
arguments: one is a function to map the counter messages to the parent message 
space and the other is the parent message that the remove button should send.

Mark

> On Jul 7, 2016, at 10:50 AM, Sandi Dušić  wrote:
> 
> In Elm 0.16 the Architecture tutorial had one more button list example (I dug 
> that up from an old commit), aside from this one. Each counter would have 
> it's own remove button which would remove that exact one when clicked, unlike 
> in the simpler example with a sole remove button that removes the first 
> counter. This was accomplished by passing two addresses to the counter view, 
> one for it's own actions and another which it's father component 
> (CounterList) handled, used for signaling removal. 
> 
> I did the exact same thing in my application. I have a bunch of small 
> components in a big component, and the big component needs to know when one 
> of the small ones has been clicked. How do you do this in 0.17? Is it 
> impossible, since they removed the example which is supposed to implement it?
> 
> This is the only thing I can think of: Add the message that needs to be sent 
> upwards to the big component to the message union of the small component (in 
> the CounterList, this would mean Counter.Msg has Remove). When the big 
> component gets a small component action, it would first check with an if 
> whether it's the one it needs to handle (if msg == Counter.Remove then ...). 
> If so, it can handle it (remove the Counter), otherwise it would just 
> regularly pass it to Counter.update.
> 
> To me that seems like it goes against the principles of Elm Architecture. You 
> can no longer treat components (and especially their actions) like black 
> boxes, but rather you have to tear them apart in a way. They cannot fully 
> define their interface. I don't know, it's just weird.
> 
> If there's a way to define custom subscriptions they might be leveraged to 
> solve this, but I don't see a way to do that in the API. I apologize if this 
> is a silly question, 0.17 is still new to me.
> -- 
> 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.

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