我正在学习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
答案 0 :(得分:4)
类型是“递归”的。您写了
formView label msg = div [] [text (label ++ ": "), input [onInput msg] []]
请注意msg
使用传入的onInput
。 onInput在标准库中定义为
onInput : (String -> msg) -> Attribute msg
因此,您调用的参数msg
必须具有类型String -> msg
。如果您的代码中没有其他矛盾的地方,那么您的代码将被编译。如果msg的其他用法与该推论相抵触,则编译器将强制您调和差异。
在您的情况下,您传递给formView EmailChanged
。您将其声明为用字符串完成的自定义类型。在幕后,榆树创建了一个函数,该函数接受String并返回Msg
并将其命名为EmailChanged
,而您传入的正是后者,并且遇到了预期的类型。最后一点魔术需要一点时间来适应,但是在榆树中无处不在,因此您很快就会熟悉。