Elm 为什么这个函数要这样注释?

Elm 为什么这个函数要这样注释?,elm,Elm,我正在学习Elm,并试图理解泛型函数的类型注释是如何编写的。(不确定“通用函数”这是Elm中的正确术语,请告知。) 给定以下代码: import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) type Msg = EmailChanged String | PasswordChanged String formView label msg = div [] [t

我正在学习Elm,并试图理解泛型函数的类型注释是如何编写的。(不确定“通用函数”这是Elm中的正确术语,请告知。)

给定以下代码:

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)

type Msg = EmailChanged String | PasswordChanged String

formView label msg = div [] [text (label ++ ": "), input [onInput msg] []]

main = div [] [formView "Email" EmailChanged, formView "Password" PasswordChanged]
像这样注释
formView
函数的原因是什么

formView : String -> (String -> msg) -> Html msg
这个注释背后的原因是什么,函数不正确

formView : String -> msg -> Html Msg

这些类型是递归“推断”的。你写的

formView label msg = div [] [text (label ++ ": "), input [onInput msg] []]
注意您传入的
msg
是如何被
onInput
使用的。在标准库中定义为

onInput : (String -> msg) -> Attribute msg
因此,您调用的参数
msg
需要具有类型
String->msg
。如果代码中没有其他内容与此相矛盾,那么代码将编译。如果msg的其他用法与该推断相矛盾,那么编译器将强制您协调差异


在您的情况下,您传递给formView
EmailChanged
。您已将其声明为自定义类型,并用字符串完成。在幕后,elm创建了一个函数,该函数接受一个字符串并返回
Msg
,然后调用它
EmailChanged
,而您传入的正是后一个函数,它满足了预期的类型。这最后一点魔力需要一点习惯,但它在Elm中无处不在,因此您很快就会熟悉。

类型是递归“推断”的。你写的

formView label msg = div [] [text (label ++ ": "), input [onInput msg] []]
注意您传入的
msg
是如何被
onInput
使用的。在标准库中定义为

onInput : (String -> msg) -> Attribute msg
因此,您调用的参数
msg
需要具有类型
String->msg
。如果代码中没有其他内容与此相矛盾,那么代码将编译。如果msg的其他用法与该推断相矛盾,那么编译器将强制您协调差异

在您的情况下,您传递给formView
EmailChanged
。您已将其声明为自定义类型,并用字符串完成。在幕后,elm创建了一个函数,该函数接受一个字符串并返回
Msg
,然后调用它
EmailChanged
,而您传入的正是后一个函数,它满足了预期的类型。这最后一点魔法需要一点习惯,但它在榆树中无处不在,所以你会很快变得熟悉