Random Dice Simulation
This review comes with the caveat that I've spent a few days in total on Elm so far... Take anything I say with a pinch of salt.

Firstly, some style things.

posX: Int -&gt; Int -&gt; Int
posX i n =
  round (33 + (15 * cos (6.28 * (toFloat(i) / toFloat(n)))))


Why so many brackets? You can cut it down to this very easily

posX i n =
  round (33 + 15 * cos (6.28 * toFloat(i) / toFloat(n)))


But you can make it even clearer by using a |&gt;

posX i n = 
  33 + 15 * cos (6.28 * toFloat(i) / toFloat(n))
    |&gt; round


I like this more because it also promotes the calculation to its own line where nothing else happens. You could also have written:

posX i n = 
  round &lt;| 33 + 15 * cos (6.28 * toFloat(i) / toFloat(n))


I think it's up to you which one you prefer. I like to think about getting the value first and then rounding it.

There is a similar thing here:

drawFace : Int -&gt; Html Msg
drawFace numDots =
  div [ style "width: 66px; height: 66px; padding: 10px" ] [
    svg
      [ version "1.1", width "66", height "66" ]
      (drawDice ::
      (List.map (\i -&gt; drawDot i numDots) (range 0 (numDots - 1))))
  ]


I would instead have:

drawFace : Int -&gt; Html Msg
drawFace numDots =
  div [ style "width: 66px; height: 66px; padding: 10px" ] [
    svg
      [ version "1.1", width "66", height "66" ]
      (range 0 (numDots - 1)
        |&gt; List.map (\i -&gt; drawDot i numDots) 
        |&gt; (::) drawDice
      )
  ]


It may look more complex but it's easier to follow in my opinion because each line does one thing. 


Create your range
Map each to an Svg Msg (your dots)
Cons the face to the list of dots


Now, if you change the order of your arguments to drawDot you can simplify it further with currying.

drawDot: Int -&gt; Int -&gt; Svg Msg
drawDot n i =
  circle [ fill "black", cx (toString (posX i n)), cy (toString (posY i n)), r "5" ] []

(range 0 (numDots - 1)
    |&gt; List.map (drawDot numDots) 
    |&gt; (::) drawDice
)


You'll find that you need to think about the usage of the function before writing it so you can get the parameter order right for currying.

In my limited understanding/knowledge of Elm, I'd say that your code is pretty good :)