将 JSON 解码为非别名类型

Decoding JSON into a non-alias type

我正在尝试在 Elm 中直接或间接解码递归类型,这要求至少其中一个被定义为 "proper"、非别名类型。我正在使用 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
    }

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

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

那么你在编写解码器的过程中还需要克服两个障碍。

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

类型的参数

第二个是你需要在 list 的定义中引用解码器 list,它被编译器标记为 "bad recursion."

第一个问题的解决方案是创建您自己的列表制作功能:(\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)