我正在学习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在标准库中定义为
onInput : (String -> msg) -> Attribute msg
因此,您调用msg
的参数需要具有String -> msg
类型。如果您的代码中没有其他内容与您的代码相反,则代码将编译。如果msg的其他一些使用与该推断相矛盾,那么编译器将强制您调和差异。
在您的情况下,您传递给formView EmailChanged
。您将此声明为使用String填充的自定义类型。在幕后,elm创建了一个函数,它接受一个String并返回Msg
并将其命名为EmailChanged
,而后一个函数是你传入的并且符合预期类型。这最后一点点魔法需要一点时间习惯,但它在Elm中无处不在,所以你很快就会变得熟悉。