rust says trait From<i32> isn't implimented - rust

I've got an enum:
#[derive(PartialEq, Debug)]
pub enum EventValue {
Numeric(i32),
Bool(bool),
Text(String),
}
And it's used in a Vec which is used in a HashMap:
type Events = Vec<Event>;
pub type Stream = HashMap<String, Events>;
and I've implemented the From trait on it for i32 (and the other three types):
impl From<i32> for EventValue {
fn from(v: i32) -> Self {
EventValue::Numeric(v)
}
}
impl From<String> for EventValue {
fn from(v: String) -> Self {
EventValue::Text(v)
}
}
impl From<bool> for EventValue {
fn from(v: bool) -> Self {
EventValue::Bool(v)
}
}
but when I try to use it in a function:
let motions = event_stream.get_channel("motions"); // << return a Vec
for motion in motions.drain(0..) {
let amount: i32 = motion.value.into(); // <-- here is where I get the error
// .. do somthing with amount
}
I get this error:
the trait bound `i32: std::convert::From<prelude::game::entity::components::event_stream::EventValue>` is not satisfied
--> src/game/system/entity/movement.rs:17:48
|
17 | let amount: i32 = motion.value.into();
| ^^^^ the trait `std::convert::From<prelude::game::entity::components::event_stream::EventValue>` is not implemented for `i32`
|
= help: the following implementations were found:
<i32 as std::convert::From<bool>>
<i32 as std::convert::From<i16>>
<i32 as std::convert::From<i8>>
<i32 as std::convert::From<std::num::NonZeroI32>>
and 2 others
= note: required because of the requirements on the impl of `std::convert::Into<i32>` for `prelude::game::entity::components::event_stream::EventValue`
What have I missed?
Bonus:
It's possible to build a function that auto converts incoming values for you provided you implement From like this:
impl Event {
pub fn new<V: Into<EventValue>>(message: String, value: V) -> Event {
Self {
message: message,
value: value.into(),
}
}
}
Is it possible to create a function that can do the same thing but for returning a value?

