将JSON解码为非别名类型

时间:2018-01-08 04:22:09

标签: json elm

我正在尝试直接或间接地解码Elm中的递归类型,这要求至少将其中一个定义为“正确的”非别名类型。我正在使用Json.Decode.Pipeline。这是我用alias做的方法,显然不起作用:

import Json.Decode as Jdec
import Json.Decode.Pipeline as Jpipe

type alias List =
    { next : Maybe List
    , item : Float
    }

list : Jdec.Decoder List
list =
    Jpipe.decode List
        |> Jpipe.optional "next" (Jdec.nullable list) Nothing
        |> Jpipe.required "item" Jdec.float

如果List被正确定义为

,如何使解码功能起作用
type List = List
    { next : Maybe List
    , item : Float
    }

1 个答案:

答案 0 :(得分:3)

如果您按照建议定义递归类型:

type List = List
    { next : Maybe List
    , item : Float
    }

然后你仍然需要克服编写解码器的两个障碍。

第一个是List不再是类型别名的名称,因此,它不再是创建列表的两个参数的函数。相反,List是一个构造函数,接受一个{next : Maybe List, item : Float}类型的参数。

第二个是你需要在list的定义中引用list解码器,它被编译器标记为"错误的递归。"

第一个问题的解决方案是创建自己的列表制作功能:(\next item -> List {next=next, item=item})。第二个问题的解决方案是使用Json.Decode.lazy,它允许您使用解码器返回闭包代替解码器:

list : Jdec.Decoder List
list =
    Jdec.map2 (\next item -> List {next=next, item=item})
          (Jdec.field "next" (Jdec.lazy (\_ -> Jdec.nullable list)))
          (Jdec.field "item" Jdec.float)