What are the pros and cons of each of the following two ways to create a tree node?
type TreeNode = | TreeNode of int * (TreeNode option) * (TreeNode option) * (TreeNode option)
type Node = | Node of int * Node * Node
| None
What are the pros and cons of each of the following two ways to create a tree node?
type TreeNode = | TreeNode of int * (TreeNode option) * (TreeNode option) * (TreeNode option)
type Node = | Node of int * Node * Node
| None
They are very close, but not entirely equivalent. You can actually reason about functional types quite nicely using mathematics (see for example my recent article), but you can see that even informally.
Given any TreeNode(num, optLeft, optRight)
, you can always create a Node
containing the same information (None
of the option type will be mapped to Node.None
).
Interestingly, this does not work the other way round. If someone gives you Node.None
, you cannot turn it into TreeNode
, because TreeNode
needs at least one integer in the root.
So, they are equivalent with the exception that the second one allows empty trees. From the practical perspective, the second type seems easier to use (because you only have to handle empty tree in one place).