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;
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