I have an element which I want to store in a tree.
protocol GenericElement<Key, Value>
{
associatedtype Key
associatedtype Value
}
The tree consists of nodes and leafs which adhere to common protocol.
protocol Page<Element>
{
associatedtype Element : GenericElement
func fetch(for: Element.Key) -> Element?
}
struct Node<Element> : Page
where Element : GenericElement
{
func fetch(for: Element.Key) -> Element? { nil }
}
struct Leaf<Element> : Page
where Element : GenericElement
{
func fetch(for: Element.Key) -> Element? { nil }
}
The tree has a root which is either a node or a leaf.
struct Tree<Element>
where Element : GenericElement
{
var root: any Page<Element>
}
I want to fetch an element from the tree.
extension Tree
{
func fetch(for key: Element.Key) -> Element? { root.fetch(for: key) }
}
Unfortunately this does not compile:
Member 'fetch' cannot be used on value of type 'any Page<Element>';
consider using a generic constraint instead
This however does compile:
protocol Page<Element, Key>
{
associatedtype Element : GenericElement where Element.Key == Key
associatedtype Key
func fetch(for: Key) -> Element?
}
with root being:
var root: any Page<Element, Element.Key>
The same Element with the same associated Key is used everywhere.
I kinda expected that passing along Element would be sufficient for the compiler to know about Key.
If somebody could explain to me why my expectation was wrong, it would be much appreciated.
It seems to me I am just passing along duplicate information in the second version.
This was such a time sink I really want to avoid my mistake/misunderstanding in the future.
Thank you for reading.