Reputation: 13
The task is to create a binary tree with its nodes having a member is_locked
that can be true or false and a method lock()
that shall set is_locked
to true if it's not already.
I tried this
type BinaryTreeNode =
| Node of BinaryTreeNode * BinaryTreeNode
| End
with
let mutable internalIsLocked = false
member this.is_locked
with get() = internalIsLocked
member this.lock() = internalIsLocked <- true
but compiler says no due to This declaration element is not permitted in an augmentation
at the let binding.
val mutable internalIsLocked : bool
instead does not work for the same reason.
How can this problem be solved then? Is it not solvable with discriminated unions?
Upvotes: 1
Views: 143
Reputation: 17038
If you really want to do this, you can move the mutable state into a separate class type, and then use that type in your discriminated union:
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
Note that I've assumed that End
nodes are not lockable. Usage:
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
However, I wouldn't recommend it.
Upvotes: 1