使用andThen将多态JSON对象解码为elm

使用andThen将多态JSON对象解码为elm,json,elm,Json,Elm,我的JSON与此类似: { "items" : [ { "type" : 0, "order": 10, "content": { "a" : 10, "b" : "description", ... } } , { "type" : 1, "order": 11, "content": { "a" : 11, "b" : "same key, but different use", ... } } , { "type" : 2, "order": 12, "content":

我的JSON与此类似:

{ "items" : 
  [ { "type" : 0, "order": 10, "content": { "a" : 10,  "b" : "description", ... } }
  , { "type" : 1, "order": 11, "content": { "a" : 11,  "b" : "same key, but different use", ... } }
  , { "type" : 2, "order": 12, "content": { "c": "totally different fields", ... } }
   ...
  ] 
}
我想使用
type
值来决定解码时要创建的联合类型。因此,我在elm中为上述所有内容定义了别名类型和解码器:

import Json.Decode exposing (..)
import Json.Decode.Pipeline exposing (..)

type alias Type0Content = { a : Int, b : String }
type alias Type1Content = { a : Int, b2 : String }
type alias Type2Content = { c : String }
type Content = Type0 Type0Content | Type1 Type1Content | Type2 Type2Content
type alias Item = { order : Int, type : Int, content: Content }

decode0 = succeed Type0Content
    |> requiredAt ["content", "a"] int
    |> requiredAt ["content", "b"] string
decode1 = succeed Type1Content
    |> requiredAt ["content", "a"] int
    |> requiredAt ["content", "b"] string
decode2 = succeed Type2Content
    |> requiredAt ["content", "c"] string
decodeContentByType hint =
    case hint of
        0 -> Type0 decode0
        1 -> Type1 decode1
        2 -> Type2 decode2
        _ -> fail "unknown type"
decodeItem = succeed Item
    |> required "order" int
    |> required "type" int `andThen` decodeContentByType
无法根据需要使最后两个函数进行交互。 我已经阅读了Brian Thicks的json生存工具包第33页,但这也没有让我走上正轨


任何建议和讲座都将不胜感激

这本书似乎是针对Elm 0.17或更低版本编写的。在Elm 0.18中。您还需要为
类型
使用不同的字段名,因为它是一个保留字,所以我将重命名它
类型

一些注释可能有助于缩小bug的范围。让我们注释
decodeContentByType
,因为现在,分支返回的不是相同的类型。三个成功的值应将解码器映射到预期的
内容
构造函数:

decodeContentByType:Int->解码器内容
decodeContentByType提示=
案例提示
0->映射类型0解码0
1->地图类型1解码1
2->地图类型2解码2
_->失败“未知类型”
现在,解决
decodeItem
函数。我们需要三个字段来满足
构造函数。第二个字段是类型,可以通过
必需的“type”int
获得,但第三个字段依赖
的“type”
值来推断正确的构造函数。在使用Elm的
字段
解码器获取
解码器Int
值后,我们可以使用
(从Elm 0.18开始使用管道语法):

decodeItem:解码器项
解码项=成功项
|>必需的“订单”整数
|>必需的“类型”int
|>自定义(字段“type”int |>然后按类型解码ContentByType)

您忘了提到
必需的
自定义的
属于
Json.Decode.Pipeline
。如果您想坚持核心软件包,可以使用
map3
field
。感谢Chad和Chris提供的解决方案和有用的解释。我发现找到这么多0.18之前的教程,甚至对
Decode.Pipeline.custom
的新解释都没有帮助,这让我很不安。你的描述帮助更大。