M
Modular2mo ago
Josiah

Difficult Trait Conformance

I have been using mojo nightly mojo 2024.8.305 (f99b2e40). I need someone's help on why this doesn't work:
trait IterDataPipable:
fn __next__[T: CollectionElement](ref[_] self) -> Optional[T]: pass

@value
struct ListDatapipe[T: CollectionElement](IterDataPipable[T]):
var src: List[T]
var index: Int

fn __init__(inout self, src: List[T]):
self.src = src
self.index = 0

fn __init__(inout self, src: List[T], index: Int):
self.src = src
self.index = index

fn __iter__(self) -> Self: return self

fn __next__(ref[_] self) -> Optional[T]:
self.index += 1
if self.index == len(self.src) + 1:
return Optional[T](None)

return Optional[T](self.src[self.index - 1])

fn __len__(self) -> Int: return len(self.src) - self.index
trait IterDataPipable:
fn __next__[T: CollectionElement](ref[_] self) -> Optional[T]: pass

@value
struct ListDatapipe[T: CollectionElement](IterDataPipable[T]):
var src: List[T]
var index: Int

fn __init__(inout self, src: List[T]):
self.src = src
self.index = 0

fn __init__(inout self, src: List[T], index: Int):
self.src = src
self.index = index

fn __iter__(self) -> Self: return self

fn __next__(ref[_] self) -> Optional[T]:
self.index += 1
if self.index == len(self.src) + 1:
return Optional[T](None)

return Optional[T](self.src[self.index - 1])

fn __len__(self) -> Int: return len(self.src) - self.index
When running:
var numbers = List(1,2,3,4,5)
var pipe = ListDatapipe(numbers)
# var pipe2 = AnotherPipe(pipe)
# additional pipes
var n = pipe.__next__()
var numbers = List(1,2,3,4,5)
var pipe = ListDatapipe(numbers)
# var pipe2 = AnotherPipe(pipe)
# additional pipes
var n = pipe.__next__()
It keeps saying ListDatapipe doesnt conform to IterDataPipable. I've tried a bunch of different ways of trying to make this work, but none of them work well. I'm trying to get a generic IterDataPipable working so I can chain. Tried getting help from https://discordapp.com/channels/1087530497313357884/1269718914208759870 kapa. I'm convinced its an issue with https://github.com/modularml/mojo/issues/3215
3 Replies
Drakontas
Drakontas2mo ago
Might not be implementable except by moving [T: CollectionElement] parameter from ListDatapipe to every function of ListDatapipe, but you still run into the issue with var src: List[T] definitely something that needs parameterizable traits to make this easy My mojo -v is 24.4, so ref[_] doesn't parse for me yet, feel free to add it back in:
trait IterDataPipable:
fn __next__[T: CollectionElement](inout self) -> Optional[T]: pass

@value
struct ListDatapipe[T: CollectionElement](IterDataPipable):
var src: List[T]
var index: Int

fn __init__(inout self, src: List[T]):
self.src = src
self.index = 0

fn __init__(inout self, src: List[T], index: Int):
self.src = src
self.index = index

fn __iter__(self) -> Self: return self

fn __next__[T: CollectionElement](inout self) -> Optional[T]:
self.index += 1
if self.index == len(self.src) + 1:
return Optional[T](None)

return Optional[T](self.src[self.index - 1])

fn __len__(self) -> Int: return len(self.src) - self.index
trait IterDataPipable:
fn __next__[T: CollectionElement](inout self) -> Optional[T]: pass

@value
struct ListDatapipe[T: CollectionElement](IterDataPipable):
var src: List[T]
var index: Int

fn __init__(inout self, src: List[T]):
self.src = src
self.index = 0

fn __init__(inout self, src: List[T], index: Int):
self.src = src
self.index = index

fn __iter__(self) -> Self: return self

fn __next__[T: CollectionElement](inout self) -> Optional[T]:
self.index += 1
if self.index == len(self.src) + 1:
return Optional[T](None)

return Optional[T](self.src[self.index - 1])

fn __len__(self) -> Int: return len(self.src) - self.index
I made __next__ in the trait take an inout self, copied the parameters onto __next__ impl, and then made that one inout self as well since it mutates self.index and then also removed the [T] from the required traits
Josiah
Josiah2mo ago
I still get:
error: no matching function in initialization
return Optional[T](self.src[self.index - 1])
~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
note: candidate not viable: expected at most 1 positional argument, got 2
from fastrl_mojo.data.datapipes.base import ListDatapipe
^note: candidate not viable: argument #1 cannot be converted from 'T' to 'T'
from fastrl_mojo.data.datapipes.base import ListDatapipe
error: no matching function in initialization
return Optional[T](self.src[self.index - 1])
~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
note: candidate not viable: expected at most 1 positional argument, got 2
from fastrl_mojo.data.datapipes.base import ListDatapipe
^note: candidate not viable: argument #1 cannot be converted from 'T' to 'T'
from fastrl_mojo.data.datapipes.base import ListDatapipe
Yeah sounds like parameterizable traits will be needed to make this actually work, but I appreciate the response!
Drakontas
Drakontas2mo ago
oh i see, because the T in __next__ may not necessarily be the same T as the one from ListDatapipe yeah, this 100% needs parameterized traits, no way around it
Want results from more Discord servers?
Add your server