use crate::higher::Higher2;
pub trait Bifunctor<C, D>: Higher2 {
fn bimap(
self,
f: impl FnMut(Self::Param1) -> C,
g: impl FnMut(Self::Param2) -> D,
) -> Self::Target<C, D>;
}
impl<A, B, C, D> Bifunctor<C, D> for Result<A, B> {
fn bimap(self, mut f: impl FnMut(A) -> C, mut g: impl FnMut(B) -> D) -> Result<C, D> {
match self {
Ok(x) => Ok(f(x)),
Err(e) => Err(g(e)),
}
}
}
impl<A, B, C, D> Bifunctor<C, D> for (A, B) {
fn bimap(self, mut f: impl FnMut(A) -> C, mut g: impl FnMut(B) -> D) -> (C, D) {
(f(self.0), g(self.1))
}
}
if_std! {
use std::collections::HashMap;
use std::hash::Hash;
impl<A, B, C: Eq+Hash, D> Bifunctor<C, D> for HashMap<A, B> {
fn bimap(
self,
mut f: impl FnMut(A) -> C,
mut g: impl FnMut(B) -> D,
) -> HashMap<C, D> {
self.into_iter().map(|(k, v)| (f(k), g(v))).collect()
}
}
}