Elm允许循环引用吗?
假设有两种数据类型:Elm允许循环引用吗?,elm,Elm,假设有两种数据类型: type alias Player = { name : String , team : Team } type alias Team = { name : String , players : List Player } 这个JSON: { "players": [ { "id": 100, "name": "Sam Bradford", "teamId": 200 }, { "id": 101, "name": "Kyl
type alias Player =
{ name : String
, team : Team
}
type alias Team =
{ name : String
, players : List Player
}
这个JSON:
{
"players": [
{ "id": 100, "name": "Sam Bradford", "teamId": 200 },
{ "id": 101, "name": "Kyle Rudolph", "teamId": 200 },
{ "id": 102, "name": "Matthew Stafford", "teamId": 201 },
{ "id": 103, "name": "Marvin Jones Jr.", "teamId": 201 },
{ "id": 104, "name": "Golden Tate", "teamId": 201 },
],
"teams": [
{ "id": 200, "name": "Minnesota Vikings" },
{ "id": 201, "name": "Detroit Lions" },
]
}
很明显,这个JSON可以被解码成非空链接对象,这可以由JSON解码器在解码数据时确定。有没有办法解码这个JSON并创建链接的数据结构?我不知道如何使用完全不可变的数据结构,或者如果可能的话。使用不可变的数据结构,不可能创建以某种循环方式相互引用的完全耦合的值层次结构 问题的核心可以通过几个步骤来说明:
我建议使用球员和球队的
Dict
,根据各自的ID进行索引,以便于查找。Elm中的递归数据类型有一个很好的解释
如果尝试编译数据类型,则会出现以下错误:
-- ALIAS PROBLEM ---------------------------------------------------------------
This type alias is part of a mutually recursive set of type aliases.
4|>type alias Player =
5|> { name : String
6|> , team : Team
7|> }
The following type aliases are mutually recursive:
┌─────┐
│ V
│ Player
│ │
│ V
│ Team
└─────┘
You need to convert at least one `type alias` into a `type`. This is a kind of
subtle distinction, so definitely read up on this before you make a fix:
<https://github.com/elm-lang/elm-compiler/blob/0.17.0/hints/recursive-alias.md>
更新:您在问题中还提到了null
引用。在上面的数据类型中,每个玩家必须有一个团队。如果团队是可选字段,我将定义如下:
type alias Player =
{ name : String
, teamID : Maybe ID
}
对于列表
和字符串
类型,实际上不需要可能
类型。使用[]
(空列表)和“
(空字符串)可以更轻松地为这些对象设置空状态
PS:另一个假设是,您需要在模型的每个团队中存储团队成员列表。因为严格来说你不需要:球员名单已经有了确定哪些球员(如果有的话)属于X队所需的所有数据。
请注意,如果您维护双向参考,需要做大量工作(并可能导致严重的错误):如果一名球员更换球队,您需要更新3条记录(1名球员+2名球队记录)。如果您真的想要一个如您所述的结构,球队和球员可以在浅层上相互参考,它可以通过一些
Json实现。然后是acrobatic。我很好奇,所以我继续写了一个快速而肮脏的例子来说明如何做到这一点。顺便说一句:@ChadGilbert在回答中也提到了用Dict
和ID
处理循环引用。
type alias Player =
{ name : String
, teamID : Maybe ID
}