Cyclical type-message dependency with 0.17

137 views
Skip to first unread message

Ondřej Žára

unread,
May 11, 2016, 7:26:56 AM5/11/16
to Elm Discuss
Hi,

when updating my code 0.16->0.17, I stumbled upon this weird circular dependency in my code:

```
type Msg = NoOp | Response (List Slide)

type alias Slide = {
  title: String,
  node: Html Msg
}
```

The definition above corresponds to a static slideshow system that fetches data, parses it into a list of Slides (each having a title and a HTML node) and displays them.

In 0.16, the "node" was just "Html" (static, no event listeners). In 0.17, I have to specify what messages are emitted (none) from the resulting Html subtree. Is there any way of separating these two type definitions/aliases so they can be split into two modules?

On an unrelated note, I recall reading something like "the NoOp action/msg is no longer necessary in 0.17". Is this true? A NoOp Msg seems like a viable way of processing/tagging an unhandled keyboard keyCode...


Thanks,
O.

Peter Damoc

unread,
May 11, 2016, 7:38:29 AM5/11/16
to Elm Discuss
If you don't have event listeners in `node` use Html msg instead of Html Msg.

Regarding NoOp pattern, it still has uses. 

I've used it so far in order to create an OnEnter handler and to satisfy the Task.perform `fail` requirement. 





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



--
There is NO FATE, we are the creators.
blog: http://damoc.ro/

Janis Voigtländer

unread,
May 11, 2016, 7:38:49 AM5/11/16
to elm-d...@googlegroups.com

One possibility of separating those two types so they can be split into two modules is:

type Msg = NoOp | Response (List (Slide Msg))

type alias Slide msg = {
  title: String,
  node: Html msg
}

Tobias Burger

unread,
May 11, 2016, 8:20:06 AM5/11/16
to Elm Discuss
Exactly the same question I was telling myself, when I saw that Signal isn't anymore. How to process only the keyCode I'm interested in?
NoOp is the only solution I got up so far. Wonder if there is another way of discarding keyboard events I'm not interested in.

Janis Voigtländer

unread,
May 11, 2016, 8:28:22 AM5/11/16
to elm-d...@googlegroups.com
So, looking for a function

Sub.filter : (a -> Bool) -> Sub a -> Sub a 

?

Tobias Burger

unread,
May 11, 2016, 8:39:28 AM5/11/16
to Elm Discuss
Exactly! :) Or is it an antipattern? I'm not sure, because there exists no filter anymore and I thought it ins't idiomatic elm anymore...

Ondřej Žára

unread,
May 11, 2016, 8:57:15 AM5/11/16
to Elm Discuss
Thanks, Peter and Janis. Your two answers are actually the same (I cannot simply change Html Msg to Html msg, the templated "msg" must be propagated upwards to Slide msg).

This being said, I find it somewhat uncomfortable that there is no way to specify that "this HTML is static and does not emit any Messages, so please do not bother me with these mandatory dummy potential msg types".


O.

Janis Voigtländer

unread,
May 11, 2016, 9:02:33 AM5/11/16
to elm-d...@googlegroups.com

This being said, I find it somewhat uncomfortable that there is no way to specify that “this HTML is static and does not emit any Messages, so please do not bother me with these mandatory dummy potential msg types”.

Who said that there is no such way? In my reply I said that one way to do what you want is so-and-so. I did not say that that was the only way. For example, you could also do something like:

type Msg = NoOp | Response (List Slide)

type alias Slide = {
  title: String,
  node: Html Never
}

Janis Voigtländer

unread,
May 11, 2016, 9:04:05 AM5/11/16
to elm-d...@googlegroups.com

Don’t know whether it’s an antipattern. Probably needs discussion. In a separate thread. You could start one with a specific use case where you would want such a Sub.filter being available.

Ondřej Žára

unread,
May 11, 2016, 9:14:26 AM5/11/16
to Elm Discuss

Who said that there is no such way? In my reply I said that one way to do what you want is so-and-so. I did not say that that was the only way. For example, you could also do something like:

type Msg = NoOp | Response (List Slide)

type alias Slide = {
  title: String,
  node: Html Never
}



Okay, I was a bit hasty then, sorry for that. This apparently shows that I have zero understanding how "Html Msg" works:

1) what is Never? Where does that come from? Why can I use "Never" and not "()" for example?

2) even with Never, my code fails to compile (the "view" function passed to Html.App.program is expected to return "Html Msg", but I guess that is some fault hidden in my code). I will have to look into this deeper.


O.
 

Janis Voigtländer

unread,
May 11, 2016, 9:19:28 AM5/11/16
to elm-d...@googlegroups.com

About 1), http://package.elm-lang.org/packages/elm-lang/core/4.0.0/Basics#Never

About 2), Never is not Msg, so if a type Html.Msg is needed somewhere, you have to use Html.map with a function of type Never -> Msg. The function always NoOp springs to mind. Or, in an attempt to get rid of NoOp, the function from this proposal: https://github.com/elm-lang/core/pull/593

Ondřej Žára

unread,
May 11, 2016, 9:30:40 AM5/11/16
to Elm Discuss
Ah, thanks for explaining this.

Converting Never to always NoOp works. It is still not clear to me why the Html.App.program requires the view function to return that particular message type. I am almost sure that I never created a dependency on my "Messages.Msg" type nor the described "Html.Msg" (is the Html.Msg defined anywhere? The Html/Html.App docs only use the lowercased templated "msg"...).

Perhaps the dependency was created by analyzing the first argument type of the "update" function (which *is* my Messages.Msg)?


O.

Janis Voigtländer

unread,
May 11, 2016, 9:36:40 AM5/11/16
to elm-d...@googlegroups.com

Sorry, I guess I confused you by writing Html.Msg. That was a typo, should have been Html Msg. That is, the Msg there is your Msg type. As to why it is needed, I’d bet you do create a dependency on it somewhere in your code.

Reply all
Reply to author
Forward
0 new messages