I'd like to improve my process for constructing functional programs while having conversations with my compiler. I've had the thought for awhile that while functional solutions to problems are often easier to read (once constructed), they tend to be slower for me to write, since I'm not quite functional-fluent (yet), and for that reason, tend to be ridden with type errors.
This is my current thinking process, and design approach to constructing functional programs. I'd like advice on how to think better, and that's a bit open ended. At each iteration, I'm trying to figure out what it is that the next step is going to do. I have a general idea at the beginning, and iterate, comfort the screaming type errors, and eventually arrive at a result.
In this particular case, I'm building a 2D array.
fn main() {
let now = std::time::Instant::now();
println!("result: {:?}, time: {:?}", e11(), now.elapsed());
}
// took out all but two lines here
const INPUT: &'static str = r"
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
";
// Alternative: let buffer = include_str!("../data/p011_grid.txt");
// or use BufReader
fn e11() {
INPUT
.lines()
.skip(1) // discovered: need to skip the first one, which is empty
.take(5)
.for_each(|x| println!("lines test {:?}", x));
INPUT
.lines()
.skip(1)
.map(|x| {
x.split(' ')
.map(|x| x.parse().unwrap())
// x needs a type, but the type can be pretty much whatever: try String, usize,
.take(1) // column
.for_each(|x: usize| println!("{:?} parse test", x))
}) // needs a collect or for_each goes uncalled
.collect::<()>();
INPUT
.lines()
.skip(1)
.map(|x| {
x.split(' ')
.map(|x| x.parse().unwrap())
.collect::<Vec<usize>>();
})
.take(2)
.for_each(|x| println!("vec test {:?}", x)); // Result: (); needs a collect?
let b = INPUT.lines().skip(1).map(|x| {
x.split_whitespace()
.map(|x| x.parse().unwrap())
.collect::<Vec<usize>>();
// I have a column vector now
}); // I think I need a collect here
println!("b test: {:?}", b);
let c: Vec<()> = INPUT // not Vec<usize>. Says Iterator<Item=()>. Try Vec<()>. Works. But I don't think that's what I want
.lines()
.skip(1)
.map(|x| {
x.split_whitespace()
.map(|x| x.parse().unwrap())
.collect::<Vec<usize>>();
})
.collect(); // what type is c now? xD
println!("b test: {:?}", b);
let c: Vec<Vec<usize>> = INPUT // Semicolon fix. Now I can get my 2D vector.
.lines()
.skip(1)
.map(|x| {
x.split_whitespace()
.map(|x| x.parse().unwrap())
.collect::<Vec<usize>>() // ah I think this semicolon was in the way
})
.collect();
println!("c test: {:?}", c);
}