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.