我正在尝试在寓言中编写一个通用的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>功能的同时保持其通用性?
谢谢
答案 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)