【问题标题】:Elm "type" syntax - where is value coming from?榆树“类型”语法——价值从何而来?
【发布时间】:2016-05-20 18:11:07
【问题描述】:

我很新,目前正在尝试学习 Elm。我来自 JS/React,之前没有任何 RFP 经验。

我在此处的指南中: http://guide.elm-lang.org/architecture/user_input/text_fields.html

我遇到问题的部分是updateview

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

它有一个参数,在本例中是 Change 函数 在我们声明 Msg 类型时创建:

更改:字符串 -> 消息

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

type Msg
  = Change String

我们如何在这里定义一个 Change 函数?我们如何定义该功能的工作方式?在我看来,我们似乎刚刚声明了 Msg 的类型,它以某种方式包含 ChangeString 类型。

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

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

在我看来,update 是一个高阶函数,它接受 Msg 并返回函数 Model -> Model。但随后我们定义了一个带有两个参数的函数。 Msg -> Model -> Model 是否仅表示除最后一部分之外的所有部分都是参数?

然后我们调用Change函数:

Change newContent ->
          { model | content = newContent }

我不明白的是箭头。通常箭头出现在参数定义之后。但是这里我们在->之前有一个函数的结果。

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

【问题讨论】:

    标签: syntax elm


    【解决方案1】:

    当您声明 type Msg = Change String 时,您声明了一个单一类型 (Msg),其中包含一个接受字符串的构造函数。

    请参阅 Union Types(AKA 代数数据类型,ADT)上的 Elm 指南部分。

    这是一个示例:

    type User = Anonymous | Named String
    

    所以创建User 类型也创建了名为AnonymousNamed 的构造函数。如果你想创建一个User,你必须使用这两个构造函数之一

    构造函数是函数,因此您可以将它们称为Change "a string"(返回类型为Msg

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

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

    你的第二个问题;

    在我看来,update 是一个高阶函数,它接受一个 Msg 并返回一个函数 Model -> Model

    是的,差不多就是这样。函数应用的优先规则意味着你可以不带括号调用它们。这称为 currying,elm 指南中也有介绍

    【讨论】:

      【解决方案2】:

      只是为了澄清一下第二部分:

      所有函数都是柯里化的,这意味着update: Msg->Model->Model 可以接收Msg 并返回函数Model->Model 或接收MsgModel 并返回Model

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

      箭头只是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 = "" }
      

      在前一种情况下,可以使用Change StringDelete 构造Msg。根据 msg 的构造方式,更新函数的行为会有所不同。

      【讨论】:

        猜你喜欢
        • 2018-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-12
        • 1970-01-01
        • 2016-07-15
        • 2017-02-10
        相关资源
        最近更新 更多