acme_core/specs/
prop.rs

1/*
2    Appellation: prop <mod>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use crate::error::PredictError;
6
7/// [Backward] describes an object capable of backward propagation.
8///
9///  
10pub trait Backward {
11    type Output;
12
13    fn backward(&self) -> Self::Output;
14}
15
16/// [Forward] describes an object capable of forward propagation.
17pub trait Forward<T> {
18    type Output;
19
20    fn forward(&self, args: &T) -> Result<Self::Output, PredictError>;
21}
22
23pub trait ForwardIter<T> {
24    type Item: Forward<T, Output = T>;
25
26    fn forward_iter(self, args: &T) -> Result<<Self::Item as Forward<T>>::Output, PredictError>;
27}
28
29// Trait implementations
30mod impls {
31    use super::*;
32
33    impl<I, M, T> ForwardIter<T> for I
34    where
35        I: IntoIterator<Item = M>,
36        M: Forward<T, Output = T>,
37        T: Clone,
38    {
39        type Item = M;
40
41        fn forward_iter(self, args: &T) -> Result<M::Output, PredictError> {
42            let mut result = args.clone();
43            for i in self {
44                result = i.forward(&result)?;
45            }
46            Ok(result)
47        }
48    }
49
50    impl<S, T> Forward<T> for Option<S>
51    where
52        S: Forward<T, Output = T>,
53        T: Clone,
54    {
55        type Output = T;
56
57        fn forward(&self, args: &T) -> Result<Self::Output, PredictError> {
58            match self {
59                Some(s) => s.forward(args),
60                None => Ok(args.clone()),
61            }
62        }
63    }
64
65    impl<S, T> Forward<T> for S
66    where
67        S: AsRef<dyn Forward<T, Output = T>>,
68        T: Clone,
69    {
70        type Output = T;
71
72        fn forward(&self, args: &T) -> Result<Self::Output, PredictError> {
73            self.as_ref().forward(args)
74        }
75    }
76}