Elm syntax - where does the value come from?

I am very new and am currently trying to get to know Elma. I come from JS / React and have no previous RFP experience.

I'm in the Guide right here: http://guide.elm-lang.org/architecture/user_input/text_fields.html

I have problems with update and view :

 -- UPDATE type Msg = Change String update : Msg -> Model -> Model update msg model = case msg of Change newContent -> { model | content = newContent } -- VIEW view : Model -> Html Msg view model = div [] [ input [ placeholder "Text to reverse", onInput Change ] [] , div [] [ text (String.reverse model.content) ] ] 

Start with the Msg ad. The manual says:

It takes one argument, in this case the change function that was created when we declared the Msg type:

Edit: String -> Msg

I do not see how this happened here:

 type Msg = Change String 

How did we define the change function here? How did we determine how this function works? It seems to me that we just declared an Msg type, which somehow contains all the Change and the String type.

My second update question:

 update : Msg -> Model -> Model update msg model = case msg of Change newContent -> { model | content = newContent } 

It seems to me that the update is a higher order function that takes Msg and returns a Model -> Model function. But then we define a function with two parameters. Msg -> Model -> Model means that all but the last are parameters?

Then we call the Change function:

 Change newContent -> { model | content = newContent } 

What I can’t do is have an arrow. Usually an arrow appears after a parameter has been defined. But here we have the result of the function before -> .

I hope that my questions will make sense, I'm just very confused by this (supposedly amazing) language.

+8
syntax elm
source share
2 answers

When you declare type Msg = Change String , you declare one type ( Msg ) with one constructor that takes a string.

See the Elm manual section in Connection Types (AKA, ADT Algebra Data Types).

Here is an example:

 type User = Anonymous | Named String 

Therefore, creating a User type also created constructors called Anonymous and Named . If you want to create a User , you must use one of these two constructors.

Constructors are functions, therefore you name them as Change "a string" (returns type Msg )

Constructors also provide the ability to use pattern matching to retrieve an internal value as a union. This use -> that you are not familiar with.

 case msg of Change theString -> ... use theString ... 

Your second question;

It seems to me that the update is a higher order function that takes Msg and returns a Model β†’ Model function

Yes, this is more or less what is happening. The priority rules for a function application mean that you can call them without parentheses. This is called currying, and it is also covered with guide elms.

+4
source share

Just to clarify the second part a bit:

All functions have a curried value, which means that update: Msg->Model->Model can get Msg and return the function Model->Model or get Msg and a Model and return a Model .

In fact, when you call update aMessage aModel , you really call update aMessage , which returns a function, and then you pass aModel this function, which will run expressions in the body of the function and return the updated model.

The arrow is part of the syntax case.. of . The left side is the pattern you want to match, the right side is the expression that you want to execute. In your case, your update will only execute the expression if Msg was created using the Change constructor.

 type Msg = Change String | Delete update : Msg -> Model -> Model update msg model = case msg of Change newContent -> { model | content = newContent } Delete -> { model | content = "" } 

In the previous case, Msg can be built either using Change String , or using Delete . The update function behaves differently according to how msg was created.

+2
source share

All Articles