use deep_causality_haft::utils_tests::*;
use deep_causality_haft::{Effect5, HKT5, MonadEffect5};
type TransactionEffect<T> = <<MyEffect5 as Effect5>::HktWitness as HKT5<
<MyEffect5 as Effect5>::Fixed1,
<MyEffect5 as Effect5>::Fixed2,
<MyEffect5 as Effect5>::Fixed3,
<MyEffect5 as Effect5>::Fixed4,
>>::Type<T>;
fn main() {
println!("=== DeepCausality HKT: Audited Financial Transaction (Effect System) ===\n");
let initial_balance: TransactionEffect<i32> = MyMonadEffect5::pure(1000);
println!("Initial Balance: ${}", initial_balance.value);
let debit_step = |amount: i32| {
Box::new(move |balance: i32| -> TransactionEffect<i32> {
if balance < amount {
MyCustomEffectType5 {
value: balance,
f1: Some("Insufficient Funds".to_string()),
f2: vec!["Failed Debit".to_string()],
f3: vec![10], f4: vec!["WARN: Balance check failed".to_string()],
}
} else {
MyCustomEffectType5 {
value: balance - amount,
f1: None,
f2: vec![format!("Debited ${}", amount)],
f3: vec![50], f4: vec!["INFO: Debit applied".to_string()],
}
}
})
};
let apply_tax = |rate_percent: i32| {
Box::new(move |balance: i32| -> TransactionEffect<i32> {
let tax = balance * rate_percent / 100;
MyCustomEffectType5 {
value: balance - tax,
f1: None,
f2: vec![format!("Applied Tax ${} ({}%)", tax, rate_percent)],
f3: vec![5], f4: vec!["INFO: Tax calculated".to_string()],
}
})
};
let credit_bonus = |bonus: i32| {
Box::new(move |balance: i32| -> TransactionEffect<i32> {
MyCustomEffectType5 {
value: balance + bonus,
f1: None,
f2: vec![format!("Credited Bonus ${}", bonus)],
f3: vec![20],
f4: vec!["INFO: Bonus applied".to_string()],
}
})
};
println!("\n--- 1. Successful Transaction Pipeline ---");
let steps: Vec<Box<dyn Fn(i32) -> TransactionEffect<i32>>> =
vec![debit_step(200), apply_tax(10), credit_bonus(50)];
let mut current_tx = initial_balance;
for (i, step) in steps.into_iter().enumerate() {
current_tx = MyMonadEffect5::bind(current_tx, step);
println!(
"Step {} complete. Current Balance: ${}",
i + 1,
current_tx.value
);
}
println!("\n--- Final Transaction Report ---");
println!("Final Balance: ${}", current_tx.value);
println!(
"Status: {:?}",
current_tx.f1.unwrap_or("Success".to_string())
);
println!("Audit Log: {:?}", current_tx.f2);
println!(
"Total Cost: {} micro-cents",
current_tx.f3.iter().sum::<u64>()
);
println!("System Trace: {:?}", current_tx.f4);
assert_eq!(current_tx.value, 770); assert_eq!(current_tx.f3.iter().sum::<u64>(), 75);
println!("\n--- 2. Failed Transaction Pipeline ---");
let initial_balance_2: TransactionEffect<i32> = MyMonadEffect5::pure(1000);
let steps_fail: Vec<Box<dyn Fn(i32) -> TransactionEffect<i32>>> =
vec![debit_step(2000), apply_tax(10)];
let mut fail_tx = initial_balance_2;
for step in steps_fail {
fail_tx = MyMonadEffect5::bind(fail_tx, step);
}
println!("Final Balance: ${}", fail_tx.value);
println!("Status: {:?}", fail_tx.f1);
println!("Audit Log: {:?}", fail_tx.f2);
assert!(fail_tx.f1.is_some());
assert_eq!(fail_tx.f1.unwrap(), "Insufficient Funds");
}