将 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)
我正在尝试在 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)