rust - Rust 中相同类型的相同特征的多个实现

标签 rust traits typeclass

有了 Rust traits,我可以表达一个 Monoid 类型的类(请原谅我对方法的命名):

trait Monoid {
  fn append(self, other: Self) -> Self;
  fn neutral() -> Self;
}

然后,我还可以为字符串或整数实现特征:

impl Monoid for i32 {
  fn append(self, other: i32) -> i32 {
    self + other
  }
  fn neutral() -> Self { 0 }
}

但是,我现在如何在 i32 上为乘法情况添加另一个实现?

impl Monoid for i32 {
  fn append(self, other: i32) -> i32 {
    self * other
  }
  fn neutral() { 1 }
}

我尝试了类似于 functional 中所做的事情但该解决方案似乎依赖于在特征上有一个额外的类型参数,而不是对元素使用 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))
}

关于rust - Rust 中相同类型的相同特征的多个实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65832862/

相关文章:

multidimensional-array - ndarray-尝试将impl AddAssign <ArrayBase>用于ArrayBase会导致编译器错误

scala - 在 scala 中,如何使类型类适用于 Aux 模式? - 第2部分

haskell - 类型类挑战 : having both variadic arguments and results

iterator - Rx 的 `startWith` 的 Rust 等价物是什么?

rust - 为外来类型实现外来特征

random - 如何在不引入偏差的情况下生成一个范围内的随机 Rust 整数?

模板化类型的 C++ 模板特化

Scala自类型注释与 'with'混合

rust - 从函数返回闭包

haskell - 为什么在创建类型类实例时不能下划线(忽略)类型变量?