我很新,目前正在努力学习榆树。我来自JS / React,并且没有任何以前的RFP经验。
我在这里的指南: http://guide.elm-lang.org/architecture/user_input/text_fields.html
我遇到问题的部分是update
和view
:
-- 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
我们是如何在此定义更改功能的?我们如何定义该功能的工作原理?对我而言,我们只是声明了Msg的类型,它以某种方式包含Change
和类型String
。
我的第二个问题是关于更新:
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 }
我不能到达那里的是箭头。通常箭头是在param定义之后。但是在这里我们得到了->
之前的函数结果。
我希望我的问题有道理,我对这种(可能是很棒的)语言非常困惑。
答案 0 :(得分:6)
当您声明type Msg = Change String
时,您声明一个类型(Msg
),其中一个构造函数接受一个字符串。
请参阅Union Types上的榆树指南部分(AKA代数数据类型,ADT)。
以下是一个示例:
type User = Anonymous | Named String
因此,创建类型
User
还会创建名为Anonymous
和Named
的构造函数。如果要创建User
,则必须使用这两个构造函数之一
构造函数是函数,因此您可以将它们称为Change "a string"
(返回类型Msg
)
构造函数还提供了使用模式匹配来提取联合类型中的内部值的功能。这是您不熟悉的->
的使用。
case msg of
Change theString -> ... use theString ...
你的第二个问题;
对我来说,这看起来像update是一个更高阶的函数,它接受一个Msg并返回一个函数Model - >模型
是的,这或多或少发生了什么。函数应用程序的优先规则意味着您可以不带括号调用它们。这称为 currying ,它也包含在榆树指南
中答案 1 :(得分:3)
只是为了澄清第二部分:
所有功能都是curry,这意味着update: Msg->Model->Model
可以收到Msg
并返回功能Model->Model
或接收Msg
和Model
并返回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 String
或Delete
构建Msg。根据msg的构造方式,更新函数的行为会有所不同。