How to implement a common linked list function in Rust?

I'm cutting my teeth with rust, and I'm trying to implement a combined list with a typical type. So far my functions consand work len, but something is wrong with mapthat I can not understand.

use std::fmt;

#[derive(Debug)]
enum List<A> {
    Empty,
    Cons(A, Box<List<A>>),
}

fn cons<A>(x: A, xs: List<A>) -> List<A> {
    return List::Cons(x, Box::new(xs));
}

fn len<A>(xs: List<A>) -> i32 {
    match xs {
        List::Empty => 0,
        List::Cons(_, xs) => 1 + len(*xs),
    }
}

fn map<A, B>(f: &Fn(A) -> B, xs: List<A>) -> List<B> {
    match xs {
        List::Empty => List::Empty,
        List::Cons(x, xs) => cons(f(x), map(f, *xs)),
    }
}

fn main() {
    let xs = cons(1, cons(2, cons(3, List::Empty)));
    println!("{:?}", xs);
    println!("{:?}", len(xs));
    let f = |x: i32| x * x;
    println!("{:?})", map(f, xs));
}

Error

error[E0308]: mismatched types
  --> src/main.rs:32:27
   |
32 |     println!("{:?})", map(f, xs));
   |                           ^ expected reference, found closure
   |
   = note: expected type `&std::ops::Fn(_) -> _`
              found type `[closure@src/main.rs:31:13: 31:27]`

Expected Result

Cons(1, Cons(2, Cons(3, Empty)))
3
Cons(1, Cons(4, Cons(9, Empty)))

My problem is related to

println!("{:?})", map(f, xs));

If I comment on this line, then the first two lines of output are correct. I'm not sure what happened to my callmap


Update

aochagavia helped me sort out the problem of setting functions and the first problem with the owner (because of many, apparently!). I'm having problems using the same method we used in lenat mapand getting a new error

My updated function maplooks like this:

fn map<A, B>(f: &Fn(A) -> B, xs: &List<A>) -> List<B> {
    match *xs {
        List::Empty => List::Empty,
        List::Cons(x, ref xs) => cons(f(x), map(f, xs)),
    }
}

Now i'm trying to do it

let f = |x: i32| x * x;
let ys = map(&f, &xs);
let zs = map(&f, &xs);
println!("{:?})", ys);
println!("{:?})", zs);

A new mistake is

error[E0009]: cannot bind by-move and by-ref in the same pattern
  --> src/main.rs:23:20
   |
23 |         List::Cons(x, ref xs) => cons(f(x), map(f, xs)),
   |                    ^  ------ both by-ref and by-move used
   |                    |
   |                    by-move pattern here
+4
1

, , : let y = map(f, xs);, ( ):

error[E0308]: mismatched types
  --> <anon>:32:15
   |
32 |   let y = map(f, xs);
   |               ^ expected reference, found closure
   |
   = note: expected type `&std::ops::Fn(_) -> _`
              found type `[closure@<anon>:31:11: 31:25]`

, ! map(&f, xs) ( ) . (. ).

len fn len<A> (xs: List<A>) -> i32. , , . , , , , ! , .

- len xs , . :

fn len<A>(xs: &List<A>) -> i32 {
    match *xs {
        List::Empty => 0,
        List::Cons(_, ref xs) => 1 + len(xs),
    }
}

, main, , len : len(&xs) ( , ).

xs,

, map xs . :

fn map<A, B>(f: &Fn(&A) -> B, xs: &List<A>) -> List<B> {
    match *xs {
        List::Empty => List::Empty,
        List::Cons(ref x, ref xs) => cons(f(x), map(f, xs)),
    }
}

, &A A (. Fn(&A) -> B). , , ( , ).

map :

let f = |x: &i32| (*x) * (*x);
map(&f, &xs);

, f , , map.

Rust. , , Fn, FnMut FnOnce.

( , ), , :

fn map<F, A, B> (f: F, xs: List<A>) -> List<B>
    where F: Fn(A) -> B
{

. , , , / .

+4
source

Source: https://habr.com/ru/post/1673582/


All Articles