Syntax 榆树;“类型”;语法-值从何而来?

Syntax 榆树;“类型”;语法-值从何而来?,syntax,elm,Syntax,Elm,我是个新手,目前正在努力学习Elm。我来自JS/React,之前没有任何RFP经验 我就在这里的指南中: 我遇到的问题是更新和查看: -- UPDATE type Msg = Change String update : Msg -> Model -> Model update msg model = case msg of Change newContent -> { model | content = newContent } -- V

我是个新手,目前正在努力学习Elm。我来自JS/React,之前没有任何RFP经验

我就在这里的指南中:

我遇到的问题是
更新
查看

-- 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声明开始。指南说:

它需要一个参数,在本例中是 在声明Msg类型时创建:

更改:字符串->消息

我不明白这是怎么发生的:

type Msg
  = Change String
我们是如何定义变更函数的?我们如何定义该函数的工作原理?在我看来,我们只是声明了Msg的类型,它以某种方式包含了
Change
是什么以及类型
String

我的第二个问题是关于更新:

update : Msg -> Model -> Model
update msg model =
  case msg of
    Change newContent ->
      { model | content = newContent }
对我来说,这看起来像是一个更高阶的函数,它接受一个
Msg
并返回一个函数
Model->Model
。但是我们定义了一个有两个参数的函数。
Msg->Model->Model
是否仅仅意味着除了最后一部分以外的所有部分都是参数

然后我们调用
Change
函数:

Change newContent ->
          { model | content = newContent }
我不明白的是箭头。通常,箭头位于参数定义之后。但是这里我们有一个函数的结果,在
->
之前


我希望我的问题是有意义的,我只是对这种(想必是很棒的)语言感到非常困惑。

当你声明
type Msg=Change String
时,你声明的是一个单一类型(
Msg
)和一个接受字符串的构造函数

请参阅Elm指南中关于(也称为代数数据类型,ADT)的部分

以下是一个示例:

因此,创建类型
User
还创建了名为
Anonymous
named
的构造函数。如果要创建
用户
,必须使用这两个构造函数之一

构造函数是函数,因此您可以像调用
Change“a string”
(返回type
Msg

构造函数还提供了使用模式匹配来提取联合类型中的内部值的能力。这是您不熟悉的
->
的用法

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

你的第二个问题

对我来说,这看起来像是一个更高阶的函数,它接受一个Msg并返回一个函数Model->Model


是的,这或多或少就是正在发生的事情。函数应用程序的优先规则意味着您可以在不使用括号的情况下调用它们。这就是所谓的咖喱,elm指南中也介绍了这一点,只是为了进一步澄清第二部分:

所有函数都是curry,这意味着
update:Msg->Model->Model
可以接收
Msg
并返回函数
Model->Model
,或者接收
Msg
Model
并返回
Model

实际上,当您调用
updateamessage aModel
时,实际上是在调用
updateamessage
,它返回一个函数,然后将
aModel
传递给该函数,该函数将运行函数体中的表达式并返回更新后的模型

箭头只是
案例的一部分。。属于
语法。左侧是要匹配的模式,右侧是要执行的表达式。在您的情况下,只有在使用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的构造方式,update函数的行为有所不同

type Msg
  = Change String | Delete

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