用Elm解析JSON多态记录

用Elm解析JSON多态记录,elm,Elm,也许这是一个初学者的问题。我有一个保存多态记录的JSON数据格式,需要对其进行解析。这些是图的顶点或边 { "records": [{ "id": 0, "object": { "id": "vertex1" } }, { "id": 1, "object": { "id": "vertex2" } }, { "

也许这是一个初学者的问题。我有一个保存多态记录的JSON数据格式,需要对其进行解析。这些是图的顶点或边

{
    "records": [{
        "id": 0,
        "object": {
            "id": "vertex1"
        }
    }, {
        "id": 1,
        "object": {
            "id": "vertex2"
        }

    }, {
        "id": 2,
        "object": {
            "from": "vertex1",
            "to": "vertex2"
        }
    }]
}
如您所见,它们都具有
id
,但顶点和边具有不同的记录结构

我试图找到解析此类结构的方法,但我找到的唯一方法是,但我无法将答案转换为Elm 0.17(简单地将
数据
重命名为
类型
没有帮助)

一般来说,有两个挑战:

  • 定义多态记录
  • 将JSON动态解码为顶点或边
  • 这就是我取得的成绩:

    type alias RecordBase =
        { id : Int
        }
    
    type Records = List (Record RecordBase)
    
    type Record o =
        VertexRecord o
        | EdgeRecord o
    
    type alias VertexRecord o =
        { o | object : {
          id : Int
        }
      }
    
    type alias EdgeRecord o =
        { o | object : {
          from : Int
          , to : Int
        }
      }
    
    但是编译器抱怨

    命名多个顶级值
    VertexRecord
    会使事情变得复杂 模棱两可

    显然,
    union
    已经定义了
    VertexRecord
    EdgeRecord
    类型


    我真的不知道如何从这里开始。所有的建议都是非常受欢迎的。

    因为您的标签
    id
    位于多个位置,并且有多种类型,我认为使用类型别名和字段名来指示每个id的用途会让事情变得更干净一些

    编辑2016-12-15:更新至elm-0.18

    类型别名RecordID=Int
    类型别名VertexID=String
    类型别名VertexContents=
    {vertexID:vertexID}
    类型别名EdgeContents=
    {from:VertexID
    ,致:VertexID
    }
    
    您的
    记录
    类型实际上不需要在任何地方包含
    对象的字段名。您可以简单地使用联合类型。这里有一个例子。您可以通过几种不同的方式来塑造这一点,需要理解的重要部分是将这两种类型的数据作为单个记录类型进行拟合

    类型记录
    =顶点记录ID VertexContents
    |Edge记录ID EdgeContents
    
    您可以定义一个函数,该函数返回给定顶点或边的
    记录ID
    ,如下所示:

    getRecordID:Record->RecordID
    getRecordID r=
    案例r
    顶点记录ID->记录ID
    边缘记录ID->记录ID
    
    现在,开始解码。使用
    Json.Decode。然后,您可以解码公共记录ID字段,然后将Json传递给另一个解码器以获取其余内容:

    recordDecoder:Json.Decoder记录
    录音解码器=
    Json.field“id”Json.int
    |>Json.anthen\recordID->
    Json.oneOf[vertexDecoder recordID,EdgeCoder recordID]
    vertexDecoder:RecordID->Json.Decoder记录
    顶点解码器记录ID=
    Json.object2顶点
    (Json.recordID)
    (Json.object1 VertexContents(Json.at[“object”,“id”]Json.string))
    EdgeCoder:RecordID->Json.Decoder记录
    边编码器记录ID=
    Json.object2边缘
    (Json.recordID)
    (Json.object2 EdgeContents)
    (Json.at[“object”,“from”]Json.string)
    (Json.at[“object”,“to”]Json.string))
    recordListDecoder:Json.Decoder(列表记录)
    记录列表解码器=
    Json.field“records”Json.list recordDecoder
    
    将所有这些放在一起,您可以像这样解码您的示例:

    导入Html(文本)
    导入Json。解码为Json
    主要=
    
    文字哇!它起作用了@查德·吉尔伯特你帮了我很多!我自己找不到。非常感谢!