想学点新东西,同时看下函数式编程是什么样的,所以开始看Elm
。不过函数式编程对我来说还是太陌生了,所以强制自己写点博文理解。
初步目标是根据官方文档的三个例子(Buttons
,Text Fields
,Forms
)来做分析。这篇是第一篇,根据Button
的计数器。
概念
Main
-- MAIN
main =
Browser.sandbox { init = init, update = update, view = view }
main
在 Elm 里是个特殊的值,它描述什么该显示在屏幕上。这里程序将用init
初始化,view
显示,update
填充用户输入。Browser.sandbox
:Browser
是 Elm 的浏览器模块,允许用户创建在浏览器中运行的Elm
程序。Browser
下不同的模块对页面有不同的控制能力:sandbox
只处理和用户的交互,不能通信;element
能对外通信;document
在其上能控制页面的 title, body 等元素 ;application
制作完整的单页 app。 能输入的参数也不同,下略。参考这个页面中对 Elm 运行时的说明
Model
-- MODEL
type alias Model = Int
init : Model
init =
0
- 数据模型管理所有程序数据的细节。在计数器程序中就是计数的数量。
type alias
表示类型别名,这里用Model
指Int
型。
View
-- VIEW
view : Model -> Html Msg
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
]
view
描述数据显示的方法。view : Model -> Html Msg
表示view
为接受Model
类型,输出Html Msg
类型的函数。- Elm 中的函数和通常的表现方法不一样,为
<函数名> [参数...]>
。view model
即为参数为model
的view
函数。
Update
-- UPDATE
type Msg = Increment | Decrement
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
update
函数描述model
如何变化。type Msg = Increment | Decrement
定义了一个自定义类型Msg
。它可以为Increment
也可以是Decrement
。update : Msg -> Model -> Model
表示update
接受Msg
类型,输出一个函数(输入Model
,输出Model
类型的函数)。从概念上讲,每个函数只接受一个参数,但它可以返回带接受一个参数的函数。表现起来就像接受两个参数的函数。(见这里)
练习
最后完成文档后留的作业:给计数器添加“重置”键。
module Main exposing (..)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
-- MAIN
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Model = Int
init : Model
init =
0
-- UPDATE
type Msg = Increment | Decrement | Reset
update : Msg -> Model -> Model
update msg model =
case msg of
Increment ->
model + 1
Decrement ->
model - 1
Reset ->
0
-- VIEW
view : Model -> Html Msg
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [] [ text (String.fromInt model) ]
, button [ onClick Increment ] [ text "+" ]
, button [ onClick Reset ] [ text "Reset" ]
]