Ya vimos un par de ejemplos de definición de un tipo Msg. Este tipo de tipo es extremadamente común en Elm. En nuestra sala de chat, podríamos definir un tipo Msg de la siguiente manera:
type Msg
= PressedEnter
| ChangedDraft String
| ReceivedMessage { user: User, message: String }
| ClickedExit
Tenemos cuatro variantes. Algunas no tienen datos asociados, otras tienen muchos. Observe que ReceivedMessage tiene un registro como dato asociado. Esto es perfectamente correcto. ¡Cualquier tipo puede ser un dato asociado! Esto le permite describir las interacciones en su aplicación con mucha precisión.
Los tipos personalizados se vuelven extremadamente potentes cuando empieza a modelar situaciones con mucha precisión. Por ejemplo, si está esperando a que se carguen datos, podría querer modelarlos con un tipo personalizado como este:
type Profile
= Failure
| Loading
| Success { name : String, description : String }
Así, puedes comenzar en el estado Loading y luego pasar a Failure o Success según lo que suceda. Esto simplifica enormemente la creación de una función de vista que siempre muestre algo razonable cuando se cargan los datos.
Los tipos personalizados son la característica más importante de Elm. Ofrecen mucha profundidad, especialmente una vez que te acostumbras a modelar escenarios con mayor precisión.