Elm:如何定义一个以消息为参数执行请求的函数

Elm: How to define a function that performs a request with message as parameter

在 Elm 0.18 中,如何定义一个执行请求的函数,该函数在收到响应时将 消息 作为更新函数的参数?

以下代码:

mypost : String -> String -> msg -> Cmd msg
mypost url csrf mymsg =
    Http.request
        { method = "POST"
        , headers = [ Http.header "X-CSRFToken" csrf ]
        , url = url
        , body = Http.emptyBody
        , expect = Http.expectJson mydecoder
        , timeout = Nothing
        , withCredentials = False
        }
        |> RemoteData.sendRequest
        |> Cmd.map mymsg

不编译:

The argument to function map is causing a mismatch.

124| Cmd.map m ^ Function map is expecting the argument to be:

a -> msg

But it is:

msg

Hint: It looks like a function needs 1 more argument.

如果 msg 带有参数怎么办?例如:

|> Cmd.map (mymsg myParamTomymsg)

这导致我有很多代码重复,必须有更好的方法...

此答案是在假设您使用标准 Http 包的情况下编写的。如果您是 Elm 的新手,我建议您先试用一下,然后使用开源包。

TL;DR

代码中 mymsg 的类型应该是 a -> msg,其中类型变量 a 与解码器 mydecoder 产生的值类型相同

mypost : String -> String -> (a -> msg) -> Cmd msg

您必须明确指定类型并将 a 替换为响应类型。

更长的解释

换句话说,您必须明确说明传递给 Http.send 的第一个参数是一个函数,它将响应映射到消息。

定义联合类型时,Msg 是新类型的名称,NoOpUpdate 是实际值,可以充当 Msg类型。

type Msg
    = NoOp
    | Update String

通过在代码中使用Update "Hello"我们创建了一个Msg类型的值,其中字符串"Hello"被标记为Update同样的事情发生在Http.send,除了标记值的类型应该是 Result.

Update 的类型隐含为 String -> Msg

让我们看一下 Http.send:

的类型注释定义
send : (Result Error a -> msg) -> Request a -> Cmd msg

这是一个 generic GET request:

的例子
get : Int -> Difficulty -> (Result Error TriviaResult -> msg) -> Cmd msg
get amount difficulty msg =
    Http.get (triviaRequestUrl amount difficulty) decoder
        |> Http.send msg

如果您正在使用 remotedata

您必须修复您的类型定义注释:

myget1 : (WebData HttpBin -> msg) -> Cmd msg

希望对您有所帮助。