F#中的结构依赖----可能没有可变和可空的字段?

时间:2014-05-23 16:59:41

标签: f# c#-to-f#

我希望有两种类型相互作为字段:

type Player<'Team>(team:'Team) =
    member this.Team = team

type DoublesTeam(playerA:Player<DoublesTeam>, playerB:Player<DoublesTeam>) =
    member this.PlayerA = playerA
    member this.PlayerB = playerB

(这是参数化以打破类型之间的循环依赖)。

问题:如何创建这些类型的实例以使它们彼此指向?

在C#中,这很明确:创建两个玩家而不指定Team字段(即保持为null),创建一个Team在构造函数中传递两个玩家并手动将他们的Team字段设置为Team实例。要在F#中执行此操作,Team字段需要是可变的,可空的或选项类型。这是非常不受欢迎的。

有没有办法在不将其中一个字段置为可空或选项类型的情况下执行此操作?

1 个答案:

答案 0 :(得分:4)

您将无法使用类完全以该形式执行此操作。但是,如果切换到记录,则很容易:

type Player<'Team> = { team:'Team }

type DoublesTeam = { playerA:Player<DoublesTeam>; playerB:Player<DoublesTeam> }

let rec t1 = {playerA = p1; playerB = p2 }
and p1 = { team = t1 }
and p2 = { team = t1 }

请注意,可以使用类来执行此操作,但您必须引入某种形式的延迟;最简单的方法可能是增加一丝懒惰:

type Player<'Team>(team:Lazy<'Team>) =
    member this.Team = team.Value

type DoublesTeam(playerA:Lazy<Player<DoublesTeam>>, playerB:Lazy<Player<DoublesTeam>>) =
    member this.PlayerA = playerA.Value
    member this.PlayerB = playerB.Value

let rec t1 = DoublesTeam(lazy p1, lazy p2)
and p1 = Player(lazy t1)
and p2 = Player(lazy t1)