Elm "type" 语法——价值从何而来?
Elm "type" syntax - where is value coming from?
我是新手,目前正在尝试学习 Elm。我来自 JS/React,以前没有任何 RFP 经验。
我在指南中:
http://guide.elm-lang.org/architecture/user_input/text_fields.html
我遇到问题的部分是 update
和 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) ]
]
让我们从 Msg 声明开始。指南说:
It takes one argument, in this case the Change function which was
created when we declared the Msg type:
Change : String -> Msg
我不明白这是怎么发生的:
type Msg
= Change String
我们这里是怎么定义Change函数的?我们如何定义该功能的工作原理?在我看来,我们只是声明了 Msg 的类型,它以某种方式包含了 Change
和类型 String
。
我的第二个问题是关于更新的:
update : Msg -> Model -> Model
update msg model =
case msg of
Change newContent ->
{ model | content = newContent }
对我来说,update 是一个高阶函数,它接受一个 Msg
和 returns 一个函数 Model -> Model
。但是随后我们定义了一个带有两个参数的函数。 Msg -> Model -> Model
是否仅表示除最后一部分之外的所有参数?
然后我们调用Change
函数:
Change newContent ->
{ model | content = newContent }
我不明白那里的箭头。通常箭头出现在参数定义之后。但是这里我们有 ->
.
之前函数的结果
我希望我的问题是有道理的,我只是对这种(大概很棒的)语言感到很困惑。
当您声明 type Msg = Change String
时,您是在声明一种类型 (Msg
),其中包含一个接受字符串的构造函数。
请参阅有关 Union Types(也称为代数数据类型,ADT)的 Elm 指南部分。
这是一个示例:
type User = Anonymous | Named String
So creating the type User
also created constructors named Anonymous
and Named
. If you want to create a User
you must use one of these two constructors
构造函数是函数,所以你可以这样称呼它们 Change "a string"
(returns 类型 Msg
)
构造函数还提供了使用模式匹配 提取联合类型中的内部值的能力。这是你不熟悉的->
的用法。
case msg of
Change theString -> ... use theString ...
你的第二个问题;
To me this looks like update is a higher order function, which takes a Msg and returns a function Model -> Model
是的,这或多或少是正在发生的事情。函数应用的优先规则意味着您可以不带括号地调用它们。这称为 currying,并且在 elm 指南
中也有介绍
只是为了更清楚地说明第二部分:
所有函数都是柯里化的,这意味着 update: Msg->Model->Model
可以接收一个 Msg
和 return 一个函数 Model->Model
或者接收一个 Msg
和一个 Model
和 return 一个 Model
.
实际上,当您调用 update aMessage aModel
时,您实际上是在调用 update aMessage
,其中 return 是一个函数,然后您将 aModel
传递给该函数,该函数将 运行 函数体中的表达式和 return 更新后的模型。
箭头只是 case.. of
语法的一部分。左边是你要匹配的模式,右边是你要执行的表达式。在您的情况下,仅当使用 Change 构造函数创建 Msg 时,您的更新才会执行表达式。
type Msg
= Change String | Delete
update : Msg -> Model -> Model
update msg model =
case msg of
Change newContent ->
{ model | content = newContent }
Delete ->
{ model | content = "" }
在前面的例子中,Msg 可以用Change String
或Delete
构造。根据 msg 的构造方式,更新函数的行为有所不同。
我是新手,目前正在尝试学习 Elm。我来自 JS/React,以前没有任何 RFP 经验。
我在指南中: http://guide.elm-lang.org/architecture/user_input/text_fields.html
我遇到问题的部分是 update
和 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) ]
]
让我们从 Msg 声明开始。指南说:
It takes one argument, in this case the Change function which was created when we declared the Msg type:
Change : String -> Msg
我不明白这是怎么发生的:
type Msg
= Change String
我们这里是怎么定义Change函数的?我们如何定义该功能的工作原理?在我看来,我们只是声明了 Msg 的类型,它以某种方式包含了 Change
和类型 String
。
我的第二个问题是关于更新的:
update : Msg -> Model -> Model
update msg model =
case msg of
Change newContent ->
{ model | content = newContent }
对我来说,update 是一个高阶函数,它接受一个 Msg
和 returns 一个函数 Model -> Model
。但是随后我们定义了一个带有两个参数的函数。 Msg -> Model -> Model
是否仅表示除最后一部分之外的所有参数?
然后我们调用Change
函数:
Change newContent ->
{ model | content = newContent }
我不明白那里的箭头。通常箭头出现在参数定义之后。但是这里我们有 ->
.
我希望我的问题是有道理的,我只是对这种(大概很棒的)语言感到很困惑。
当您声明 type Msg = Change String
时,您是在声明一种类型 (Msg
),其中包含一个接受字符串的构造函数。
请参阅有关 Union Types(也称为代数数据类型,ADT)的 Elm 指南部分。
这是一个示例:
type User = Anonymous | Named String
So creating the type
User
also created constructors namedAnonymous
andNamed
. If you want to create aUser
you must use one of these two constructors
构造函数是函数,所以你可以这样称呼它们 Change "a string"
(returns 类型 Msg
)
构造函数还提供了使用模式匹配 提取联合类型中的内部值的能力。这是你不熟悉的->
的用法。
case msg of
Change theString -> ... use theString ...
你的第二个问题;
To me this looks like update is a higher order function, which takes a Msg and returns a function Model -> Model
是的,这或多或少是正在发生的事情。函数应用的优先规则意味着您可以不带括号地调用它们。这称为 currying,并且在 elm 指南
中也有介绍只是为了更清楚地说明第二部分:
所有函数都是柯里化的,这意味着 update: Msg->Model->Model
可以接收一个 Msg
和 return 一个函数 Model->Model
或者接收一个 Msg
和一个 Model
和 return 一个 Model
.
实际上,当您调用 update aMessage aModel
时,您实际上是在调用 update aMessage
,其中 return 是一个函数,然后您将 aModel
传递给该函数,该函数将 运行 函数体中的表达式和 return 更新后的模型。
箭头只是 case.. of
语法的一部分。左边是你要匹配的模式,右边是你要执行的表达式。在您的情况下,仅当使用 Change 构造函数创建 Msg 时,您的更新才会执行表达式。
type Msg
= Change String | Delete
update : Msg -> Model -> Model
update msg model =
case msg of
Change newContent ->
{ model | content = newContent }
Delete ->
{ model | content = "" }
在前面的例子中,Msg 可以用Change String
或Delete
构造。根据 msg 的构造方式,更新函数的行为有所不同。