M
Modular•12mo ago
bartimusprimed

Quick Question on Traits

Hi, Introducing myself to the language and I am wondering how I would get the functionality of being able to pass a conforming type to a function. I tried two ways, the first way is the following code. the second way is the commented code. both ways don't seem to work. EDIT: the error probably helps 😄
error: invalid call to 'hello': argument #1 cannot be converted from 'Dog' to 'Talkable'
error: invalid call to 'hello': argument #1 cannot be converted from 'Dog' to 'Talkable'
Any assistance to help me understand if greatly appreciated!
trait Talkable:
fn hello(self, thing: Talkable) -> String: ...
fn goodbye(self, thing: Talkable) -> String: ...
fn get_name(self) -> String: ...

struct Person(Talkable):
var name: String
fn __init__(inout self, name: String):
self.name = name
fn hello(self, thing: Talkable) -> String:
return self.name + " says hello to " + thing.get_name()
fn goodbye(self, thing: Talkable) -> String:
return self.name + " says goodbye to " + thing.get_name()
fn get_name(self) -> String:
return self.name

struct Dog(Talkable):
var value: __mlir_type
var name: String
var nick_name: String
var age: Int
fn __init__(inout self, name: String, nick_name: String, age: Int):
self.name = name
self.nick_name = nick_name
self.age = age

fn hello(self, thing: Talkable) -> String:
return self.name + " barks at " + thing.get_name()
fn goodbye(self, thing: Talkable) -> String:
return self.name + " barks at " + thing.get_name()

fn get_name(self) -> String:
return self.name

# I also tried this from documentation
# fn say_hello[T: Talkable](t1: T, t2: T):
# t1.hello(t2)


fn main():
var s = Person(name="Jim")
var d = Dog("spot", "dog", 2)
d.hello(s)
# say_hello(s, d)
trait Talkable:
fn hello(self, thing: Talkable) -> String: ...
fn goodbye(self, thing: Talkable) -> String: ...
fn get_name(self) -> String: ...

struct Person(Talkable):
var name: String
fn __init__(inout self, name: String):
self.name = name
fn hello(self, thing: Talkable) -> String:
return self.name + " says hello to " + thing.get_name()
fn goodbye(self, thing: Talkable) -> String:
return self.name + " says goodbye to " + thing.get_name()
fn get_name(self) -> String:
return self.name

struct Dog(Talkable):
var value: __mlir_type
var name: String
var nick_name: String
var age: Int
fn __init__(inout self, name: String, nick_name: String, age: Int):
self.name = name
self.nick_name = nick_name
self.age = age

fn hello(self, thing: Talkable) -> String:
return self.name + " barks at " + thing.get_name()
fn goodbye(self, thing: Talkable) -> String:
return self.name + " barks at " + thing.get_name()

fn get_name(self) -> String:
return self.name

# I also tried this from documentation
# fn say_hello[T: Talkable](t1: T, t2: T):
# t1.hello(t2)


fn main():
var s = Person(name="Jim")
var d = Dog("spot", "dog", 2)
d.hello(s)
# say_hello(s, d)
2 Replies
sora
sora•12mo ago
You will need to write type for functions like hello as
fn hello[T: Talkable](self, thing: T) -> String:
fn hello[T: Talkable](self, thing: T) -> String:
Slightly simplified example:
trait Talkable:
# Use type name `S` here to work around a bug
fn hello[S: Talkable](self, thing: S) -> String: ...
fn get_name(self) -> String: ...

@value
struct Person(Talkable):
var name: String

fn hello[T: Talkable](self, thing: T) -> String:
return self.name + " says hello to " + thing.get_name()
fn get_name(self) -> String:
return self.name

@value
struct Dog(Talkable):
var name: String
var age: Int

fn hello[T: Talkable](self, thing: T) -> String:
return self.name + " barks at " + thing.get_name()
fn get_name(self) -> String:
return self.name

fn main():
var s = Person("Jim")
var d = Dog("Spot", 2)
print(s.hello(d))
trait Talkable:
# Use type name `S` here to work around a bug
fn hello[S: Talkable](self, thing: S) -> String: ...
fn get_name(self) -> String: ...

@value
struct Person(Talkable):
var name: String

fn hello[T: Talkable](self, thing: T) -> String:
return self.name + " says hello to " + thing.get_name()
fn get_name(self) -> String:
return self.name

@value
struct Dog(Talkable):
var name: String
var age: Int

fn hello[T: Talkable](self, thing: T) -> String:
return self.name + " barks at " + thing.get_name()
fn get_name(self) -> String:
return self.name

fn main():
var s = Person("Jim")
var d = Dog("Spot", 2)
print(s.hello(d))
fn say_hello[T: Talkable](t1: T, t2: T):
t1.hello(t2)
fn say_hello[T: Talkable](t1: T, t2: T):
t1.hello(t2)
This doesn't work because it requires t1 and t2 to have the same type.
bartimusprimed
bartimusprimedOP•12mo ago
Thanks so much! Greatly appreciate the help

Did you find this page helpful?