复合类型和HTML onInput

时间:2018-11-22 02:12:46

标签: elm

一周前,我终于找到了一种方法,可以将邮件分为不同的类别(Here is the SO question where I got my answer

现在我已经实现了此解决方案:

type Msg 
    = AMsg AMsg
    | BMsg BMsg
    | CMsg CMsg

然后我将AMsg定义如下

type AMsg
    = ActionOne Int String
    | ActionTwo Int

除我将ActionOne与onInput Html.Event

一起使用外,其他所有方法都非常有效
input [onInput (AMsg (ActionOne model.id))] []

这个错误告诉我onInput需要一个String-> Msg类型,但正在获取AMsg类型。

例如,如果我使用onClick并自己输入第二个参数,这将很好用

input [onClick (AMsg (ActionOne model.id "hello"))] []

但是由于我需要使用onInput,这就是将第二个String参数传递给ActionOne的原因,我被困住了。如果我更改类型以适应此

type Msg 
    = AMsg AMsg String
    | BMsg BMsg
    | CMsg CMsg

type AMsg
    = ActionOne Int
    | ActionTwo Int

这可行,但是随后我强迫ActionTwo也接受一个我不想要的字符串。

否则,我将在消息下直接指定ActionOne

type Msg 
        = AMsg AMsg
        | BMsg BMsg
        | CMsg CMsg
        | ActionOne Int String

type AMsg
    = ActionTwo Int

我真的很想将Msgs分为不同的类别-如果我想将Elm用于更大的项目,这对我来说似乎至关重要。有什么想法吗?

2 个答案:

答案 0 :(得分:4)

您传递给onInput的函数必须具有类型String -> msg(或更具体的情况是String -> Msg。)

您可以使用lambda来实现:

input [onInput (\str -> (AMsg (ActionOne model.id str)))] []

您还可以使用函数组合(<<函数)来实现相同的功能,而无需明确地谈论参数str

input [ onInput <| AMsg << ActionOne model.id ]

答案 1 :(得分:1)

进一步解释Matt McHenry的答案:

有时候,当您遇到更复杂的情况时,可以更仔细地思考通常更简单的语法的实际含义。当您掌握了

的基本情况时
type Msg
    = GotInput String
...
input [onInput GotInput] []

然后GotInput是一个函数String -> Msg。您也可以将其明确写为:

input [onInput (\str -> GotInput str)] []

因此,您在这里为onInput提供了一个函数,该函数接受str参数,然后返回GotInput str

现在您已具备此基本功能,那么如何将其扩展到更复杂的情况将变得更加清晰-您只需更改返回值并在其中的正确位置包含str

input [onInput (\str -> (AMsg (ActionOne model.id str)))] []