Yan*_*ann 5 traits typeclass rust
有了 Rust 特征,我可以表达一个Monoid类型类(请原谅我对方法的命名):
trait Monoid {
fn append(self, other: Self) -> Self;
fn neutral() -> Self;
}
Run Code Online (Sandbox Code Playgroud)
然后,我还可以实现字符串或整数的特征:
impl Monoid for i32 {
fn append(self, other: i32) -> i32 {
self + other
}
fn neutral() -> Self { 0 }
}
Run Code Online (Sandbox Code Playgroud)
但是,我现在如何i32为乘法案例添加另一个实现呢?
impl Monoid for i32 {
fn append(self, other: i32) -> i32 {
self * other
}
fn neutral() { 1 }
}
Run Code Online (Sandbox Code Playgroud)
我尝试了类似于功能中所做的事情,但该解决方案似乎依赖于特征上的附加类型参数,而不是用于Self元素,这给了我一个警告。
首选的解决方案是使用标记特征进行操作 - 我也尝试过但没有成功。
正如 @rodrigo 指出的,答案是使用标记结构。
以下示例显示了一个工作片段:playground
trait Op {}
struct Add;
struct Mul;
impl Op for Add {}
impl Op for Mul {}
trait Monoid<T: Op>: Copy {
fn append(self, other: Self) -> Self;
fn neutral() -> Self;
}
impl Monoid<Add> for i32 {
fn append(self, other: i32) -> i32 {
self + other
}
fn neutral() -> Self {
0
}
}
impl Monoid<Mul> for i32 {
fn append(self, other: i32) -> i32 {
self * other
}
fn neutral() -> Self {
1
}
}
pub enum List<T> {
Nil,
Cons(T, Box<List<T>>),
}
fn combine<O: Op, T: Monoid<O>>(l: &List<T>) -> T {
match l {
List::Nil => <T as Monoid<O>>::neutral(),
List::Cons(h, t) => h.append(combine(&*t)),
}
}
fn main() {
let list = List::Cons(
5,
Box::new(List::Cons(
2,
Box::new(List::Cons(
4,
Box::new(List::Cons(
5,
Box::new(List::Cons(-1, Box::new(List::Cons(8, Box::new(List::Nil))))),
)),
)),
)),
);
println!("{}", combine::<Add, _>(&list));
println!("{}", combine::<Mul, _>(&list))
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4309 次 |
| 最近记录: |