The error says that From<EventValue> isn't implemented for i32, not that From<i32> isn't implemented for EventValue. With the fully qualified names, it's a little harder to read, but that's what
the trait bound i32: std::convert::From<prelude::game::entity::components::event_stream::EventValue> is not satisfied
is saying.
The problem is that you're going the wrong direction. You've implemented the conversion i32 -> EventValue, but not EventValue -> i32, which is what your sample code is trying to do.
You'll probably want to match on the value instead and handle not only the Numeric case, but also the Bool and Text cases.
let motions = event_stream.get_channel("motions"); // << return a Vec
for motion in motions.drain(0..) {
match motion.value {
Numeric(value) => {// handle `Numeric` case},
Bool(value) => {// handle `Bool` case},
Text(text) => {// handle `Text` case},
}
}
motion.value could be any of those three variants, so you can't assume it'll always be convertible to i32.

Related

Assigning proper lifetimes to associated types

I am designing code that should be generic over a trait Atom, that contains many associated types that logically belong together. In the simplified example below, which concerns representing a mathematical expression, there is one variant that gives a 'view' of a Pow and an owned version of a Pow. In actuality, there will be many more variants, such as Var and OwnedVar, Function and OwnedFunction, etc.
Since some traits deal with borrowed data, I added lifetimes and this makes the code below not compile:
pub trait Atom {
// imagine more variants here
type P<'a>: Pow<'a, R = Self>;
type OP: OwnedPow<R = Self>;
}
pub trait Pow<'a> {
type R: Atom;
fn get_base(&self) -> AtomView<Self::R>;
}
pub trait OwnedPow {
type R: Atom;
fn to_view<'a>(&'a self) -> AtomView<Self::R>;
}
pub enum AtomView<'a, R: Atom> {
Pow(R::P<'a>),
}
impl<'a, R: Atom> AtomView<'a, R> {
#[allow(unconditional_recursion, irrefutable_let_patterns)]
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if let AtomView::Pow(p2) = other {
let b = p2.get_base();
Some(self.partial_cmp(&b).unwrap())
} else {
None
}
}
}
// concrete implementations
struct Rep;
impl Atom for Rep {
type P<'a> = PowD<'a>;
type OP = OwnedPowD;
}
struct PowD<'a> {
data: &'a [u8],
}
impl<'a> Pow<'a> for PowD<'a> {
type R = Rep;
fn get_base(&self) -> AtomView<Self::R> {
AtomView::Pow(PowD {
data: &self.data[1..],
})
}
}
struct OwnedPowD {
data: Vec<u8>,
}
impl OwnedPow for OwnedPowD {
type R = Rep;
fn to_view<'a>(&'a self) -> AtomView<Rep> {
AtomView::Pow(PowD { data: &self.data })
}
}
fn test<A: OwnedPow>(a: A) {
let _vv = a.to_view();
}
fn main() {
let v = OwnedPowD {
data: vec![1, 2, 3],
};
test(v);
}
This code does not compile:
error[E0621]: explicit lifetime required in the type of `other`
--> src/main.rs:25:21
|
23 | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
| ----- help: add explicit lifetime `'a` to the type of `other`: `&'a AtomView<'a, R>`
24 | if let AtomView::Pow(p2) = other {
25 | let b = p2.get_base();
| ^^^^^^^^^^^^^ lifetime `'a` required
Of course, giving other the lifetime a is a problem, since other is a locally created variable and thus following the help will not fix the problem. I fail to see why &b seems to have the lifetime &'a b.
The code can be tested on the playground.
I tried fixing this code by dropping many lifetimes in the associated types and traits, but then it seems I need to give Rep a lifetime, and then this Rep<'a> will make its way into OwnedPowD that should have no lifetime (since the data is owned). This attempt can be tried here.
Does anyone know how to assign proper lifetimes?
AtomView has a lifetime argument, which should connect all of the borrowing dependencies together. But you are never specifying it!
pub enum AtomView<'a, R: Atom> {
Pow(R::P<'a>),
}
I was able to make your code compile by changing the trait methods to constrain this lifetime in the "obvious" way in each case:
pub trait Pow<'a> {
type R: Atom;
fn get_base(&self) -> AtomView<'a, Self::R>;
}
pub trait OwnedPow {
type R: Atom;
fn to_view(&self) -> AtomView<'_, Self::R>;
}
And updating the implementations to match:
impl<'a> Pow<'a> for PowD<'a> {
type R = Rep;
fn get_base(&self) -> AtomView<'a, Self::R> {
// just for testing
AtomView::Pow(PowD {
data: &self.data[1..],
})
}
}
impl OwnedPow for OwnedPowD {
type R = Rep;
fn to_view(&self) -> AtomView<'_, Rep> {
AtomView::Pow(PowD { data: &self.data })
}
}

Generic struct's `new()` function does not accept non generic assignments to generic structs field

