The HTML functions in Elm tend to take two parameters: a list of attribute values and a list of child DOM nodes. Again, this is all code. The list values you specify are again just functions that get evaluated.
It's a little less obvious because of the syntax style of Elm, but it does let you write the function calls out in such a way that they express that tree structure.
It bears repeating: your Elm div example, at the top level, is a single function call with the first parameter '[]' being an empty list (because you aren't assigning the node any attributes like a DOM id or CSS class) and the second parameter being a list that'll be made up of the DOM nodes that result from each of the function calls within it.
This was one of the biggest mental roadblocks I had to get past when learning Elm. Just forget the idea of HTML and think instead of DOM tree-of-nodes and a lot falls into place. The 'view' function you write will return a DOM tree data structure which is then taken and applied to the browser document. You pass in your model as a parameter to that function and then other functions you call within this DOM-generating code you've written will use that data to return different DOM contents depending on it.