tableadventure
tableadventure

Reputation: 23

Why is this function annotated like this?

I'm learing Elm and trying to understand how type annotations for generic functions are written. (Not sure "generic function" this is the right term for this in Elm, please advise.)

Given the following code:

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)

type Msg = EmailChanged String | PasswordChanged String

formView label msg = div [] [text (label ++ ": "), input [onInput msg] []]

main = div [] [formView "Email" EmailChanged, formView "Password" PasswordChanged]

What is the reasoning behind the formView function being annotated like this

formView : String -> (String -> msg) -> Html msg

and what is the reasoning behind this annotation for the function not being right?

formView : String -> msg -> Html Msg

Upvotes: 0

Views: 58

Answers (1)

Simon H
Simon H

Reputation: 21005

The types are 'inferred' recursively. You wrote

formView label msg = div [] [text (label ++ ": "), input [onInput msg] []]

Note how the msg that you pass in is used by onInput. onInput is defined in the standard library as

onInput : (String -> msg) -> Attribute msg

So the parameter you called msg needs to have the type String -> msg. If nothing else in your code contradicts that then your code will compile. If some other use of msg contradicts with that inference, then the compiler will force you to reconcile the difference.

In your case, you passed to formView EmailChanged. You declared this as a custom type that is completed with a String. Behind the scenes, elm created a function that takes a String and returns Msg and called it EmailChanged and it was this latter function that you passed in and that met with the expected type. This last little bit of magic takes a bit of getting used to, but it ubiquitous in Elm so you will quickly become familiar.

Upvotes: 4

Related Questions