首页 文章

Rust中是否有支持“map”功能(如Haskell)的集合? [重复]

提问于
浏览
1

这个问题在这里已有答案:

在函数式编程语言中,集合上最原始/最基本的操作是同态 map ;它(大致) Collection[A] -> (A->B) -> Collection[B]

Rust系列似乎不支持这一点 . 我想这是因为它们是可变的集合;如果您已经在使用可变集合,则就地更新会更有效 .

我错过了一个单独的“不可变集合”库(比如Scala)吗?

怎么样的"in-place map"操作使用 A->BCollection[A] 变成 Collection[B] (与ML和Haskell不同,它实际上可以安全地做到这一点因为仿射类型!)甚至特殊情况 A=B 和就地 Map 需要 A->A

很难用搜索引擎来回答这个问题,因为所有的命中都涉及名词"map"(如 HashMap ) .

2 回答

  • 3

    要将容器映射到容器,请迭代并 collect()

    vec.iter().map(|x| x * 2).collect::<Vec<_>>();
    

    要在适当位置更改项目,请使用for循环和 iter_mut() . 不建议在这种情况下使用迭代器链接,因为修改值会引入副作用 .

    for x in vec.iter_mut() { 
        x *= 2; 
    }
    
  • 3

    Rust有一个 map() 函数,但它不是每个单独容器的一部分,而是特征Iterator(Rust特性与Haskell的类型类非常相似):Iterator:map() . 该特征包含许多有用的方法,其中许多方法对于FP程序员来说应该是熟悉的 .

    让我们看看 map() 在行动:

    let result: Vec<_> = vec![2, 3, 5, 7]
        .into_iter()      // we have to get an iterator over the vector 
        .map(|i| i * i)   // next we map each element
        .collect();       // finally we collect all elements into a new vector
    

    map() 的类型是您所期望的:

    :: Iterator a -> (a -> b) -> Iterator b
    

    或者在Rust语法中:

    trait Iterator {
        type Item;
        fn map<B, F>(self, f: F) -> Map<Self, F> 
            where F: FnMut(Self::Item) -> B;
    }
    

    这首先看起来更复杂,但它确实有意义,将来可能会更好 . 签名是 (self, f: F) -> Map<Self, F> . 和:

    • selfIterator over Self::Item [比较: Iterator a ]

    • FFnMut(Self::Item) -> B [比较: (a -> b) ]

    • Map<Self, F>Iterator 无论 F 返回( B )[比较 Iterator b ]


    如果你想做一个就地 a -> a map(意思是:没有chaning类型),你可以获得对每个元素的可变引用并进行更改 . 例:

    let mut v = vec![2, 3, 5, 7];
    for e in &mut v {
        e *= 2;
    }
    
    let mut m = HashMap::new();
    m.insert("anna", 5);
    m.insert("peter", 3);
    for v in m.values_mut() {
        v *= 2;
    }
    

    如果没有不安全的代码,目前无法执行更改类型的就地映射 . 部分原因是Rust的类型系统无法在编译时比较两种类型的大小(但它会改变) .

相关问题