我正在尝试直接或间接地解码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
}
答案 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)