use crate::CausalTensor;
use crate::types::causal_tensor_network::canonical_form::CanonicalForm;
use crate::types::causal_tensor_network::causal_tensor_train::CausalTensorTrain;
use deep_causality_haft::{Foldable, Functor, HKT, NoConstraint, Pure, Satisfies};
pub struct CausalTensorTrainWitness;
impl HKT for CausalTensorTrainWitness {
type Constraint = NoConstraint;
type Type<T>
= CausalTensorTrain<T>
where
T: Satisfies<NoConstraint>;
}
impl Functor<CausalTensorTrainWitness> for CausalTensorTrainWitness {
fn fmap<A, B, Func>(m_a: CausalTensorTrain<A>, mut f: Func) -> CausalTensorTrain<B>
where
A: Satisfies<NoConstraint>,
B: Satisfies<NoConstraint>,
Func: FnMut(A) -> B,
{
let new_cores: Vec<CausalTensor<B>> = m_a
.into_cores()
.into_iter()
.map(|core| {
let shape = core.shape().to_vec();
let data: Vec<B> = core.into_vec().into_iter().map(&mut f).collect();
CausalTensor::from_vec(data, &shape)
})
.collect();
CausalTensorTrain::from_cores_raw(new_cores, CanonicalForm::None)
}
}
impl Foldable<CausalTensorTrainWitness> for CausalTensorTrainWitness {
fn fold<A, B, Func>(fa: CausalTensorTrain<A>, init: B, mut f: Func) -> B
where
A: Satisfies<NoConstraint>,
Func: FnMut(B, A) -> B,
{
let mut acc = init;
for core in fa.into_cores() {
for a in core.into_vec() {
acc = f(acc, a);
}
}
acc
}
}
impl Pure<CausalTensorTrainWitness> for CausalTensorTrainWitness {
fn pure<T>(value: T) -> CausalTensorTrain<T>
where
T: Satisfies<NoConstraint>,
{
let core = CausalTensor::from_vec(vec![value], &[1, 1, 1]);
CausalTensorTrain::from_cores_raw(vec![core], CanonicalForm::None)
}
}