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

时间:2017-08-26 16:03:59

标签: elm

在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

无法编译:

  

函数map的参数导致不匹配。

     

124 | Cmd.map m                           ^   函数map期望参数为:

a -> msg
     

但它是:

msg
     

提示:看起来函数需要多一个参数。

如果msg采用参数怎么办?例如:

|> Cmd.map (mymsg myParamTomymsg)

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

1 个答案:

答案 0 :(得分:3)

这个答案是在您使用标准Http包的情况下编写的。如果您是榆树新手,我建议您先使用它并使用开源软件包。

TL; DR

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

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

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

更长的解释

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

定义联盟类型时,Msg是新类型的名称,NoOp Update是实际值,可以作为值{{1}的构造函数输入。

Msg

在代码中使用type Msg = NoOp | Update String ,我们创建了Update "Hello"类型的值,其中字符串Msg标记有标记"Hello"同样的事情发生在{{ 3}},但标记值的类型应为Http.send

Update的类型隐含为Update

让我们看一下Result.

的类型注释定义
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

我希望这会有所帮助。