【问题标题】:What is the 'msg' in 'HTML msg' in Elm actually?Elm 中“HTML msg”中的“msg”实际上是什么?
【发布时间】:2019-11-23 13:05:29
【问题描述】:

我正在自学榆树,并且看到(当然)很多引用 Html msg--

我知道这是一个“参数化类型”,也就是说(据我所知)Html 类型的构造函数接受一个参数——就像List Char 一样。

好的。但随后在一些教程中,我看到他们很快将msg 更改为自定义类型,通常是这样的(我是凭记忆这样做的,所以请原谅我):

Html Msg

Msg 可能被定义为

type Msg =
  Something | SomethingElse

我在这里也看到了——https://discourse.elm-lang.org/t/html-msg-vs-html-msg/2758——他们说

小写的 msg 称为类型变量。大写的 Msg 被称为具体类型 - 它是您的应用程序定义的。

这部分回答了我的问题,但有人可以详细说明这究竟意味着什么吗?因为当我看到List String 之类的东西时,我明白String 在这种情况下是什么意思,但我不明白msgHtml msg 中的含义。

另外,我们不是在改变函数返回值的类型吗?也就是说,如果 Elm 运行时期望 view 返回某个类型,而该类型是 Html msg,如果我们将返回类型更改为 Html Whatever,为什么会这样呢? (例如,我们不能随意将函数的返回值从List String 更改为List Number,对吧?)

来自 OOP 和 C、TypeScript 等类型语言的背景,我认为任何Msg 都需要以某种方式与msg 相关,即以某种方式“扩展”它以允许多态性.显然我看错了,任何解释都将不胜感激!

【问题讨论】:

    标签: elm parametric-polymorphism


    【解决方案1】:

    tl;dr:只要每个函数都同意msgmodel 的类型,它们可以是任何你想要的。

    就像List的类型参数一样,msg可以是任何东西。没有限制。为了演示,这是一个经典的递增/递减示例,msg 只是一个 Int

    -- These type aliases aren't needed, but makes it easier to distinguish
    -- their roles in later type signatures
    type alias Model = Int
    type alias Msg = Int
    
    
    update : Msg -> Model -> Model
    update msg model =
        model + msg
    
    
    view : Model -> Html Msg
    view model =
        div []
            [ button [ onClick 1 ] [ text "+1" ]
            , div [] [ text <| String.fromInt model.count ]
            , button [ onClick (-1) ] [ text "-1" ]
            ]
    
    
    main : Program () Model Msg
    main =
        Browser.sandbox { init = 0, view = view, update = update }
    

    那么它是如何工作的呢?关键在于Browser.sandbox 函数,因为这就是将所有内容连接在一起的原因。它的类型签名是:

    sandbox :
        { init : model
        , view : model -> Html msg
        , update : msg -> model -> model
        }
        -> Program () model msg
    

    其中modelmsg 是类型变量。这两个都可以替换为任何具体类型,只要它与此签名中给出的约束相匹配,即它们在initviewupdate 函数中必须相同。否则我们会在这里得到一个类型错误。例如,如果update 需要String 而不是Int,我们将收到错误:

    This argument is a record of type:
    
        { init : Model, update : String -> Model -> Model, view : Model -> Html Msg
        }
    
    But `sandbox` needs the 1st argument to be:
    
        { init : Model
        , update : String -> Model -> Model
        , view : Model -> Html String
        }
    

    它并不真正知道哪个是对还是错,当然,只是有一个不匹配。但为了提供帮助,它假定 String 是正确的,并期望 view 改为返回 Html String

    我希望这足以回答您的问题。如果没有,请评论和订阅!

    【讨论】:

    • 那么是否总是需要将msg 替换为您自己的类型?也就是说,不能只留下Html msg,而是准确地告诉系统您将在view 中发送和在update 中接收的什么 类型的消息?
    • 你没有。您可以编写处理任何类型的msg 的函数。毕竟,Browser.sandbox 就是这样做的。它只是传递值,就像一个可以容纳任何东西的盒子。您也不需要使用带有viewupdate 的具体类型,但当然这不会是一个非常有用的应用程序。它将是完全静态的。
    【解决方案2】:

    你的问题的答案最好通过例子来说明。

    简短的解释:

    我有一个这样的圣诞节功能:

    wrapPresents : presents -&gt; String

    但是presents 是什么类型?它可以是你想要的任何东西!您可以将其替换为您自己的“具体类型”。 presents 只是一个占位符!

    wrapPresents : Boxes -&gt; String wrapPresents boxes = "All the boxes are now wrapped!"

    总结:msg(小写)只是一个占位符

    【讨论】:

      猜你喜欢
      • 2017-07-30
      • 1970-01-01
      • 2011-09-29
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多