use super::category::Category;
use super::relationship::Relationship;
#[derive(Debug, Clone)]
pub struct Morphism<C: Category> {
inner: C::Morphism,
}
impl<C: Category> Morphism<C> {
pub fn of(m: C::Morphism) -> Self {
Self { inner: m }
}
pub fn id(obj: &C::Object) -> Self {
Self {
inner: C::identity(obj),
}
}
pub fn then(&self, other: &C::Morphism) -> Option<Self>
where
C::Morphism: Clone,
{
C::compose(&self.inner, other).map(|m| Self { inner: m })
}
pub fn and_then(&self, other: &Self) -> Option<Self>
where
C::Morphism: Clone,
{
self.then(&other.inner)
}
pub fn source(&self) -> C::Object {
self.inner.source()
}
pub fn target(&self) -> C::Object {
self.inner.target()
}
pub fn into_inner(self) -> C::Morphism {
self.inner
}
pub fn inner(&self) -> &C::Morphism {
&self.inner
}
}
impl<C: Category> PartialEq for Morphism<C>
where
C::Morphism: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl<C: Category> Eq for Morphism<C> where C::Morphism: Eq {}
pub fn compose_all<C: Category>(morphisms: &[C::Morphism]) -> Option<Morphism<C>>
where
C::Morphism: Clone,
{
let mut iter = morphisms.iter();
let first = Morphism::<C>::of(iter.next()?.clone());
iter.try_fold(first, |acc, m| acc.then(m))
}
pub fn direct_morphisms<C: Category>(start: &C::Object, end: &C::Object) -> Vec<C::Morphism>
where
C::Object: PartialEq,
{
C::morphisms()
.into_iter()
.filter(|m| m.source() == *start && m.target() == *end)
.collect()
}