寓言-无法获取通用参数的类型信息,请内联或注入类型解析器

时间:2018-11-22 19:49:13

标签: f# fable-f#

我正在尝试在寓言中编写一个通用的json解码功能。它似乎可以在FSharp中编译,但是我收到此代码的错误消息:

[使用Thoth.Json库和Fable.PowerPack中的Fetch库]

let autoDecoder<'a> (json:string) (value:obj) : Result<'a, Thoth.Json.Decode.DecoderError> =
    let tryDecode = Thoth.Json.Decode.Auto.fromString<'a>(json)
    let getDecoderError (str:string) : Thoth.Json.Decode.DecoderError = ( "Auto decode Error", Thoth.Json.Decode.FailMessage str) 
    Result.mapError getDecoderError tryDecode

错误寓言:无法获取通用参数的类型信息,请内联或注入类型解析器

我不确定如何解决此问题,并且在Google上找不到任何内容。

我希望能够在寓言Elmish的更新函数中调用这样的函数:

let update (msg:Msg) (model:Model) =
    match msg with
..
    | OrStart ->
        let getData() = Fetch.fetchAs<ResultResponse>  "https://randomuser.me/api/" json.autoDecoder<ResultResponse> http.getHeaders
        model, Cmd.ofPromise getData () LoadedTypedData FetchError

如何在寓言autoDecoder <'a>功能的同时保持其通用性?

谢谢

2 个答案:

答案 0 :(得分:1)

我是寓言的新手,我无法使其工作,寓言编译器不允许在没有指定类型的情况下自动解码-此处失败:

Thoth.Json.Decode.Auto.fromString<'a>(str, true)

但是对于任何在寓言中苦苦挣扎的人来说,都可以用很少的样板代码来完成。我不能保证会通用,但是像getCustomers这样的特定于类型的实现非常简洁,我最终做了这样的事情:

type Msg =
    | Start
    | LoadedCustomerData of Result<QueryDataForJson, string>
..

let getCustomers () = promise {
    let! response = Fetch.fetch "http://localhost:5000/spa/api/customers" http.getHeaders
    let! text = response.text()
    return Thoth.Json.Decode.Auto.fromString<QueryDataForJson>(text, true)
}
..
let update (msg:Msg) (model:Model) =
    match msg with
    | Start ->
        model, Cmd.ofPromise getCustomers () LoadedCustomerData FetchError
    | LoadedCustomerData resp ->
        match resp with
            | Ok qdj -> { model with gridData= queryDataFromJson qdj; message= "Loaded Customer Data"  }, Cmd.none
            | Error str -> { model with message = str }, Cmd.none

答案 1 :(得分:1)

我认为寓言告诉您使用inline像这样:

let inline autoDecoder<'a> (json:string) (value:obj) : Result<'a, Thoth.Json.Decode.DecoderError> =
    let tryDecode = Thoth.Json.Decode.Auto.fromString<'a>(json)
    let getDecoderError (str:string) : Thoth.Json.Decode.DecoderError = ( "Auto decode Error", Thoth.Json.Decode.FailMessage str) 
    Result.mapError getDecoderError tryDecode

这是因为像内联函数一样的泛型函数需要为每个调用实例化。

顺便说一句,没有使用value参数。

您还可以像这样简化代码:

let inline autoDecoder<'a> (json:string) : Result<'a, Thoth.Json.Decode.DecoderError> =
    Thoth.Json.Decode.Auto.fromString<'a> json
    |> Result.mapError (fun (str:string) ->  "Auto decode Error", Thoth.Json.Decode.FailMessage str)