Here's my broken code (will leave it to you to guess what I'm implementing!):
pub struct BlockChain<M, T>
where
M: MerkleTree,
H: <M::Hasher as MerkleHasher>::Element,
T: TransactionList<Element=H>,
for<'a> &'a M: IntoIterator, .....}
The line H: <M::Hasher as MerkleHasher>::Element,
is failing at the <
with "expected identifier, fournd <
.
All I want is to be able to use H
as an alias to <M::Hasher as MerkleHasher>::Element
throughout the struct (as shown on the T:
line). It's not intended to add any compile-time specifity to the struct.
This code compiles and seems to work, but I feel like I shouldn't need four generic types on the BlockChain
struct when three of them are related to each other by associated traits:
pub struct BlockChain<H, HR, M, T>
where
H: HashableElement,
HR: MerkleHasher<Element = H>,
M: MerkleTree<Hasher = HR>,
T: TransactionList<Element = H>,
for<'a> &'a M: IntoIterator, // TODO: MerkleTree should iterate over clones instead of references, I imagine very few uses of the iterator would not clone them anyway.
Here's another implementation that works, and only has the two generic types I actually need (M and T):
where
M: MerkleTree,
T: TransactionList<Element = <M::Hasher as MerkleHasher>::Element>,
for<'a> &'a M: IntoIterator, // TODO: MerkleTree should iterate over clones instead of references, I imagine very few uses of the iterator would not clone them anyway.
However, this leads to unwieldy syntax including the T
line above, and this behemoth inside the struct:
snapshot_root_hash: <<M::Hasher as MerkleHasher>::Element as HashableElement>::Hash,
If it's not clear, the "tree of traits" in this case is:
MerkleHash: Clone + PartialEq;
HashableElement has type Hash: MerkleHash;
MerkleHasher: has type Element: HashableElement;
MerkleTree: has type Hasher: MerkleHasher;
Hoping this is a simple question of syntax!