gpt4 book ai didi

json - Elm:解析 JSON 中的状态代码(带有潜在的错误消息)

转载 作者:行者123 更新时间:2023-12-04 16:50:28 26 4
gpt4 key购买 nike

我在用 Elm 解析 JSON 时遇到了一些困难。我似乎没有掌握基础知识,但出于某种原因,这一小段 JSON 让我感到困惑。

场景如下:我发布到一个 JSON API,它将以两种格式之一返回:

如果请求成功:

{
"status": "success",
"post": { ... }
}

如果失败:

{
"status": "error",
"message": "Some error message"
}

我正在尝试将此 JSON 响应编码为这些数据类型:

type RequestStatus = Success | Error String


type alias CreatePostResponse =
{ status : RequestStatus
, post : Maybe Post }

到目前为止,我运气不好。我一直在浏览 JSON.Decode教程和this Thoughtbot article作为向导,但似乎都没有把我带到正确的地方。这是我到目前为止的代码:

createPostResponse : Decoder CreatePostResponse
createPostResponse =
succeed CreatePostResponse
|: (("status" := string) `andThen` (("error" := string) `andThen` decodeStatus))
|: maybe ("post" := post)


decodeStatus : String -> String -> Decoder RequestStatus
decodeStatus status errorMessage =
succeed (case status of
"success" -> Success
"error" -> Error errorMessage
_ -> Error "unknown")

显然这会产生各种类型错误并且无法编译,但我一直无法想出一个好方法将字符串从“消息”字段获取到 RequestStatus 类型。

有没有人有什么想法?

最佳答案

这是一小段工作代码,应该可以满足您的需求。为了具体起见,我冒昧地假设了 Post 类型的基本形状。

import Json.Decode exposing (..)

type alias Post = { title: String, body: String }

type RequestStatus = Success Post | Error String

post: Decoder Post
post = object2 Post ("title" := string) ("body" := string)

requestStatusData: String -> Decoder RequestStatus
requestStatusData status =
case status of
"success" -> object1 Success ("post" := post)
"error" -> object1 Error ("message" := string)
_ -> fail <| status ++ " is not a valid value for request status"

decodeStatus : Decoder RequestStatus
decodeStatus =
("status" := string) `andThen` requestStatusData

首先,我将 RequestStatusCreatePostResponse 类型从里到外翻转:而不是 CreatePostResponse 具有 RequestStatus和一个 Maybe Post,它们需要彼此保持同步,RequestStatus 类型本身模拟了一个事实,即成功有一个帖子,而错误没有.新的 RequestStatus 读起来更像惯用的 Elm。

然后我从上到下进行了解码:

  1. 要将一些 JSON 解码为 RequestStatus,我们首先将 JSON 对象中的 "status" 属性反序列化为字符串,然后反序列化其余的基于"status" 是什么。执行此操作的惯用方法是使用 andThen(看起来您知道这一点,但还没有完全完善它与其余部分的配合方式)。这转化为:

    decodeStatus : Decoder RequestStatus
    decodeStatus =
    ("status" := string) `andThen` requestStatusData
  2. andThen 解码一个记录,然后将该记录传递给一个函数,该函数完成剩余的解码,因此 requestStatusData 需要看起来像:

    requestStatusData: String -> Decoder RequestStatus

    requestStatusDataSuccess PostError String。因此,我们需要两个分支,然后与状态 “成功”“错误” 相关联(加上一个默认值以捕获格式错误的状态):

    requestStatusData status =
    case status of
    "success" -> makeSuccessWithPost
    "error" -> makeErrorWithString
    _ -> fail <| status ++ " is not a valid value for request status"
  3. 我们填写makeSuccessWithPostmakeErrorWithString 实现。 Json.Decode 中的 objectN 函数提供了一种解码组件的功能,然后将它们提供给构造函数(或其他函数):

    object1 Success ("post" := post)

    首先使用定义为 post 的解码器解码 "post" 属性,然后调用 object1 的第一个参数(成功) 在结果上。同样,

    object2 Post ("title" := string) ("body" := string)

    使用string解码器解码“title”,然后使用string解码器解码“body”,然后调用 Post 函数,将两个解码后的字符串作为参数。所以我们最终得到:

    requestStatusData status =
    case status of
    "success" -> object1 Success ("post" := post)
    "error" -> object1 Error ("message" := string)
    _ -> fail <| status ++ " is not a valid value for request status"
  4. 最后一步是填写post解码器,上面说的是object2的标准应用。

总的来说,我认为我已经以相当标准、惯用的 Elm 风格处理了这个问题,但我是新手,我可能会犯一些错误。它确实有效!最后一点:我认为 RequestStatus 类型实际上并不是必需的; Elm 核心库中的 Result 类型捕捉了具有成功和失败模式的类型的概念。你可以使用

Result String Post

而不是 RequestStatus 而不会丢失任何功能(您需要稍微更改 requestStatusData 但我会把它留给读者练习......)。

关于json - Elm:解析 JSON 中的状态代码(带有潜在的错误消息),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40098899/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com