M
Modular10mo ago
benny

Type independent traits

Any ways to make the example code work? Would be nice to be able to implement custom traits for abstract classes
trait Container:
fn __contains__(self, item: AnyType) -> Bool:
...


@value
struct List(Container):
var data: VariadicList[Int]

fn __contains__(self, item: Int) -> Bool:
for i in self.data:
if i == item:
return True
return False
trait Container:
fn __contains__(self, item: AnyType) -> Bool:
...


@value
struct List(Container):
var data: VariadicList[Int]

fn __contains__(self, item: Int) -> Bool:
for i in self.data:
if i == item:
return True
return False
9 Replies
benny
bennyOP10mo ago
I also tried
fn __contains__[*Ts: AnyType](self, item: Ts[0]) -> Bool:
...
fn __contains__[*Ts: AnyType](self, item: Ts[0]) -> Bool:
...
Hammad Ali
Hammad Ali10mo ago
The code throws this error:
struct 'List' does not implement all requirements for 'Container'mojo
main.mojo(2, 5): no '__contains__' candidates have type 'fn(self = List, item = AnyType) -> Bool'
main.mojo(10, 5): candidate declared here with type 'fn(self = List, item = Int) -> Bool'
main.mojo(1, 1): trait 'Container' declared here
struct 'List' does not implement all requirements for 'Container'mojo
main.mojo(2, 5): no '__contains__' candidates have type 'fn(self = List, item = AnyType) -> Bool'
main.mojo(10, 5): candidate declared here with type 'fn(self = List, item = Int) -> Bool'
main.mojo(1, 1): trait 'Container' declared here
I don't think it's possible
Nick!
Nick!10mo ago
@benny I think what you want is a generic trait, i.e. the following:
trait Container[T: AnyType]:
fn __contains__(self, item: T) -> Bool:
...
struct List(Container[Int]):
trait Container[T: AnyType]:
fn __contains__(self, item: T) -> Bool:
...
struct List(Container[Int]):
Mojo doesn't support this yet, but it's in the works.
benny
bennyOP10mo ago
sort of, but i was thinking generic on a function level, where each function can type in different parameters, rather than generic on a struct level
Nick!
Nick!10mo ago
I’m not sure what distinction you’re making. Your struct can inherit from that trait multiple times with a different parameter, if you want to have multiple __contains__ functions. There’s also a notion of “associated types” (see Rust and Swift) which avoids the need for the trait to be parametrised.
sora
sora10mo ago
Sometimes you need both to make a nice api, and good example would be some HasAdd trait, where LHS is generic, and Output is an associated type. IMO, this is why inherit is bad terminology for traits. Could you show some code as your intended usage pattern?
benny
bennyOP10mo ago
trait Container:
fn __contains__(self, item: AnyType) -> Bool:
...


@value
struct StaticIntList(Container):
var data: VariadicList[Int]

fn __contains__(self, item: Int) -> Bool:
for i in self.data:
if i == item:
return True
return False

@value
struct StaticStringHashTable(Container):
var data: VariadicList[Int]
… other attributes and methods for dict

fn __contains__(self, item: String) -> Bool:
for i in self.data:
if i == item:
return True
return False
trait Container:
fn __contains__(self, item: AnyType) -> Bool:
...


@value
struct StaticIntList(Container):
var data: VariadicList[Int]

fn __contains__(self, item: Int) -> Bool:
for i in self.data:
if i == item:
return True
return False

@value
struct StaticStringHashTable(Container):
var data: VariadicList[Int]
… other attributes and methods for dict

fn __contains__(self, item: String) -> Bool:
for i in self.data:
if i == item:
return True
return False
sora
sora10mo ago
Ah, then you most definitely want associated type, and kinda have to wait.
a2svior
a2svior10mo ago
This worked in the previous Mojo version with parameter input, but stopped working in the new version, so I had to remove it for Lightbug 🥲
Want results from more Discord servers?
Add your server