复合类型和 Html onInput

Nic*_*tti 3 elm

一周前,我终于找到了一种将我的消息分成不同类别的方法(这是我得到答案的 SO 问题

现在我已经实施了这个解决方案:

type Msg 
    = AMsg AMsg
    | BMsg BMsg
    | CMsg CMsg
Run Code Online (Sandbox Code Playgroud)

然后我将 AMsg 定义如下

type AMsg
    = ActionOne Int String
    | ActionTwo Int
Run Code Online (Sandbox Code Playgroud)

一切都很好,除非我将 ActionOne 与 onInput Html.Event

input [onInput (AMsg (ActionOne model.id))] []
Run Code Online (Sandbox Code Playgroud)

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

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

input [onClick (AMsg (ActionOne model.id "hello"))] []
Run Code Online (Sandbox Code Playgroud)

但是因为我需要使用 onInput 并且这就是将第二个 String 参数传递给 ActionOne 的原因,所以我被卡住了。如果我改变我的类型来适应这个

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

type AMsg
    = ActionOne Int
    | ActionTwo Int
Run Code Online (Sandbox Code Playgroud)

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

否则我会被困在直接在 Msg 下指定 ActionOne

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

type AMsg
    = ActionTwo Int
Run Code Online (Sandbox Code Playgroud)

我真的很关心将 Msgs 分成不同的类别——如果我想将 elm 用于更大的项目,这对我来说似乎非常重要。有任何想法吗 ?

Mat*_*nry 5

您传递给的函数onInput必须具有类型String -> msg(或者更具体地说,在您的情况下,String -> Msg.)

您可以通过使用 lambda 来实现:

input [onInput (\str -> (AMsg (ActionOne model.id str)))] []
Run Code Online (Sandbox Code Playgroud)

你也可以使用函数组合(<<函数)来实现同样的事情,而无需str明确地谈论参数:

input [ onInput <| AMsg << ActionOne model.id ]
Run Code Online (Sandbox Code Playgroud)