受歧视联合中的可变内部价值

Mutable internal value in discriminated union

任务是创建一个二叉树,其节点有一个可以为真或假的成员is_locked和一个方法lock(),如果它是,则应将is_locked设置为真还没有。

我试过了

type BinaryTreeNode =
    | Node of BinaryTreeNode * BinaryTreeNode
    | End
    with
        let mutable internalIsLocked = false
        member this.is_locked
            with get() = internalIsLocked 
        member this.lock() = internalIsLocked <- true

但是由于 let 绑定中的 This declaration element is not permitted in an augmentation,编译器拒绝了。

val mutable internalIsLocked : bool 出于同样的原因而不起作用。

那这个问题怎么解决呢? 用有区别的工会解决不了吗?

如果你真的想这样做,你可以将可变状态移动到一个单独的 class 类型中,然后在你的区分联合中使用该类型:

type Lock() =
    let mutable internalIsLocked = false
    member this.is_locked
        with get() = internalIsLocked 
    member this.lock() = internalIsLocked <- true

type BinaryTreeNode =
    | Node of Lock * BinaryTreeNode * BinaryTreeNode
    | End
    with
    static member Create(left, right) =
        Node (Lock(), left, right)
    member this.Lock =
        match this with
            | Node (lock, _, _) -> Some lock
            | End -> None

请注意,我假设 End 节点不可锁定。用法:

let node = BinaryTreeNode.Create(End, End)
node.Lock.Value.is_locked |> printfn "%A"   // false
node.Lock.Value.lock()
node.Lock.Value.is_locked |> printfn "%A"   // true

但是,我不推荐它。