diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index b7363a7..36bdf21 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -129,7 +129,7 @@ jobs:
},
{
"name": "Run Clippy",
- "run": "nix develop --command cargo -- clippy -- -D warnings"
+ "run": "nix develop --command cargo -- clippy -- -D warnings -W clippy::must_use_candidate"
}
]
}
diff --git a/little_learner/src/auto_diff.rs b/little_learner/src/auto_diff.rs
index 8debc49..eede557 100644
--- a/little_learner/src/auto_diff.rs
+++ b/little_learner/src/auto_diff.rs
@@ -250,12 +250,12 @@ impl DifferentiableContents {
}
(
DifferentiableContents::Vector(v1, rank1),
- DifferentiableContents::Vector(v2, _rank2),
+ DifferentiableContents::Vector(v2, rank2),
) => {
assert_eq!(
v1.len(),
v2.len(),
- "Must map two vectors of the same length, got {rank1} and {_rank2}"
+ "Must map two vectors of the same length, got {rank1} and {rank2}"
);
assert_ne!(
v1.len(),
diff --git a/little_learner/src/block.rs b/little_learner/src/block.rs
index 576fccd..f0bea64 100644
--- a/little_learner/src/block.rs
+++ b/little_learner/src/block.rs
@@ -1,4 +1,4 @@
-use crate::auto_diff::{Differentiable, RankedDifferentiableTagged};
+use crate::auto_diff::{Differentiable, RankedDifferentiable, RankedDifferentiableTagged};
use crate::ext::relu;
use crate::traits::NumLike;
@@ -7,30 +7,39 @@ pub struct Block {
ranks: [usize; N],
}
-pub fn compose<'a, A, T, B, C, F, G, const N: usize, const M: usize>(
+/// Does the second argument first, so compose(b1, b2) performs b2 on its input, and then b1.
+pub fn compose<'a, 'c, 'd, A, T, B, C, F, G, const N: usize, const M: usize>(
b1: Block,
b2: Block,
j: usize,
-) -> Block C, { N + M }>
+) -> Block C, { N + M }>
where
- F: FnOnce(A, &'a [T]) -> B,
- G: FnOnce(B, &'a [T]) -> C,
- T: 'a,
+ F: FnOnce(&'a A, &'d [T]) -> B,
+ G: for<'b> FnOnce(&'b B, &'d [T]) -> C,
+ A: 'a,
+ T: 'd,
{
let mut ranks = [0usize; N + M];
- ranks.copy_from_slice(&b1.ranks[..N]);
- ranks[N..(M + N)].copy_from_slice(&b2.ranks[..M]);
+ ranks[..N].copy_from_slice(&b1.ranks);
+ ranks[N..(M + N)].copy_from_slice(&b2.ranks);
Block {
- f: move |t, theta| (b2.f)((b1.f)(t, theta), &theta[j..]),
+ f: move |t, theta| {
+ let intermediate = (b1.f)(t, theta);
+ (b2.f)(&intermediate, &theta[j..])
+ },
ranks,
}
}
-pub fn dense<'a, 'b, A, Tag>(
+#[must_use]
+pub fn dense<'b, A, Tag>(
input_len: usize,
neuron_count: usize,
) -> Block<
- impl FnOnce(&'a RankedDifferentiableTagged, &'b [Differentiable]) -> Differentiable,
+ impl for<'a> FnOnce(
+ &'a RankedDifferentiableTagged,
+ &'b [Differentiable],
+ ) -> RankedDifferentiable,
2,
>
where
@@ -38,12 +47,16 @@ where
A: NumLike + PartialOrd + Default,
{
Block {
- f: |t, theta: &'b [Differentiable]| -> Differentiable {
+ f: for<'a> |t: &'a RankedDifferentiableTagged,
+ theta: &'b [Differentiable]|
+ -> RankedDifferentiable {
relu(
t,
&(theta[0].clone().attach_rank().unwrap()),
&(theta[1].clone().attach_rank().unwrap()),
)
+ .attach_rank()
+ .unwrap()
},
ranks: [input_len, neuron_count],
}
diff --git a/little_learner/src/lib.rs b/little_learner/src/lib.rs
index 615732e..3cb333e 100644
--- a/little_learner/src/lib.rs
+++ b/little_learner/src/lib.rs
@@ -1,6 +1,7 @@
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![feature(array_methods)]
+#![feature(closure_lifetime_binder)]
pub mod auto_diff;
pub mod block;
diff --git a/little_learner_app/src/main.rs b/little_learner_app/src/main.rs
index b917512..2578c76 100644
--- a/little_learner_app/src/main.rs
+++ b/little_learner_app/src/main.rs
@@ -3,6 +3,8 @@
use crate::rms_example::rms_example;
use little_learner::auto_diff::RankedDifferentiable;
+use little_learner::block;
+use ordered_float::NotNan;
mod iris;
mod rms_example;
@@ -20,4 +22,6 @@ fn main() {
}
let _xs = RankedDifferentiable::of_vector(xs);
let _ys = RankedDifferentiable::of_vector(ys);
+
+ let _network = block::compose(block::dense::, ()>(6, 3), block::dense(4, 6), 2);
}