I ran into a problem the other day when I started learning how generics worked on rust. The issue I encountered is in the following snippet:
struct Example<T> {
a: T
}
impl<T> Example<T> {
fn new() -> Self {
Self {
a: 5
}
}
}
Trying to compile this gives the following output:
error[E0308]: mismatched types
--> src/lib.rs:11:16
|
8 | impl<T> Example<T> {
| - this type parameter
...
11 | a: 5
| ^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
For more information about this error, try `rustc --explain E0308`.
warning: `url_shortener` (lib) generated 2 warnings
error: could not compile `url_shortener` due to previous error; 2 warnings emitted
An easy fix would be specifying the type that we want, like so:
impl Example<i32> {
fn new() -> Self {
Self {
a: 5
}
}
}
But I don't really understand why keeping the type parameter general does not work. Also I have an example where changing the type parameter would not be so easy. Say we want to do something like the following:
use itertools::Itertools;
struct Example<T: Iterator<Item=String>> {
a: T
}
fn get_permutations(n: i32) -> impl Iterator<Item=String> {
(0..n)
.map(|_| (97u8..=122u8).map(|x| x as char))
.multi_cartesian_product().map(|v| v.iter().join(""))
}
impl<T: Iterator<Item=String>> Example<T> {
fn new() -> Self {
let test = get_permutations(4)
.chain(
get_permutations(3)
)
.chain(
get_permutations(2)
)
.chain(
get_permutations(1)
);
Self {
a: test
}
}
}
The type of test is Chain<Chain<Chain<impl Iterator<Item = String>, impl Iterator<Item = String>>, impl Iterator<Item = String>>, impl Iterator<Item = String>>, and we can't simply change the generic type parameter T to that, since the impl Trait syntax is not allowed for type parameters.
We could try changing the return type of the get_permutations function so that it does not return impl Trait, but the actual type returned by get_permutations includes closures and I don't know how to write it out (or if it even is possible considering each closure is its own type(?)). Besides we might want to chain together more functions in it at a later date, and it would be bad to change its type every time we wanted to do that.
So it seems it would be better to have get_permutations return type to be some generic Iterator, the only solution that I can think of is using Boxes like so:
use itertools::Itertools;
struct Example {
a: Box<dyn Iterator<Item = String>>
}
fn get_permutations(n: i32) -> Box<dyn Iterator<Item = String>> {
(0..n)
.map(|_| (97u8..=122u8).map(|x| x as char))
.multi_cartesian_product().map(|v| v.iter().join(""))
}
impl Example {
fn new() -> Self {
let test = Box::new(get_permutations(4)
.chain(
get_permutations(3)
)
.chain(
get_permutations(2)
)
.chain(
get_permutations(1)
));
Self {
a: test
}
}
}
But I find this kind of ugly. I can also create the object without using new():
use itertools::Itertools;
struct Example<T: Iterator<Item=String>> {
a: T
}
fn get_permutations(n: i32) -> impl Iterator<Item=String> {
(0..n)
.map(|_| (97u8..=122u8).map(|x| x as char))
.multi_cartesian_product().map(|v| v.iter().join(""))
}
fn main(){
let test = Example{a: get_permutations(4)
.chain(
get_permutations(3)
)
.chain(
get_permutations(2)
)
.chain(
get_permutations(1)
)};
for perm in test.a {
println!("{perm}")
}
}
But this wouldn't make much sense if it is the case that every Example object should contain this exact iterator. So, is there a better way of doing this without using Boxes?
Your simple example doesn't work since generics are specified by the user, i.e. Example::<String>::new() wouldn't make sense with your implementation, since it would try assigning 5 to a String.
For your actual use-case, you want to be able to store a type that you don't want to name, and want to avoid trait objects. As of right now, this isn't possible AFAIK. There is an unstable feature, #![feature(type_alias_impl_trait)], which would be ideal and would look like this:
#![feature(type_alias_impl_trait)] // <------------
use itertools::Itertools;
type Permutations = impl Iterator<Item = String>; // <------------
struct Example {
a: Permutations,
}
fn get_permutations(n: i32) -> impl Iterator<Item = String> {
(0..n)
.map(|_| (97u8..=122u8).map(|x| x as char))
.multi_cartesian_product()
.map(|v| v.iter().join(""))
}
impl Example {
fn new() -> Self {
let test = get_permutations(4)
.chain(get_permutations(3))
.chain(get_permutations(2))
.chain(get_permutations(1));
Self { a: test }
}
}
Your stable options are to either use a trait object, Box<dyn Iterator<Item = String>>, as you've already found or you can keep a generic argument and have a function return a concrete but opaque type via Example<impl Iterator<Item = String>>:
use itertools::Itertools;
struct Example<T: Iterator<Item = String>> {
a: T,
}
fn get_permutations(n: i32) -> impl Iterator<Item = String> {
(0..n)
.map(|_| (97u8..=122u8).map(|x| x as char))
.multi_cartesian_product()
.map(|v| v.iter().join(""))
}
impl<T: Iterator<Item = String>> Example<T> {
fn new() -> Example<impl Iterator<Item = String>> { // <------------
let test = get_permutations(4)
.chain(get_permutations(3))
.chain(get_permutations(2))
.chain(get_permutations(1));
Example { a: test }
}
}
Both have their drawbacks since the former would require an allocation and dynamic dispatch, but the latter method is still an unnameable type (you can't store Example<impl ...> in a struct) and can still be overridden by users.

Can I store an `impl Future` as a concrete type?

tokio::net::TcpStream::connect is an async function, meaning it returns an existential type, impl Future. I would like to store a Vec of these futures in a struct. I've found many questions where someone wants to store multiple different impl Futures in a list, but I only want to store the return type of one. I feel like this should be possible without Box<dyn Future> as I am really only storing a single concrete type, but I cannot figure out how without getting found opaque type errors.
It is possible with the nightly feature min_type_alias_impl_trait. The trick is to create a type alias, and a dummy function from which the compiler can infer a defining use.
#![feature(min_type_alias_impl_trait)]
use tokio::net::TcpStream;
use core::future::Future;
type TcpStreamConnectFut = impl Future<Output = std::io::Result<TcpStream>>;
fn __tcp_stream_connect_defining_use() -> TcpStreamConnectFut {
TcpStream::connect("127.0.0.1:8080")
}
struct Foo {
connection_futs: Vec<TcpStreamConnectFut>,
}
This compiles, but does not work as expected:
impl Foo {
fn push(&mut self) {
self.connection_futs.push(TcpStream::connect("127.0.0.1:8080"));
}
}
error[E0308]: mismatched types
--> src/lib.rs:18:35
|
6 | type TcpStreamConnectFut = impl Future<Output = std::io::Result<TcpStream>>;
| ------------------------------------------------ the expected opaque type
...
18 | self.connection_futs.push(TcpStream::connect("127.0.0.1:8080"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found a different opaque type
|
= note: while checking the return type of the `async fn`
= note: expected opaque type `impl Future` (opaque type at <src/lib.rs:6:28>)
found opaque type `impl Future` (opaque type at </playground/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.7.1/src/net/tcp/stream.rs:111:56>)
= help: consider `await`ing on both `Future`s
= note: distinct uses of `impl Trait` result in different opaque types
Using the dummy function we created does work:
impl Foo {
fn push(&mut self) {
self.connection_futs.push(__tcp_stream_connect_defining_use());
}
}
So we can just create wrapper functions:
fn tcp_stream_connect<A: ToSocketAddrs>(addr: A) -> TcpStreamConnectFut {
TcpStream::connect(addr)
}
Except...
error: type parameter `A` is part of concrete type but not used in parameter list for the `impl Trait` type alias
--> src/main.rs:9:74
|
9 | fn tcp_stream_connect<A: ToSocketAddrs>(addr: A) -> TcpStreamConnectFut {
| __________________________________________________________________________^
10 | | TcpStream::connect(addr)
11 | | }
| |_^
We could just use String or &'static str, and the entire thing compiles:
type TcpStreamConnectFut = impl Future<Output = std::io::Result<TcpStream>>;
fn tcp_stream_connect(addr: &'static str) -> TcpStreamConnectFut {
TcpStream::connect(addr)
}
struct Foo {
connection_futs: Vec<TcpStreamConnectFut>,
}
impl Foo {
fn push(&mut self) {
self.connection_futs.push(tcp_stream_connect("..."));
}
}
You can also add a generic parameter to the type alias itself, but that probably doesn't make sense in this case:
type TcpStreamConnectFut<A> = impl Future<Output = std::io::Result<TcpStream>>;
fn tcp_stream_connect<A: ToSocketAddrs>(addr: A) -> TcpStreamConnectFut<A> {
TcpStream::connect(addr)
}
struct Foo {
connection_futs: Vec<TcpStreamConnectFut<&'static str>>,
}
impl Foo {
fn push(&mut self) {
self.connection_futs.push(tcp_stream_connect("..."));
}
}
So it is possible, but there are a couple of restrictions. I'm not sure how many of these are bugs, and how much of it is intentional behavior. There has been discussion about a typeof operator to make this easier, but this is what we've got at the moment.
You can just use a good old Vec, just like that:
use core::future::Future;
use tokio::net::TcpStream;
fn just_vec() -> Vec<impl Future<Output = std::io::Result<TcpStream>>> {
let mut v = Vec::new();
// connect to several streams
v.push(TcpStream::connect("127.0.0.1:8080"));
v.push(TcpStream::connect("127.0.0.2:8080"));
v
}
However, it gets more tricky if you want to store it in a struct, because unlike above, where concrete type can be inferred, you need to be more explicit with structs.
One stable way to do this, is to use a generic struct. This actually very similar to storing a closure (where you don't have a concrete type either).
use core::future::Future;
use tokio::net::TcpStream;
use tokio::io::AsyncWriteExt;
struct Foo<T> {
connections: Vec<T>,
}
/// This is just like any other vec-wrapper
impl<T> Foo<T> {
pub fn new() -> Self {
Self {
connections: Vec::new(),
}
}
pub fn push(&mut self, conn: T) {
self.connections.push(conn);
}
}
/// Some more specific functios that actually need the Future
impl<T> Foo<T> where T: Future<Output = std::io::Result<TcpStream>> {
pub async fn broadcast(self, data: &[u8]) -> std::io::Result<()> {
for stream in self.connections {
stream.await?.write_all(data).await?
}
Ok(())
}
}
async fn with_struct() -> std::io::Result<()> {
let mut foo = Foo::new();
// connect to several streams
foo.push(TcpStream::connect("127.0.0.1:8080"));
foo.push(TcpStream::connect("127.0.0.2:8080"));
// Do something with the connections
foo.broadcast(&[1,2,3]).await
}

Passing in method reference to a struct

I have a struct other_struct that has a bunch of methods that I need to call depending on certain situations (in this example there is only foo(). I'd like to have a field in other_struct called fmap that stores a HashMap of other_struct methods.
use std::collections::HashMap;
pub struct fn_struct {
pub func: Option<fn(&other_struct) -> ()>,
}
pub struct other_struct<'a> {
fmap: HashMap<String, fn_struct>,
some_str: &'a str,
}
impl<'a> other_struct<'a> {
fn new(some_str: &str) -> other_struct {
let mut new_struct = other_struct {
fmap: HashMap::new(),
some_str: some_str,
};
new_struct.fmap.insert(
String::from("foo"),
fn_struct {
func: Some(other_struct::foo),
},
);
new_struct
}
pub fn foo(&self) {
println!("Do some stuff foo");
}
}
fn main() {
let test_str = "test";
let mut new_o = other_struct::new(test_str);
new_o.fmap.get("foo").unwrap().func.unwrap()(&new_o);
}
I'm struggling with dealing with the lifetimes, as I get the following error:
error[E0308]: mismatched types
--> src/main.rs:22:28
|
22 | func: Some(other_struct::foo),
| ^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected fn pointer `for<'r, 's> fn(&'r other_struct<'s>)`
found fn pointer `for<'r> fn(&'r other_struct<'_>)`
I've been reading the high ranked trait bound documentation but it's unclear to me what's happening here. Does this mean the compiler wants me to specify the lifetime of the instance of other_struct somehow in relation to the lifetime of the pointer to the method?
The fn(&other_struct) -> () part of fn_struct is a function pointer that must be able to accept other_structs of any lifetime for<'r, 's> fn(&'r other_struct<'s>) -> (). However, other_struct::foo only accepts a specific lifetime for other_struct<'_>.
You can fix it by specifying that lifetime in some manner, here basically saying its always going to pass in itself:
pub struct fn_struct<'a> {
pub func: Option<fn(&other_struct<'a>) -> ()>,
}
pub struct other_struct<'a> {
fmap: HashMap<String, fn_struct<'a>>,
some_str: &'a str,
}
Or by making foo more generic by unbinding it from 'a.
pub fn foo(_self: &other_struct) {
println!("Do some stuff foo");
}
The difference is subtle, but the original is other_struct<'a>::foo<'b>(&'b other_struct<'a>) -> () and the fixed version is other_struct<'a>::foo<'b, 'c>(&'b other_struct<'c>) -> ().

Does type constructor implement Fn?

I am not sure that the title of my question is correct since I am not sure where exactly placed.
Let say I have a code which looks like:
struct MyWrapper(u64);
fn my_func<F>(f: F, n: u64) -> MyWrapper
where
F: Fn(u64) -> MyWrapper,
{
f(n)
}
fn main() {
my_func(MyWrapper, 3);
}
It compiles and works so it looks like MyWrapper implements trait Fn.
However, should I try to use it in a trait.
struct MyWrapper(u64);
trait MyTrait
where
Self: Fn(u64) -> MyWrapper,
{
}
impl MyTrait for MyWrapper{}
I get an error
16 | impl MyTrait for MyWrapper{};
| ^^^^^^^ expected an `Fn<(u64,)>` closure, found `MyWrapper`
|
= help: the trait `std::ops::Fn<(u64,)>` is not implemented for `MyWrapper`
It was a more theoretical question.
Speaking practicaly, what I am trying to achieve is to implement trait like this
Edit:
I have rightfully pointed out that my example is not full, so there is a fixed version.
pub enum Status {
New,
Cancelled,
}
struct NewTransaction(u64);
struct CancelledTransaction(u64);
fn get_by_status(id: &str, status: Status) -> Result<u64, ()> {
Ok(3)
}
pub trait Transaction
where
Self: std::marker::Sized,
{
const status: Status;
fn get(id: &str) -> Result<Self, ()>;
}
impl Transaction for NewTransaction {
const status: Status = Status::New;
fn get(id: &str) -> Result<Self, ()> {
get_by_status(id, Self::status).map(Self)
}
}
impl Transaction for CancelledTransaction {
const status: Status = Status::Cancelled;
fn get(id: &str) -> Result<Self, ()> {
get_by_status(id, Self::status).map(Self)
}
}
This code compiles, but as you can see - all implementations of Transaction for every type are exactly the same, so it seems totally reasonable to move this implementation as a default. Like this
pub trait Transaction
where
Self: std::marker::Sized,
{
const status: Status;
fn get(id: &str) -> Result<Self, ()> {
get_by_status(id, Self::status).map(Self)
}
}
impl Transaction for NewTransaction {
const status: Status = Status::New;
}
impl Transaction for CancelledTransaction {
const status: Status = Status::Cancelled;
}
And here I got a complain that Self cannot be used as a Value.
I've tried to fix it by introducing a condition where Self: Fn(u32) -> Self on trait but it didn't work either.
Edit:
In the end, I implemented the idea suggested by Sven Marnach - added a method new and required all struct to implement this method. It still looks quite strange, since the implementation is exactly the same for all structures, but it works.
pub trait Transaction
where
Self: std::marker::Sized,
{
const status: Status;
fn new(n: u64) -> Self;
fn get(id: &str) -> Result<Self, ()> {
get_by_status(id, Self::status).map(Self::new)
}
}
impl Transaction for NewTransaction {
const status: Status = Status::New;
fn new(n: u64) -> Self {
Self(n)
}
}
Thanks everyone for answers!
The constructor of a tuple-like struct or enum variant is actually treated as a function name when used in a context where a value rather than a type is expected, and it is treated as the type it names in a context where a type is expected.
When calling my_func(MyWrapper, 3), the name MyWrapper denotes a function with a function item type that coerces to the function pointer type fn(u64) -> MyWrapper. In particular, the item type implements the trait Fn(u64) -> MyWrapper.
In the code impl MyTrait for MyWrapper {}, however, MyWrapper denotes the struct type it declares. That type is completely different from the type of MyWrapper when used in a value context, and it does not implement the Fn(u64) -> MyWrapper trait.
In your actual use case, I believe the easiest solution is to require a new() method with the desired prototype on the type:
trait Payment {
const status: Status;
fn new(x: u64) -> Self;
fn get(id: u64) -> Result<Self, Error> {
get_by_status(Self::status, id).map(Self::new)
}
}
Implementors of Payment will only need to provide new() method with the desired prototype, but will inherit the default implementation of get().
It compiles and works so it looks like MyWrapper implements trait Fn.
A quick and dirty way to know the type of something in Rust is to do:
struct MyWrapper(u64);
fn main() {
let mut foo = MyWrapper;
foo = ();
}
This produces an error:
error[E0308]: mismatched types
--> src/main.rs:5:11
|
5 | foo = ();
| ^^ expected fn item, found ()
|
= note: expected type `fn(u64) -> MyWrapper {MyWrapper}`
found type `()`
As you can see foo is not a MyWrapper structure so MyWrapper does not implement Fn like you thought it would.
I agree this can be confusing, see tuple struct case:
A struct expression with fields enclosed in parentheses constructs a tuple struct. Though it is listed here as a specific expression for completeness, it is equivalent to a call expression to the tuple struct's constructor. For example:
struct Position(i32, i32, i32);
Position(0, 0, 0); // Typical way of creating a tuple struct.
let c = Position; // `c` is a function that takes 3 arguments.
let pos = c(8, 6, 7); // Creates a `Position` value.
Speaking practically, what I am trying to achieve is to implement trait like this
Your example is not complete so my answer is not final but I don't think it's possible to do what you want.

Resources