有类型
type User
= Anonymous
| Named {name : String, email : String}
Json.Decode.object2
不适合此处,因为其第一个参数类型为(a -> b -> c)
,但Named
具有{ email : String, name : String } -> User
类型。
如何解码给用户?
答案 0 :(得分:3)
另一种方法是定义一个接受名称和电子邮件并返回Named
构造函数的函数:
userDecoder : Decoder User
userDecoder =
let
named =
object2
(\n e -> Named { name = n, email = e })
("name" := string)
("email" := string)
in
oneOf [ null Anonymous, named ]
答案 1 :(得分:2)
由于您的Named
构造函数将记录作为参数,因此为名称和电子邮件记录创建类型别名可能会更加清晰。
type alias NamedUserInfo =
{ name : String
, email : String
}
然后,您可以重新定义User
以使用别名:
type User
= Anonymous
| Named NamedUserInfo
虽然以上并不是绝对必要的,但我发现别名记录类型在很多方面证明是有用的。这里有用,因为它为我们提供了一个构造函数NamedUserInfo
,可以让我们清楚地定义解码器:
import Json.Decode exposing (..)
namedUserInfoDecoder : Decoder NamedUserInfo
namedUserInfoDecoder =
object2
NamedUserInfo
("name" := string)
("email" := string)
最后,您的用户解码器可以像这样构建:
userDecoder : Decoder User
userDecoder =
oneOf
[ null Anonymous
, object1 Named namedUserInfoDecoder
]
你可以通过这样的快速测试来运行你的例子:
exampleJson =
"""
[{"user":null}, {"user": {"name": "John Doe", "email": "j.doe@mailg.com"}}]
"""
main =
text <| toString <| decodeString (list ("user" := userDecoder)) exampleJson
-- Ouputs:
-- Ok ([Anonymous,Named { name = "John Doe", email = "j.doe@mailg.com" }])